[
  {
    "path": "CMakeLists.txt",
    "content": "# ----------------- Project Title ----------------\nCMAKE_MINIMUM_REQUIRED(VERSION 2.8)\nPROJECT(UChain)\n\n# ----------------- Project Build Type ----------------\nSET(CMAKE_VERBOSE_MAKEFILE 1)\nSET(ENABLE_SHARED_LIBS OFF CACHE BOOL   \"Enable shared libs.\")\nSET(MG_ENABLE_DEBUG    OFF CACHE BOOL   \"Enable Mongoose debug.\")\n\nIF(NOT CMAKE_BUILD_TYPE)\n    #SET(CMAKE_BUILD_TYPE DEBUG)\n    SET(CMAKE_BUILD_TYPE RELEASE)\n    #SET(CMAKE_BUILD_TYPE RELWITHDEBINFO)\n    #SET(CMAKE_BUILD_TYPE MINSIZEREL)\nENDIF()\nSTRING(TOUPPER \"${CMAKE_BUILD_TYPE}\" CMAKE_BUILD_TYPE)\n\n# Enable for use with clang-tidy.\nIF(NOT CMAKE_EXPORT_COMPILE_COMMANDS)\n    SET(CMAKE_EXPORT_COMPILE_COMMANDS ON)\nENDIF()\n\n# --------------- Check os verson---------------------\nif ( NOT WINDOWS )\n        if (${CMAKE_SYSTEM_PROCESSOR} MATCHES i386|i586|i686)\n                set ( BIT_MODE \"32\")\n        else ()\n                set ( BIT_MODE \"64\")\n        endif ()\n\n\n        if(EXISTS \"/etc/debian_version\")\n           set ( PLATFORM \"Debian\")\n        endif(EXISTS \"/etc/debian_version\")\n\n        if(EXISTS \"/etc/redhat-release\")\n           set ( PLATFORM \"Redhat\")\n        endif(EXISTS \"/etc/redhat-release\")\nendif ( NOT WINDOWS )\n# --------------- Compiler Settings ------------------\n# Common Definitions \n\nIF(${CMAKE_CXX_COMPILER} MATCHES .*android.*)\n    SET(ANDROID 1)\nENDIF()\n\nSET(COMMON_WARN \"-Wall -Wextra -Wstrict-aliasing=2 -Wno-unused-parameter -Wno-unused-variable -Wno-type-limits\")\n#if (NOT ANDROID) \n#\t\tSET(COMMON_WARN \"${COMMON_WARN} -Werror\")\n#endif()\nSET(COMMON_FLAGS \"-fstrict-aliasing -fvisibility=hidden\")\nSET(COMMON_ARGS \"${COMMON_FLAGS} ${COMMON_WARN}\")\n\nIF (APPLE)\n    ADD_DEFINITIONS(-DMAC_OSX=1)\n    SET(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++\")\nELSE()\n    SET(CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++\")\nENDIF()\n\n# GXX/Clang settings\nIF(\"${CMAKE_CXX_COMPILER_ID}\" STREQUAL \"GNU\")\n    SET(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} -std=c11 ${COMMON_ARGS}\")\n    #libbitcoin has too many ignored-qualifiers, and TODOs\n    SET(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -std=c++14 ${COMMON_ARGS} -pthread -fno-enforce-eh-specs -fnothrow-opt -Wno-reorder -Wno-ignored-qualifiers -Wno-unused-function -Wno-unused-but-set-variable -Wno-sign-compare -Wno-unused-but-set-parameter -Wno-implicit-fallthrough\")\n\nELSEIF(\"${CMAKE_CXX_COMPILER_ID}\" MATCHES \"Clang\")\n    SET(CMAKE_C_FLAGS \"-std=c11 ${COMMON_ARGS}\")\n    SET(CMAKE_CXX_FLAGS \"-std=c++14 ${COMMON_ARGS} -Wno-reorder -Wno-ignored-qualifiers -Wno-inconsistent-missing-override -Wno-missing-braces -Wno-mismatched-tags -Wno-overloaded-virtual -Wno-sometimes-uninitialized -Wno-macro-redefined -Wno-uninitialized -Wno-unused-private-field -Wno-unused-function -Wno-implicit-fallthrough\")\nENDIF()\n\nif(MINGW OR MSYS)\n\tset(CMAKE_CXX_STANDARD_LIBRARIES \"${CMAKE_CXX_STANDARD_LIBRARIES} -lwsock32 -lws2_32 -lgmp -static\")\n\tset(CMAKE_C_STANDARD_LIBRARIES \"${CMAKE_C_STANDARD_LIBRARIES} -lwsock32 -lws2_32 -lgmp -static\")\nENDIF()\n\t\nSET(CMAKE_SHARED_LINKER_FLAGS \"${CMAKE_SHARED_LINKER_FLAGS} -fPIC\")\n\n# --------------- Macro Definitions ------------------\n#ADD_DEFINITIONS(-DBOOST_NO_AUTO_PTR=1 -DBOOST_NO_RTTI=1 -DBOOST_NO_TYPEID=1)\nIF(CMAKE_BUILD_TYPE STREQUAL \"DEBUG\")\n    ADD_DEFINITIONS(-DUC_DEBUG=1)\nENDIF()\n\n# --------------- Outputs ---------------------\nSET(EXECUTABLE_OUTPUT_PATH \"${PROJECT_BINARY_DIR}/bin\")\nSET(LIBRARY_OUTPUT_PATH \"${PROJECT_BINARY_DIR}/lib\")\n\nFILE(MAKE_DIRECTORY \"${EXECUTABLE_OUTPUT_PATH}\")\nFILE(MAKE_DIRECTORY \"${LIBRARY_OUTPUT_PATH}\")\nFILE(MAKE_DIRECTORY \"${PROJECT_BINARY_DIR}/share/doc/html\")\n\nSET(CMAKE_MODULE_PATH \"${CMAKE_MODULE_PATH}\" \"${PROJECT_SOURCE_DIR}/etc\")\nSET(CMAKE_INSTALL_PREFIX \"/usr/local/\")\n\n# --------------- Libraries Dependencies ---------------------\nIF(ENABLE_SHARED_LIBS)\n    SET(Boost_USE_STATIC_LIBS   OFF)\nELSE()\n    SET(Boost_USE_STATIC_LIBS   ON)\nENDIF()\n\n# use UPNP\nSET(USE_UPNP ON CACHE BOOL \"Use UPNP.\")\nIF(USE_UPNP)\n    ADD_DEFINITIONS(-DUSE_UPNP=1)\n    FIND_PACKAGE(miniupnpc REQUIRED)\n    INCLUDE_DIRECTORIES(\"${miniupnpc_INCLUDE_DIRS}\")\n    IF(ENABLE_SHARED_LIBS)\n        SET(miniupnpc_LIBRARY miniupnpc_shared)\n    ELSE()\n        SET(miniupnpc_LIBRARY miniupnpc_static)\n    ENDIF()\nENDIF()\n\nFIND_PACKAGE(Boost 1.56 REQUIRED COMPONENTS date_time filesystem system\nprogram_options regex thread)\n#set(Boost_LIBRARIES ${Boost_LIBRARIES} icui18n icuuc icudata pthread dl)\n\nFIND_PACKAGE(secp256k1 REQUIRED)\nFIND_PACKAGE(ZeroMQ 4.2.0 REQUIRED)\n\n# ---------------- Doxygen --------------------\nFIND_PROGRAM(ENV_EXECUTABLE env QUIET)\nFIND_PROGRAM(DOT_EXECUTABLE dot QUIET)\nFIND_PACKAGE(Doxygen QUIET)          # Optional.\n\nIF(DOXYGEN_FOUND)\n  CONFIGURE_FILE(\"${PROJECT_SOURCE_DIR}/Doxyfile.in\"\n    \"${PROJECT_BINARY_DIR}/Doxyfile\")\n\n  ADD_CUSTOM_TARGET(doc\n    WORKING_DIRECTORY \"${PROJECT_SOURCE_DIR}\"\n    COMMAND \"${CMAKE_COMMAND}\" -E make_directory \"${PROJECT_BINARY_DIR}/share\"\n    COMMAND \"${DOXYGEN_EXECUTABLE}\" \"${PROJECT_BINARY_DIR}/Doxyfile\"\n    SOURCES \"${PROJECT_BINARY_DIR}/Doxyfile\")\n\n  ADD_CUSTOM_COMMAND(TARGET doc POST_BUILD\n    COMMAND \"${CMAKE_COMMAND}\" -E copy \"${PROJECT_SOURCE_DIR}/doc/CNAME\"\n            \"${PROJECT_BINARY_DIR}/share/doc/html/\")\n\n  INSTALL(DIRECTORY \"${PROJECT_BINARY_DIR}/share/doc/\" DESTINATION share/doc)\nENDIF()\n\n# ------------------ UC Includes --------------------\nINCLUDE_DIRECTORIES(\"${Boost_INCLUDE_DIRS}\")\nINCLUDE_DIRECTORIES(\"${PROJECT_SOURCE_DIR}/thirdparty\")\nINCLUDE_DIRECTORIES(\"${PROJECT_SOURCE_DIR}/include\")\nINCLUDE_DIRECTORIES(\"${secp256k1_INCLUDE_DIRS}\")\nINCLUDE_DIRECTORIES(\"${ZeroMQ_INCLUDE_DIRS}\")\n\n# ------------------ UC Libraries --------------------\nIF(ENABLE_SHARED_LIBS)\n    SET(mongoose_LIBRARY mongoose_shared)\n    SET(jsoncpp_LIBRARY jsoncpp_shared)\n    SET(cryptojs_LIBRARY cryptojs_shared)\n    SET(bitcoin_LIBRARY bitcoin_shared)\n    SET(txs_LIBRARY txs_shared)\n    SET(bitcoinmath_LIBRARY bitcoinmath_shared)\n    SET(network_LIBRARY network_shared)\n    SET(consensus_LIBRARY consensus_shared)\n    SET(database_LIBRARY database_shared)\n    SET(data_LIBRARY data_shared)\n    SET(node_LIBRARY node_shared)\n    SET(protocol_LIBRARY protocol_shared)\n    SET(client_LIBRARY client_shared)\n    SET(explorer_LIBRARY explorer_shared)\n    SET(api_LIBRARY api_shared)\nELSE()\n    SET(mongoose_LIBRARY mongoose_static)\n    SET(jsoncpp_LIBRARY jsoncpp_static)\n    SET(cryptojs_LIBRARY cryptojs_static)\n    SET(bitcoin_LIBRARY bitcoin_static)\n    SET(txs_LIBRARY txs_static)\n    SET(bitcoinmath_LIBRARY bitcoinmath_static)\n    SET(network_LIBRARY network_static)\n    SET(consensus_LIBRARY consensus_static)\n    SET(database_LIBRARY database_static)\n    SET(data_LIBRARY data_static)\n    SET(blockchain_LIBRARY blockchain_static)\n    SET(node_LIBRARY node_static)\n    SET(protocol_LIBRARY protocol_static)\n    SET(client_LIBRARY client_static)\n    SET(explorer_LIBRARY explorer_static)\n    SET(api_LIBRARY api_static)\nENDIF()\n\nENABLE_TESTING()\n\n# ------------------ UC src --------------------\nADD_SUBDIRECTORY(etc)\nADD_SUBDIRECTORY(thirdparty)\nADD_SUBDIRECTORY(include)\nADD_SUBDIRECTORY(src)\n#ADD_SUBDIRECTORY(test)\n"
  },
  {
    "path": "Doxyfile.in",
    "content": "# Doxyfile 1.8.11\n\n# This file describes the settings to be used by the documentation system\n# doxygen (www.doxygen.org) for a project.\n#\n# All text after a double hash (##) is considered a comment and is placed in\n# front of the TAG it is preceding.\n#\n# All text after a single hash (#) is considered a comment and will be ignored.\n# The format is:\n# TAG = value [value, ...]\n# For lists, items can also be appended using:\n# TAG += value [value, ...]\n# Values that contain spaces should be placed between quotes (\\\" \\\").\n\n#---------------------------------------------------------------------------\n# Project related configuration options\n#---------------------------------------------------------------------------\n\n# This tag specifies the encoding used for all characters in the config file\n# that follow. The default is UTF-8 which is also the encoding used for all text\n# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv\n# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv\n# for the list of possible encodings.\n# The default value is: UTF-8.\n\nDOXYFILE_ENCODING      = UTF-8\n\n# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by\n# double-quotes, unless you are using Doxywizard) that should identify the\n# project for which the documentation is generated. This name is used in the\n# title of most generated pages and in a few other places.\n# The default value is: My Project.\n\nPROJECT_NAME           = \"UChain\"\n\n# The PROJECT_NUMBER tag can be used to enter a project or revision number. This\n# could be handy for archiving the generated documentation or if some version\n# control system is used.\n\nPROJECT_NUMBER         =\n\n# Using the PROJECT_BRIEF tag one can provide an optional one line description\n# for a project that appears at the top of each page and should give viewer a\n# quick idea about the purpose of the project. Keep the description short.\n\nPROJECT_BRIEF          = \"The New Reality Blockchain project\"\n\n# With the PROJECT_LOGO tag one can specify a logo or an icon that is included\n# in the documentation. The maximum height of the logo should not exceed 55\n# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy\n# the logo to the output directory.\n\nPROJECT_LOGO           = \"${PROJECT_SOURCE_DIR}/doc/image/logo.png\"\n\n# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path\n# into which the generated documentation will be written. If a relative path is\n# entered, it will be relative to the location where doxygen was started. If\n# left blank the current directory will be used.\n\nOUTPUT_DIRECTORY       = \"${CMAKE_BINARY_DIR}/share/doc\"\n\n# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-\n# directories (in 2 levels) under the output directory of each output format and\n# will distribute the generated files over these directories. Enabling this\n# option can be useful when feeding doxygen a huge amount of source files, where\n# putting all generated files in the same directory would otherwise causes\n# performance problems for the file system.\n# The default value is: NO.\n\nCREATE_SUBDIRS         = NO\n\n# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII\n# characters to appear in the names of generated files. If set to NO, non-ASCII\n# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode\n# U+3044.\n# The default value is: NO.\n\nALLOW_UNICODE_NAMES    = NO\n\n# The OUTPUT_LANGUAGE tag is used to specify the language in which all\n# documentation generated by doxygen is written. Doxygen will use this\n# information to generate all constant output in the proper language.\n# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,\n# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),\n# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,\n# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),\n# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,\n# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,\n# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,\n# Ukrainian and Vietnamese.\n# The default value is: English.\n\nOUTPUT_LANGUAGE        = English\n\n# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member\n# descriptions after the members that are listed in the file and class\n# documentation (similar to Javadoc). Set to NO to disable this.\n# The default value is: YES.\n\nBRIEF_MEMBER_DESC      = YES\n\n# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief\n# description of a member or function before the detailed description\n#\n# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the\n# brief descriptions will be completely suppressed.\n# The default value is: YES.\n\nREPEAT_BRIEF           = YES\n\n# This tag implements a quasi-intelligent brief description abbreviator that is\n# used to form the text in various listings. Each string in this list, if found\n# as the leading text of the brief description, will be stripped from the text\n# and the result, after processing the whole list, is used as the annotated\n# text. Otherwise, the brief description is used as-is. If left blank, the\n# following values are used ($name is automatically replaced with the name of\n# the entity):The $name class, The $name widget, The $name file, is, provides,\n# specifies, contains, represents, a, an and the.\n\nABBREVIATE_BRIEF       =\n\n# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then\n# doxygen will generate a detailed section even if there is only a brief\n# description.\n# The default value is: NO.\n\nALWAYS_DETAILED_SEC    = NO\n\n# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all\n# inherited members of a class in the documentation of that class as if those\n# members were ordinary class members. Constructors, destructors and assignment\n# operators of the base classes will not be shown.\n# The default value is: NO.\n\nINLINE_INHERITED_MEMB  = NO\n\n# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path\n# before files name in the file list and in the header files. If set to NO the\n# shortest path that makes the file name unique will be used\n# The default value is: YES.\n\nFULL_PATH_NAMES        = YES\n\n# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.\n# Stripping is only done if one of the specified strings matches the left-hand\n# part of the path. The tag can be used to show relative paths in the file list.\n# If left blank the directory from which doxygen is run is used as the path to\n# strip.\n#\n# Note that you can specify absolute paths here, but also relative paths, which\n# will be relative from the directory where doxygen is started.\n# This tag requires that the tag FULL_PATH_NAMES is set to YES.\n\nSTRIP_FROM_PATH        = \"${PROJECT_SOURCE_DIR}/include\"\n\n# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the\n# path mentioned in the documentation of a class, which tells the reader which\n# header file to include in order to use a class. If left blank only the name of\n# the header file containing the class definition is used. Otherwise one should\n# specify the list of include paths that are normally passed to the compiler\n# using the -I flag.\n\nSTRIP_FROM_INC_PATH    = \"${PROJECT_SOURCE_DIR}/include\"\n\n# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but\n# less readable) file names. This can be useful is your file systems doesn't\n# support long names like on DOS, Mac, or CD-ROM.\n# The default value is: NO.\n\nSHORT_NAMES            = NO\n\n# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the\n# first line (until the first dot) of a Javadoc-style comment as the brief\n# description. If set to NO, the Javadoc-style will behave just like regular Qt-\n# style comments (thus requiring an explicit @brief command for a brief\n# description.)\n# The default value is: NO.\n\nJAVADOC_AUTOBRIEF      = YES\n\n# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first\n# line (until the first dot) of a Qt-style comment as the brief description. If\n# set to NO, the Qt-style will behave just like regular Qt-style comments (thus\n# requiring an explicit \\brief command for a brief description.)\n# The default value is: NO.\n\nQT_AUTOBRIEF           = NO\n\n# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a\n# multi-line C++ special comment block (i.e. a block of //! or /// comments) as\n# a brief description. This used to be the default behavior. The new default is\n# to treat a multi-line C++ comment block as a detailed description. Set this\n# tag to YES if you prefer the old behavior instead.\n#\n# Note that setting this tag to YES also means that rational rose comments are\n# not recognized any more.\n# The default value is: NO.\n\nMULTILINE_CPP_IS_BRIEF = NO\n\n# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the\n# documentation from any documented member that it re-implements.\n# The default value is: YES.\n\nINHERIT_DOCS           = YES\n\n# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new\n# page for each member. If set to NO, the documentation of a member will be part\n# of the file/class/namespace that contains it.\n# The default value is: NO.\n\nSEPARATE_MEMBER_PAGES  = NO\n\n# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen\n# uses this value to replace tabs by spaces in code fragments.\n# Minimum value: 1, maximum value: 16, default value: 4.\n\nTAB_SIZE               = 4\n\n# This tag can be used to specify a number of aliases that act as commands in\n# the documentation. An alias has the form:\n# name=value\n# For example adding\n# \"sideeffect=@par Side Effects:\\n\"\n# will allow you to put the command \\sideeffect (or @sideeffect) in the\n# documentation, which will result in a user-defined paragraph with heading\n# \"Side Effects:\". You can put \\n's in the value part of an alias to insert\n# newlines.\n\nALIASES                =\n\n# This tag can be used to specify a number of word-keyword mappings (TCL only).\n# A mapping has the form \"name=value\". For example adding \"class=itcl::class\"\n# will allow you to use the command class in the itcl::class meaning.\n\nTCL_SUBST              =\n\n# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources\n# only. Doxygen will then generate output that is more tailored for C. For\n# instance, some of the names that are used will be different. The list of all\n# members will be omitted, etc.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_FOR_C  = YES\n\n# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or\n# Python sources only. Doxygen will then generate output that is more tailored\n# for that language. For instance, namespaces will be presented as packages,\n# qualified scopes will look different, etc.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_JAVA   = NO\n\n# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran\n# sources. Doxygen will then generate output that is tailored for Fortran.\n# The default value is: NO.\n\nOPTIMIZE_FOR_FORTRAN   = NO\n\n# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL\n# sources. Doxygen will then generate output that is tailored for VHDL.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_VHDL   = NO\n\n# Doxygen selects the parser to use depending on the extension of the files it\n# parses. With this tag you can assign which parser to use for a given\n# extension. Doxygen has a built-in mapping, but you can override or extend it\n# using this tag. The format is ext=language, where ext is a file extension, and\n# language is one of the parsers supported by doxygen: IDL, Java, Javascript,\n# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:\n# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:\n# Fortran. In the later case the parser tries to guess whether the code is fixed\n# or free formatted code, this is the default for Fortran type files), VHDL. For\n# instance to make doxygen treat .inc files as Fortran files (default is PHP),\n# and .f files as C (default is Fortran), use: inc=Fortran f=C.\n#\n# Note: For files without extension you can use no_extension as a placeholder.\n#\n# Note that for custom extensions you also need to set FILE_PATTERNS otherwise\n# the files are not read by doxygen.\n\nEXTENSION_MAPPING      =\n\n# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments\n# according to the Markdown format, which allows for more readable\n# documentation. See http://daringfireball.net/projects/markdown/ for details.\n# The output of markdown processing is further processed by doxygen, so you can\n# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in\n# case of backward compatibilities issues.\n# The default value is: YES.\n\nMARKDOWN_SUPPORT       = YES\n\n# When enabled doxygen tries to link words that correspond to documented\n# classes, or namespaces to their corresponding documentation. Such a link can\n# be prevented in individual cases by putting a % sign in front of the word or\n# globally by setting AUTOLINK_SUPPORT to NO.\n# The default value is: YES.\n\nAUTOLINK_SUPPORT       = YES\n\n# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want\n# to include (a tag file for) the STL sources as input, then you should set this\n# tag to YES in order to let doxygen match functions declarations and\n# definitions whose arguments contain STL classes (e.g. func(std::string);\n# versus func(std::string) {}). This also make the inheritance and collaboration\n# diagrams that involve STL classes more complete and accurate.\n# The default value is: NO.\n\nBUILTIN_STL_SUPPORT    = YES\n\n# If you use Microsoft's C++/CLI language, you should set this option to YES to\n# enable parsing support.\n# The default value is: NO.\n\nCPP_CLI_SUPPORT        = NO\n\n# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:\n# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen\n# will parse them like normal C++ but will assume all classes use public instead\n# of private inheritance when no explicit protection keyword is present.\n# The default value is: NO.\n\nSIP_SUPPORT            = NO\n\n# For Microsoft's IDL there are propget and propput attributes to indicate\n# getter and setter methods for a property. Setting this option to YES will make\n# doxygen to replace the get and set methods by a property in the documentation.\n# This will only work if the methods are indeed getting or setting a simple\n# type. If this is not the case, or you want to show the methods anyway, you\n# should set this option to NO.\n# The default value is: YES.\n\nIDL_PROPERTY_SUPPORT   = YES\n\n# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC\n# tag is set to YES then doxygen will reuse the documentation of the first\n# member in the group (if any) for the other members of the group. By default\n# all members of a group must be documented explicitly.\n# The default value is: NO.\n\nDISTRIBUTE_GROUP_DOC   = NO\n\n# If one adds a struct or class to a group and this option is enabled, then also\n# any nested class or struct is added to the same group. By default this option\n# is disabled and one has to add nested compounds explicitly via \\ingroup.\n# The default value is: NO.\n\nGROUP_NESTED_COMPOUNDS = NO\n\n# Set the SUBGROUPING tag to YES to allow class member groups of the same type\n# (for instance a group of public functions) to be put as a subgroup of that\n# type (e.g. under the Public Functions section). Set it to NO to prevent\n# subgrouping. Alternatively, this can be done per class using the\n# \\nosubgrouping command.\n# The default value is: YES.\n\nSUBGROUPING            = YES\n\n# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions\n# are shown inside the group in which they are included (e.g. using \\ingroup)\n# instead of on a separate page (for HTML and Man pages) or section (for LaTeX\n# and RTF).\n#\n# Note that this feature does not work in combination with\n# SEPARATE_MEMBER_PAGES.\n# The default value is: NO.\n\nINLINE_GROUPED_CLASSES = NO\n\n# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions\n# with only public data fields or simple typedef fields will be shown inline in\n# the documentation of the scope in which they are defined (i.e. file,\n# namespace, or group documentation), provided this scope is documented. If set\n# to NO, structs, classes, and unions are shown on a separate page (for HTML and\n# Man pages) or section (for LaTeX and RTF).\n# The default value is: NO.\n\nINLINE_SIMPLE_STRUCTS  = NO\n\n# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or\n# enum is documented as struct, union, or enum with the name of the typedef. So\n# typedef struct TypeS {} TypeT, will appear in the documentation as a struct\n# with name TypeT. When disabled the typedef will appear as a member of a file,\n# namespace, or class. And the struct will be named TypeS. This can typically be\n# useful for C code in case the coding convention dictates that all compound\n# types are typedef'ed and only the typedef is referenced, never the tag name.\n# The default value is: NO.\n\nTYPEDEF_HIDES_STRUCT   = NO\n\n# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This\n# cache is used to resolve symbols given their name and scope. Since this can be\n# an expensive process and often the same symbol appears multiple times in the\n# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small\n# doxygen will become slower. If the cache is too large, memory is wasted. The\n# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range\n# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536\n# symbols. At the end of a run doxygen will report the cache usage and suggest\n# the optimal cache size from a speed point of view.\n# Minimum value: 0, maximum value: 9, default value: 0.\n\nLOOKUP_CACHE_SIZE      = 0\n\n#---------------------------------------------------------------------------\n# Build related configuration options\n#---------------------------------------------------------------------------\n\n# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in\n# documentation are documented, even if no documentation was available. Private\n# class members and static file members will be hidden unless the\n# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.\n# Note: This will also disable the warnings about undocumented members that are\n# normally produced when WARNINGS is set to YES.\n# The default value is: NO.\n\nEXTRACT_ALL            = YES\n\n# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will\n# be included in the documentation.\n# The default value is: NO.\n\nEXTRACT_PRIVATE        = NO\n\n# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal\n# scope will be included in the documentation.\n# The default value is: NO.\n\nEXTRACT_PACKAGE        = NO\n\n# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be\n# included in the documentation.\n# The default value is: NO.\n\nEXTRACT_STATIC         = YES\n\n# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined\n# locally in source files will be included in the documentation. If set to NO,\n# only classes defined in header files are included. Does not have any effect\n# for Java sources.\n# The default value is: YES.\n\nEXTRACT_LOCAL_CLASSES  = YES\n\n# This flag is only useful for Objective-C code. If set to YES, local methods,\n# which are defined in the implementation section but not in the interface are\n# included in the documentation. If set to NO, only methods in the interface are\n# included.\n# The default value is: NO.\n\nEXTRACT_LOCAL_METHODS  = NO\n\n# If this flag is set to YES, the members of anonymous namespaces will be\n# extracted and appear in the documentation as a namespace called\n# 'anonymous_namespace{file}', where file will be replaced with the base name of\n# the file that contains the anonymous namespace. By default anonymous namespace\n# are hidden.\n# The default value is: NO.\n\nEXTRACT_ANON_NSPACES   = NO\n\n# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all\n# undocumented members inside documented classes or files. If set to NO these\n# members will be included in the various overviews, but no documentation\n# section is generated. This option has no effect if EXTRACT_ALL is enabled.\n# The default value is: NO.\n\nHIDE_UNDOC_MEMBERS     = NO\n\n# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all\n# undocumented classes that are normally visible in the class hierarchy. If set\n# to NO, these classes will be included in the various overviews. This option\n# has no effect if EXTRACT_ALL is enabled.\n# The default value is: NO.\n\nHIDE_UNDOC_CLASSES     = NO\n\n# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend\n# (class|struct|union) declarations. If set to NO, these declarations will be\n# included in the documentation.\n# The default value is: NO.\n\nHIDE_FRIEND_COMPOUNDS  = NO\n\n# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any\n# documentation blocks found inside the body of a function. If set to NO, these\n# blocks will be appended to the function's detailed documentation block.\n# The default value is: NO.\n\nHIDE_IN_BODY_DOCS      = NO\n\n# The INTERNAL_DOCS tag determines if documentation that is typed after a\n# \\internal command is included. If the tag is set to NO then the documentation\n# will be excluded. Set it to YES to include the internal documentation.\n# The default value is: NO.\n\nINTERNAL_DOCS          = NO\n\n# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file\n# names in lower-case letters. If set to YES, upper-case letters are also\n# allowed. This is useful if you have classes or files whose names only differ\n# in case and if your file system supports case sensitive file names. Windows\n# and Mac users are advised to set this option to NO.\n# The default value is: system dependent.\n\nCASE_SENSE_NAMES       = YES\n\n# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with\n# their full class and namespace scopes in the documentation. If set to YES, the\n# scope will be hidden.\n# The default value is: NO.\n\nHIDE_SCOPE_NAMES       = YES\n\n# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will\n# append additional text to a page's title, such as Class Reference. If set to\n# YES the compound reference will be hidden.\n# The default value is: NO.\n\nHIDE_COMPOUND_REFERENCE= NO\n\n# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of\n# the files that are included by a file in the documentation of that file.\n# The default value is: YES.\n\nSHOW_INCLUDE_FILES     = YES\n\n# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each\n# grouped member an include statement to the documentation, telling the reader\n# which file to include in order to use the member.\n# The default value is: NO.\n\nSHOW_GROUPED_MEMB_INC  = NO\n\n# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include\n# files with double quotes in the documentation rather than with sharp brackets.\n# The default value is: NO.\n\nFORCE_LOCAL_INCLUDES   = NO\n\n# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the\n# documentation for inline members.\n# The default value is: YES.\n\nINLINE_INFO            = YES\n\n# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the\n# (detailed) documentation of file and class members alphabetically by member\n# name. If set to NO, the members will appear in declaration order.\n# The default value is: YES.\n\nSORT_MEMBER_DOCS       = YES\n\n# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief\n# descriptions of file, namespace and class members alphabetically by member\n# name. If set to NO, the members will appear in declaration order. Note that\n# this will also influence the order of the classes in the class list.\n# The default value is: NO.\n\nSORT_BRIEF_DOCS        = NO\n\n# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the\n# (brief and detailed) documentation of class members so that constructors and\n# destructors are listed first. If set to NO the constructors will appear in the\n# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.\n# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief\n# member documentation.\n# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting\n# detailed member documentation.\n# The default value is: NO.\n\nSORT_MEMBERS_CTORS_1ST = NO\n\n# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy\n# of group names into alphabetical order. If set to NO the group names will\n# appear in their defined order.\n# The default value is: NO.\n\nSORT_GROUP_NAMES       = NO\n\n# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by\n# fully-qualified names, including namespaces. If set to NO, the class list will\n# be sorted only by class name, not including the namespace part.\n# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.\n# Note: This option applies only to the class list, not to the alphabetical\n# list.\n# The default value is: NO.\n\nSORT_BY_SCOPE_NAME     = NO\n\n# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper\n# type resolution of all parameters of a function it will reject a match between\n# the prototype and the implementation of a member function even if there is\n# only one candidate or it is obvious which candidate to choose by doing a\n# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still\n# accept a match between prototype and implementation in such cases.\n# The default value is: NO.\n\nSTRICT_PROTO_MATCHING  = NO\n\n# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo\n# list. This list is created by putting \\todo commands in the documentation.\n# The default value is: YES.\n\nGENERATE_TODOLIST      = YES\n\n# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test\n# list. This list is created by putting \\test commands in the documentation.\n# The default value is: YES.\n\nGENERATE_TESTLIST      = YES\n\n# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug\n# list. This list is created by putting \\bug commands in the documentation.\n# The default value is: YES.\n\nGENERATE_BUGLIST       = YES\n\n# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)\n# the deprecated list. This list is created by putting \\deprecated commands in\n# the documentation.\n# The default value is: YES.\n\nGENERATE_DEPRECATEDLIST= YES\n\n# The ENABLED_SECTIONS tag can be used to enable conditional documentation\n# sections, marked by \\if <section_label> ... \\endif and \\cond <section_label>\n# ... \\endcond blocks.\n\nENABLED_SECTIONS       =\n\n# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the\n# initial value of a variable or macro / define can have for it to appear in the\n# documentation. If the initializer consists of more lines than specified here\n# it will be hidden. Use a value of 0 to hide initializers completely. The\n# appearance of the value of individual variables and macros / defines can be\n# controlled using \\showinitializer or \\hideinitializer command in the\n# documentation regardless of this setting.\n# Minimum value: 0, maximum value: 10000, default value: 30.\n\nMAX_INITIALIZER_LINES  = 30\n\n# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at\n# the bottom of the documentation of classes and structs. If set to YES, the\n# list will mention the files that were used to generate the documentation.\n# The default value is: YES.\n\nSHOW_USED_FILES        = YES\n\n# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This\n# will remove the Files entry from the Quick Index and from the Folder Tree View\n# (if specified).\n# The default value is: YES.\n\nSHOW_FILES             = YES\n\n# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces\n# page. This will remove the Namespaces entry from the Quick Index and from the\n# Folder Tree View (if specified).\n# The default value is: YES.\n\nSHOW_NAMESPACES        = YES\n\n# The FILE_VERSION_FILTER tag can be used to specify a program or script that\n# doxygen should invoke to get the current version for each file (typically from\n# the version control system). Doxygen will invoke the program by executing (via\n# popen()) the command command input-file, where command is the value of the\n# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided\n# by doxygen. Whatever the program writes to standard output is used as the file\n# version. For an example see the documentation.\n\nFILE_VERSION_FILTER    =\n\n# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed\n# by doxygen. The layout file controls the global structure of the generated\n# output files in an output format independent way. To create the layout file\n# that represents doxygen's defaults, run doxygen with the -l option. You can\n# optionally specify a file name after the option, if omitted DoxygenLayout.xml\n# will be used as the name of the layout file.\n#\n# Note that if you run doxygen from a directory containing a file called\n# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE\n# tag is left empty.\n\nLAYOUT_FILE            = \"${PROJECT_SOURCE_DIR}/etc/DoxygenLayout.xml\"\n\n# The CITE_BIB_FILES tag can be used to specify one or more bib files containing\n# the reference definitions. This must be a list of .bib files. The .bib\n# extension is automatically appended if omitted. This requires the bibtex tool\n# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.\n# For LaTeX the style of the bibliography can be controlled using\n# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the\n# search path. See also \\cite for info how to create references.\n\nCITE_BIB_FILES         =\n\n#---------------------------------------------------------------------------\n# Configuration options related to warning and progress messages\n#---------------------------------------------------------------------------\n\n# The QUIET tag can be used to turn on/off the messages that are generated to\n# standard output by doxygen. If QUIET is set to YES this implies that the\n# messages are off.\n# The default value is: NO.\n\nQUIET                  = NO\n\n# The WARNINGS tag can be used to turn on/off the warning messages that are\n# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES\n# this implies that the warnings are on.\n#\n# Tip: Turn warnings on while writing the documentation.\n# The default value is: YES.\n\nWARNINGS               = YES\n\n# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate\n# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag\n# will automatically be disabled.\n# The default value is: YES.\n\nWARN_IF_UNDOCUMENTED   = YES\n\n# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for\n# potential errors in the documentation, such as not documenting some parameters\n# in a documented function, or documenting parameters that don't exist or using\n# markup commands wrongly.\n# The default value is: YES.\n\nWARN_IF_DOC_ERROR      = YES\n\n# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that\n# are documented, but have no documentation for their parameters or return\n# value. If set to NO, doxygen will only warn about wrong or incomplete\n# parameter documentation, but not about the absence of documentation.\n# The default value is: NO.\n\nWARN_NO_PARAMDOC       = NO\n\n# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when\n# a warning is encountered.\n# The default value is: NO.\n\nWARN_AS_ERROR          = NO\n\n# The WARN_FORMAT tag determines the format of the warning messages that doxygen\n# can produce. The string should contain the $file, $line, and $text tags, which\n# will be replaced by the file and line number from which the warning originated\n# and the warning text. Optionally the format may contain $version, which will\n# be replaced by the version of the file (if it could be obtained via\n# FILE_VERSION_FILTER)\n# The default value is: $file:$line: $text.\n\nWARN_FORMAT            = \"$file:$line: $text\"\n\n# The WARN_LOGFILE tag can be used to specify a file to which warning and error\n# messages should be written. If left blank the output is written to standard\n# error (stderr).\n\nWARN_LOGFILE           =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the input files\n#---------------------------------------------------------------------------\n\n# The INPUT tag is used to specify the files and/or directories that contain\n# documented source files. You may enter file names like myfile.cpp or\n# directories like /usr/src/myproject. Separate the files or directories with\n# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING\n# Note: If this tag is empty the current directory is searched.\n\nINPUT                  =\n\n# This tag can be used to specify the character encoding of the source files\n# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses\n# libiconv (or the iconv built into libc) for the transcoding. See the libiconv\n# documentation (see: http://www.gnu.org/software/libiconv) for the list of\n# possible encodings.\n# The default value is: UTF-8.\n\nINPUT_ENCODING         = UTF-8\n\n# If the value of the INPUT tag contains directories, you can use the\n# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and\n# *.h) to filter out the source-files in the directories.\n#\n# Note that for custom extensions or not directly supported extensions you also\n# need to set EXTENSION_MAPPING for the extension otherwise the files are not\n# read by doxygen.\n#\n# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,\n# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,\n# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,\n# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f, *.for, *.tcl,\n# *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js.\n\nFILE_PATTERNS          = *.h \\\n                         *.hpp \\\n                         *.md\n\n# The RECURSIVE tag can be used to specify whether or not subdirectories should\n# be searched for input files as well.\n# The default value is: NO.\n\nRECURSIVE              = YES\n\n# The EXCLUDE tag can be used to specify files and/or directories that should be\n# excluded from the INPUT source files. This way you can easily exclude a\n# subdirectory from a directory tree whose root is specified with the INPUT tag.\n#\n# Note that relative paths are relative to the directory from which doxygen is\n# run.\n\nEXCLUDE                =\n\n# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or\n# directories that are symbolic links (a Unix file system feature) are excluded\n# from the input.\n# The default value is: NO.\n\nEXCLUDE_SYMLINKS       = NO\n\n# If the value of the INPUT tag contains directories, you can use the\n# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude\n# certain files from those directories.\n#\n# Note that the wildcards are matched against the file with absolute path, so to\n# exclude all test directories for example use the pattern */test/*\n\nEXCLUDE_PATTERNS       =\n\n# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names\n# (namespaces, classes, functions, etc.) that should be excluded from the\n# output. The symbol name can be a fully qualified name, a word, or if the\n# wildcard * is used, a substring. Examples: ANamespace, AClass,\n# AClass::ANamespace, ANamespace::*Test\n#\n# Note that the wildcards are matched against the file with absolute path, so to\n# exclude all test directories use the pattern */test/*\n\nEXCLUDE_SYMBOLS        =\n\n# The EXAMPLE_PATH tag can be used to specify one or more files or directories\n# that contain example code fragments that are included (see the \\include\n# command).\n\nEXAMPLE_PATH           =\n\n# If the value of the EXAMPLE_PATH tag contains directories, you can use the\n# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and\n# *.h) to filter out the source-files in the directories. If left blank all\n# files are included.\n\nEXAMPLE_PATTERNS       = *.c \\\n                         *.cpp\n\n# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be\n# searched for input files to be used with the \\include or \\dontinclude commands\n# irrespective of the value of the RECURSIVE tag.\n# The default value is: NO.\n\nEXAMPLE_RECURSIVE      = YES\n\n# The IMAGE_PATH tag can be used to specify one or more files or directories\n# that contain images that are to be included in the documentation (see the\n# \\image command).\n\nIMAGE_PATH             = \"${PROJECT_SOURCE_DIR}/image\" \"${PROJECT_BINARY_DIR}/image\"\n\n# The INPUT_FILTER tag can be used to specify a program that doxygen should\n# invoke to filter for each input file. Doxygen will invoke the filter program\n# by executing (via popen()) the command:\n#\n# <filter> <input-file>\n#\n# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the\n# name of an input file. Doxygen will then use the output that the filter\n# program writes to standard output. If FILTER_PATTERNS is specified, this tag\n# will be ignored.\n#\n# Note that the filter must not add or remove lines; it is applied before the\n# code is scanned, but not when the output code is generated. If lines are added\n# or removed, the anchors will not be placed correctly.\n#\n# Note that for custom extensions or not directly supported extensions you also\n# need to set EXTENSION_MAPPING for the extension otherwise the files are not\n# properly processed by doxygen.\n\nINPUT_FILTER           =\n\n# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern\n# basis. Doxygen will compare the file name with each pattern and apply the\n# filter if there is a match. The filters are a list of the form: pattern=filter\n# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how\n# filters are used. If the FILTER_PATTERNS tag is empty or if none of the\n# patterns match the file name, INPUT_FILTER is applied.\n#\n# Note that for custom extensions or not directly supported extensions you also\n# need to set EXTENSION_MAPPING for the extension otherwise the files are not\n# properly processed by doxygen.\n\nFILTER_PATTERNS        =\n\n# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using\n# INPUT_FILTER) will also be used to filter the input files that are used for\n# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).\n# The default value is: NO.\n\nFILTER_SOURCE_FILES    = NO\n\n# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file\n# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and\n# it is also possible to disable source filtering for a specific pattern using\n# *.ext= (so without naming a filter).\n# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.\n\nFILTER_SOURCE_PATTERNS =\n\n# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that\n# is part of the input, its contents will be placed on the main page\n# (index.html). This can be useful if you have a project on for instance GitHub\n# and want to reuse the introduction page also for the doxygen output.\n\nUSE_MDFILE_AS_MAINPAGE =\n\n#---------------------------------------------------------------------------\n# Configuration options related to source browsing\n#---------------------------------------------------------------------------\n\n# If the SOURCE_BROWSER tag is set to YES then a list of source files will be\n# generated. Documented entities will be cross-referenced with these sources.\n#\n# Note: To get rid of all source code in the generated output, make sure that\n# also VERBATIM_HEADERS is set to NO.\n# The default value is: NO.\n\nSOURCE_BROWSER         = NO\n\n# Setting the INLINE_SOURCES tag to YES will include the body of functions,\n# classes and enums directly into the documentation.\n# The default value is: NO.\n\nINLINE_SOURCES         = NO\n\n# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any\n# special comment blocks from generated source code fragments. Normal C, C++ and\n# Fortran comments will always remain visible.\n# The default value is: YES.\n\nSTRIP_CODE_COMMENTS    = YES\n\n# If the REFERENCED_BY_RELATION tag is set to YES then for each documented\n# function all documented functions referencing it will be listed.\n# The default value is: NO.\n\nREFERENCED_BY_RELATION = NO\n\n# If the REFERENCES_RELATION tag is set to YES then for each documented function\n# all documented entities called/used by that function will be listed.\n# The default value is: NO.\n\nREFERENCES_RELATION    = NO\n\n# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set\n# to YES then the hyperlinks from functions in REFERENCES_RELATION and\n# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will\n# link to the documentation.\n# The default value is: YES.\n\nREFERENCES_LINK_SOURCE = YES\n\n# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the\n# source code will show a tooltip with additional information such as prototype,\n# brief description and links to the definition and documentation. Since this\n# will make the HTML file larger and loading of large files a bit slower, you\n# can opt to disable this feature.\n# The default value is: YES.\n# This tag requires that the tag SOURCE_BROWSER is set to YES.\n\nSOURCE_TOOLTIPS        = YES\n\n# If the USE_HTAGS tag is set to YES then the references to source code will\n# point to the HTML generated by the htags(1) tool instead of doxygen built-in\n# source browser. The htags tool is part of GNU's global source tagging system\n# (see http://www.gnu.org/software/global/global.html). You will need version\n# 4.8.6 or higher.\n#\n# To use it do the following:\n# - Install the latest version of global\n# - Enable SOURCE_BROWSER and USE_HTAGS in the config file\n# - Make sure the INPUT points to the root of the source tree\n# - Run doxygen as normal\n#\n# Doxygen will invoke htags (and that will in turn invoke gtags), so these\n# tools must be available from the command line (i.e. in the search path).\n#\n# The result: instead of the source browser generated by doxygen, the links to\n# source code will now point to the output of htags.\n# The default value is: NO.\n# This tag requires that the tag SOURCE_BROWSER is set to YES.\n\nUSE_HTAGS              = NO\n\n# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a\n# verbatim copy of the header file for each class for which an include is\n# specified. Set to NO to disable this.\n# See also: Section \\class.\n# The default value is: YES.\n\nVERBATIM_HEADERS       = YES\n\n# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the\n# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the\n# cost of reduced performance. This can be particularly helpful with template\n# rich C++ code for which doxygen's built-in parser lacks the necessary type\n# information.\n# Note: The availability of this option depends on whether or not doxygen was\n# generated with the -Duse-libclang=ON option for CMake.\n# The default value is: NO.\n\nCLANG_ASSISTED_PARSING = NO\n\n# If clang assisted parsing is enabled you can provide the compiler with command\n# line options that you would normally use when invoking the compiler. Note that\n# the include paths will already be set by doxygen for the files and directories\n# specified with INPUT and INCLUDE_PATH.\n# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.\n\nCLANG_OPTIONS          =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the alphabetical class index\n#---------------------------------------------------------------------------\n\n# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all\n# compounds will be generated. Enable this if the project contains a lot of\n# classes, structs, unions or interfaces.\n# The default value is: YES.\n\nALPHABETICAL_INDEX     = YES\n\n# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in\n# which the alphabetical index list will be split.\n# Minimum value: 1, maximum value: 20, default value: 5.\n# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.\n\nCOLS_IN_ALPHA_INDEX    = 5\n\n# In case all classes in a project start with a common prefix, all classes will\n# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag\n# can be used to specify a prefix (or a list of prefixes) that should be ignored\n# while generating the index headers.\n# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.\n\nIGNORE_PREFIX          =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the HTML output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output\n# The default value is: YES.\n\nGENERATE_HTML          = YES\n\n# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: html.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_OUTPUT            = html\n\n# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each\n# generated HTML page (for example: .htm, .php, .asp).\n# The default value is: .html.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_FILE_EXTENSION    = .html\n\n# The HTML_HEADER tag can be used to specify a user-defined HTML header file for\n# each generated HTML page. If the tag is left blank doxygen will generate a\n# standard header.\n#\n# To get valid HTML the header file that includes any scripts and style sheets\n# that doxygen needs, which is dependent on the configuration options used (e.g.\n# the setting GENERATE_TREEVIEW). It is highly recommended to start with a\n# default header using\n# doxygen -w html new_header.html new_footer.html new_stylesheet.css\n# YourConfigFile\n# and then modify the file new_header.html. See also section \"Doxygen usage\"\n# for information on how to generate the default header that doxygen normally\n# uses.\n# Note: The header is subject to change so you typically have to regenerate the\n# default header when upgrading to a newer version of doxygen. For a description\n# of the possible markers and block names see the documentation.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_HEADER            =\n\n# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each\n# generated HTML page. If the tag is left blank doxygen will generate a standard\n# footer. See HTML_HEADER for more information on how to generate a default\n# footer and what special commands can be used inside the footer. See also\n# section \"Doxygen usage\" for information on how to generate the default footer\n# that doxygen normally uses.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_FOOTER            =\n\n# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style\n# sheet that is used by each HTML page. It can be used to fine-tune the look of\n# the HTML output. If left blank doxygen will generate a default style sheet.\n# See also section \"Doxygen usage\" for information on how to generate the style\n# sheet that doxygen normally uses.\n# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as\n# it is more robust and this tag (HTML_STYLESHEET) will in the future become\n# obsolete.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_STYLESHEET        =\n\n# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined\n# cascading style sheets that are included after the standard style sheets\n# created by doxygen. Using this option one can overrule certain style aspects.\n# This is preferred over using HTML_STYLESHEET since it does not replace the\n# standard style sheet and is therefore more robust against future updates.\n# Doxygen will copy the style sheet files to the output directory.\n# Note: The order of the extra style sheet files is of importance (e.g. the last\n# style sheet in the list overrules the setting of the previous ones in the\n# list). For an example see the documentation.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_EXTRA_STYLESHEET  =\n\n# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or\n# other source files which should be copied to the HTML output directory. Note\n# that these files will be copied to the base HTML output directory. Use the\n# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these\n# files. In the HTML_STYLESHEET file, use the file name only. Also note that the\n# files will be copied as-is; there are no commands or markers available.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_EXTRA_FILES       =\n\n# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen\n# will adjust the colors in the style sheet and background images according to\n# this color. Hue is specified as an angle on a colorwheel, see\n# http://en.wikipedia.org/wiki/Hue for more information. For instance the value\n# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300\n# purple, and 360 is red again.\n# Minimum value: 0, maximum value: 359, default value: 220.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_COLORSTYLE_HUE    = 220\n\n# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors\n# in the HTML output. For a value of 0 the output will use grayscales only. A\n# value of 255 will produce the most vivid colors.\n# Minimum value: 0, maximum value: 255, default value: 100.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_COLORSTYLE_SAT    = 100\n\n# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the\n# luminance component of the colors in the HTML output. Values below 100\n# gradually make the output lighter, whereas values above 100 make the output\n# darker. The value divided by 100 is the actual gamma applied, so 80 represents\n# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not\n# change the gamma.\n# Minimum value: 40, maximum value: 240, default value: 80.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_COLORSTYLE_GAMMA  = 80\n\n# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML\n# page will contain the date and time when the page was generated. Setting this\n# to YES can help to show when doxygen was last run and thus if the\n# documentation is up to date.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_TIMESTAMP         = NO\n\n# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML\n# documentation will contain sections that can be hidden and shown after the\n# page has loaded.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_DYNAMIC_SECTIONS  = NO\n\n# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries\n# shown in the various tree structured indices initially; the user can expand\n# and collapse entries dynamically later on. Doxygen will expand the tree to\n# such a level that at most the specified number of entries are visible (unless\n# a fully collapsed tree already exceeds this amount). So setting the number of\n# entries 1 will produce a full collapsed tree by default. 0 is a special value\n# representing an infinite number of entries and will result in a full expanded\n# tree by default.\n# Minimum value: 0, maximum value: 9999, default value: 100.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_INDEX_NUM_ENTRIES = 100\n\n# If the GENERATE_DOCSET tag is set to YES, additional index files will be\n# generated that can be used as input for Apple's Xcode 3 integrated development\n# environment (see: http://developer.apple.com/tools/xcode/), introduced with\n# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a\n# Makefile in the HTML output directory. Running make will produce the docset in\n# that directory and running make install will install the docset in\n# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at\n# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html\n# for more information.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_DOCSET        = NO\n\n# This tag determines the name of the docset feed. A documentation feed provides\n# an umbrella under which multiple documentation sets from a single provider\n# (such as a company or product suite) can be grouped.\n# The default value is: Doxygen generated docs.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_FEEDNAME        = \"Doxygen generated docs\"\n\n# This tag specifies a string that should uniquely identify the documentation\n# set bundle. This should be a reverse domain-name style string, e.g.\n# com.mycompany.MyDocSet. Doxygen will append .docset to the name.\n# The default value is: org.doxygen.Project.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_BUNDLE_ID       = org.doxygen.Project\n\n# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify\n# the documentation publisher. This should be a reverse domain-name style\n# string, e.g. com.mycompany.MyDocSet.documentation.\n# The default value is: org.doxygen.Publisher.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_PUBLISHER_ID    = org.doxygen.Publisher\n\n# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.\n# The default value is: Publisher.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_PUBLISHER_NAME  = Publisher\n\n# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three\n# additional HTML index files: index.hhp, index.hhc, and index.hhk. The\n# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop\n# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on\n# Windows.\n#\n# The HTML Help Workshop contains a compiler that can convert all HTML output\n# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML\n# files are now used as the Windows 98 help format, and will replace the old\n# Windows help format (.hlp) on all Windows platforms in the future. Compressed\n# HTML files also contain an index, a table of contents, and you can search for\n# words in the documentation. The HTML workshop also contains a viewer for\n# compressed HTML files.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_HTMLHELP      = NO\n\n# The CHM_FILE tag can be used to specify the file name of the resulting .chm\n# file. You can add a path in front of the file if the result should not be\n# written to the html output directory.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nCHM_FILE               =\n\n# The HHC_LOCATION tag can be used to specify the location (absolute path\n# including file name) of the HTML help compiler (hhc.exe). If non-empty,\n# doxygen will try to run the HTML help compiler on the generated index.hhp.\n# The file has to be specified with full path.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nHHC_LOCATION           =\n\n# The GENERATE_CHI flag controls if a separate .chi index file is generated\n# (YES) or that it should be included in the master .chm file (NO).\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nGENERATE_CHI           = NO\n\n# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)\n# and project file content.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nCHM_INDEX_ENCODING     =\n\n# The BINARY_TOC flag controls whether a binary table of contents is generated\n# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it\n# enables the Previous and Next buttons.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nBINARY_TOC             = NO\n\n# The TOC_EXPAND flag can be set to YES to add extra items for group members to\n# the table of contents of the HTML help documentation and to the tree view.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nTOC_EXPAND             = NO\n\n# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and\n# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that\n# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help\n# (.qch) of the generated HTML documentation.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_QHP           = NO\n\n# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify\n# the file name of the resulting .qch file. The path specified is relative to\n# the HTML output folder.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQCH_FILE               =\n\n# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help\n# Project output. For more information please see Qt Help Project / Namespace\n# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).\n# The default value is: org.doxygen.Project.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_NAMESPACE          = org.doxygen.Project\n\n# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt\n# Help Project output. For more information please see Qt Help Project / Virtual\n# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-\n# folders).\n# The default value is: doc.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_VIRTUAL_FOLDER     = doc\n\n# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom\n# filter to add. For more information please see Qt Help Project / Custom\n# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-\n# filters).\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_CUST_FILTER_NAME   =\n\n# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the\n# custom filter to add. For more information please see Qt Help Project / Custom\n# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-\n# filters).\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_CUST_FILTER_ATTRS  =\n\n# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this\n# project's filter section matches. Qt Help Project / Filter Attributes (see:\n# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_SECT_FILTER_ATTRS  =\n\n# The QHG_LOCATION tag can be used to specify the location of Qt's\n# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the\n# generated .qhp file.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHG_LOCATION           =\n\n# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be\n# generated, together with the HTML files, they form an Eclipse help plugin. To\n# install this plugin and make it available under the help contents menu in\n# Eclipse, the contents of the directory containing the HTML and XML files needs\n# to be copied into the plugins directory of eclipse. The name of the directory\n# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.\n# After copying Eclipse needs to be restarted before the help appears.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_ECLIPSEHELP   = NO\n\n# A unique identifier for the Eclipse help plugin. When installing the plugin\n# the directory name containing the HTML and XML files should also have this\n# name. Each documentation set should have its own identifier.\n# The default value is: org.doxygen.Project.\n# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.\n\nECLIPSE_DOC_ID         = org.doxygen.Project\n\n# If you want full control over the layout of the generated HTML pages it might\n# be necessary to disable the index and replace it with your own. The\n# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top\n# of each HTML page. A value of NO enables the index and the value YES disables\n# it. Since the tabs in the index contain the same information as the navigation\n# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nDISABLE_INDEX          = NO\n\n# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index\n# structure should be generated to display hierarchical information. If the tag\n# value is set to YES, a side panel will be generated containing a tree-like\n# index structure (just like the one that is generated for HTML Help). For this\n# to work a browser that supports JavaScript, DHTML, CSS and frames is required\n# (i.e. any modern browser). Windows users are probably better off using the\n# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can\n# further fine-tune the look of the index. As an example, the default style\n# sheet generated by doxygen has an example that shows how to put an image at\n# the root of the tree instead of the PROJECT_NAME. Since the tree basically has\n# the same information as the tab index, you could consider setting\n# DISABLE_INDEX to YES when enabling this option.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_TREEVIEW      = NO\n\n# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that\n# doxygen will group on one line in the generated HTML documentation.\n#\n# Note that a value of 0 will completely suppress the enum values from appearing\n# in the overview section.\n# Minimum value: 0, maximum value: 20, default value: 4.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nENUM_VALUES_PER_LINE   = 4\n\n# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used\n# to set the initial width (in pixels) of the frame in which the tree is shown.\n# Minimum value: 0, maximum value: 1500, default value: 250.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nTREEVIEW_WIDTH         = 250\n\n# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to\n# external symbols imported via tag files in a separate window.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nEXT_LINKS_IN_WINDOW    = NO\n\n# Use this tag to change the font size of LaTeX formulas included as images in\n# the HTML documentation. When you change the font size after a successful\n# doxygen run you need to manually remove any form_*.png images from the HTML\n# output directory to force them to be regenerated.\n# Minimum value: 8, maximum value: 50, default value: 10.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nFORMULA_FONTSIZE       = 10\n\n# Use the FORMULA_TRANPARENT tag to determine whether or not the images\n# generated for formulas are transparent PNGs. Transparent PNGs are not\n# supported properly for IE 6.0, but are supported on all modern browsers.\n#\n# Note that when changing this option you need to delete any form_*.png files in\n# the HTML output directory before the changes have effect.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nFORMULA_TRANSPARENT    = YES\n\n# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see\n# http://www.mathjax.org) which uses client side Javascript for the rendering\n# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX\n# installed or if you want to formulas look prettier in the HTML output. When\n# enabled you may also need to install MathJax separately and configure the path\n# to it using the MATHJAX_RELPATH option.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nUSE_MATHJAX            = NO\n\n# When MathJax is enabled you can set the default output format to be used for\n# the MathJax output. See the MathJax site (see:\n# http://docs.mathjax.org/en/latest/output.html) for more details.\n# Possible values are: HTML-CSS (which is slower, but has the best\n# compatibility), NativeMML (i.e. MathML) and SVG.\n# The default value is: HTML-CSS.\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_FORMAT         = HTML-CSS\n\n# When MathJax is enabled you need to specify the location relative to the HTML\n# output directory using the MATHJAX_RELPATH option. The destination directory\n# should contain the MathJax.js script. For instance, if the mathjax directory\n# is located at the same level as the HTML output directory, then\n# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax\n# Content Delivery Network so you can quickly see the result without installing\n# MathJax. However, it is strongly recommended to install a local copy of\n# MathJax from http://www.mathjax.org before deployment.\n# The default value is: http://cdn.mathjax.org/mathjax/latest.\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest\n\n# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax\n# extension names that should be enabled during MathJax rendering. For example\n# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_EXTENSIONS     =\n\n# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces\n# of code that will be used on startup of the MathJax code. See the MathJax site\n# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an\n# example see the documentation.\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_CODEFILE       =\n\n# When the SEARCHENGINE tag is enabled doxygen will generate a search box for\n# the HTML output. The underlying search engine uses javascript and DHTML and\n# should work on any modern browser. Note that when using HTML help\n# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)\n# there is already a search function so this one should typically be disabled.\n# For large projects the javascript based search engine can be slow, then\n# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to\n# search using the keyboard; to jump to the search box use <access key> + S\n# (what the <access key> is depends on the OS and browser, but it is typically\n# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down\n# key> to jump into the search results window, the results can be navigated\n# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel\n# the search. The filter options can be selected when the cursor is inside the\n# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>\n# to select a filter and <Enter> or <escape> to activate or cancel the filter\n# option.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nSEARCHENGINE           = YES\n\n# When the SERVER_BASED_SEARCH tag is enabled the search engine will be\n# implemented using a web server instead of a web client using Javascript. There\n# are two flavors of web server based searching depending on the EXTERNAL_SEARCH\n# setting. When disabled, doxygen will generate a PHP script for searching and\n# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing\n# and searching needs to be provided by external tools. See the section\n# \"External Indexing and Searching\" for details.\n# The default value is: NO.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nSERVER_BASED_SEARCH    = NO\n\n# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP\n# script for searching. Instead the search results are written to an XML file\n# which needs to be processed by an external indexer. Doxygen will invoke an\n# external search engine pointed to by the SEARCHENGINE_URL option to obtain the\n# search results.\n#\n# Doxygen ships with an example indexer (doxyindexer) and search engine\n# (doxysearch.cgi) which are based on the open source search engine library\n# Xapian (see: http://xapian.org/).\n#\n# See the section \"External Indexing and Searching\" for details.\n# The default value is: NO.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nEXTERNAL_SEARCH        = NO\n\n# The SEARCHENGINE_URL should point to a search engine hosted by a web server\n# which will return the search results when EXTERNAL_SEARCH is enabled.\n#\n# Doxygen ships with an example indexer (doxyindexer) and search engine\n# (doxysearch.cgi) which are based on the open source search engine library\n# Xapian (see: http://xapian.org/). See the section \"External Indexing and\n# Searching\" for details.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nSEARCHENGINE_URL       =\n\n# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed\n# search data is written to a file for indexing by an external tool. With the\n# SEARCHDATA_FILE tag the name of this file can be specified.\n# The default file is: searchdata.xml.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nSEARCHDATA_FILE        = searchdata.xml\n\n# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the\n# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is\n# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple\n# projects and redirect the results back to the right project.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nEXTERNAL_SEARCH_ID     =\n\n# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen\n# projects other than the one defined by this configuration file, but that are\n# all added to the same external search index. Each project needs to have a\n# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of\n# to a relative location where the documentation can be found. The format is:\n# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nEXTRA_SEARCH_MAPPINGS  =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the LaTeX output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.\n# The default value is: YES.\n\nGENERATE_LATEX         = YES\n\n# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: latex.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_OUTPUT           = latex\n\n# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be\n# invoked.\n#\n# Note that when enabling USE_PDFLATEX this option is only used for generating\n# bitmaps for formulas in the HTML output, but not in the Makefile that is\n# written to the output directory.\n# The default file is: latex.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_CMD_NAME         = latex\n\n# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate\n# index for LaTeX.\n# The default file is: makeindex.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nMAKEINDEX_CMD_NAME     = makeindex\n\n# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX\n# documents. This may be useful for small projects and may help to save some\n# trees in general.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nCOMPACT_LATEX          = NO\n\n# The PAPER_TYPE tag can be used to set the paper type that is used by the\n# printer.\n# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x\n# 14 inches) and executive (7.25 x 10.5 inches).\n# The default value is: a4.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nPAPER_TYPE             = a4\n\n# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names\n# that should be included in the LaTeX output. The package can be specified just\n# by its name or with the correct syntax as to be used with the LaTeX\n# \\usepackage command. To get the times font for instance you can specify :\n# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}\n# To use the option intlimits with the amsmath package you can specify:\n# EXTRA_PACKAGES=[intlimits]{amsmath}\n# If left blank no extra packages will be included.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nEXTRA_PACKAGES         =\n\n# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the\n# generated LaTeX document. The header should contain everything until the first\n# chapter. If it is left blank doxygen will generate a standard header. See\n# section \"Doxygen usage\" for information on how to let doxygen write the\n# default header to a separate file.\n#\n# Note: Only use a user-defined header if you know what you are doing! The\n# following commands have a special meaning inside the header: $title,\n# $datetime, $date, $doxygenversion, $projectname, $projectnumber,\n# $projectbrief, $projectlogo. Doxygen will replace $title with the empty\n# string, for the replacement values of the other commands the user is referred\n# to HTML_HEADER.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_HEADER           =\n\n# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the\n# generated LaTeX document. The footer should contain everything after the last\n# chapter. If it is left blank doxygen will generate a standard footer. See\n# LATEX_HEADER for more information on how to generate a default footer and what\n# special commands can be used inside the footer.\n#\n# Note: Only use a user-defined footer if you know what you are doing!\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_FOOTER           =\n\n# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined\n# LaTeX style sheets that are included after the standard style sheets created\n# by doxygen. Using this option one can overrule certain style aspects. Doxygen\n# will copy the style sheet files to the output directory.\n# Note: The order of the extra style sheet files is of importance (e.g. the last\n# style sheet in the list overrules the setting of the previous ones in the\n# list).\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_EXTRA_STYLESHEET =\n\n# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or\n# other source files which should be copied to the LATEX_OUTPUT output\n# directory. Note that the files will be copied as-is; there are no commands or\n# markers available.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_EXTRA_FILES      =\n\n# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is\n# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will\n# contain links (just like the HTML output) instead of page references. This\n# makes the output suitable for online browsing using a PDF viewer.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nPDF_HYPERLINKS         = YES\n\n# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate\n# the PDF file directly from the LaTeX files. Set this option to YES, to get a\n# higher quality PDF documentation.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nUSE_PDFLATEX           = YES\n\n# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode\n# command to the generated LaTeX files. This will instruct LaTeX to keep running\n# if errors occur, instead of asking the user for help. This option is also used\n# when generating formulas in HTML.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_BATCHMODE        = NO\n\n# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the\n# index chapters (such as File Index, Compound Index, etc.) in the output.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_HIDE_INDICES     = NO\n\n# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source\n# code with syntax highlighting in the LaTeX output.\n#\n# Note that which sources are shown also depends on other settings such as\n# SOURCE_BROWSER.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_SOURCE_CODE      = NO\n\n# The LATEX_BIB_STYLE tag can be used to specify the style to use for the\n# bibliography, e.g. plainnat, or ieeetr. See\n# http://en.wikipedia.org/wiki/BibTeX and \\cite for more info.\n# The default value is: plain.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_BIB_STYLE        = plain\n\n# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated\n# page will contain the date and time when the page was generated. Setting this\n# to NO can help when comparing the output of multiple runs.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_TIMESTAMP        = NO\n\n#---------------------------------------------------------------------------\n# Configuration options related to the RTF output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The\n# RTF output is optimized for Word 97 and may not look too pretty with other RTF\n# readers/editors.\n# The default value is: NO.\n\nGENERATE_RTF           = NO\n\n# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: rtf.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_OUTPUT             = rtf\n\n# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF\n# documents. This may be useful for small projects and may help to save some\n# trees in general.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nCOMPACT_RTF            = NO\n\n# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will\n# contain hyperlink fields. The RTF file will contain links (just like the HTML\n# output) instead of page references. This makes the output suitable for online\n# browsing using Word or some other Word compatible readers that support those\n# fields.\n#\n# Note: WordPad (write) and others do not support links.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_HYPERLINKS         = NO\n\n# Load stylesheet definitions from file. Syntax is similar to doxygen's config\n# file, i.e. a series of assignments. You only have to provide replacements,\n# missing definitions are set to their default value.\n#\n# See also section \"Doxygen usage\" for information on how to generate the\n# default style sheet that doxygen normally uses.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_STYLESHEET_FILE    =\n\n# Set optional variables used in the generation of an RTF document. Syntax is\n# similar to doxygen's config file. A template extensions file can be generated\n# using doxygen -e rtf extensionFile.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_EXTENSIONS_FILE    =\n\n# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code\n# with syntax highlighting in the RTF output.\n#\n# Note that which sources are shown also depends on other settings such as\n# SOURCE_BROWSER.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_SOURCE_CODE        = NO\n\n#---------------------------------------------------------------------------\n# Configuration options related to the man page output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for\n# classes and files.\n# The default value is: NO.\n\nGENERATE_MAN           = NO\n\n# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it. A directory man3 will be created inside the directory specified by\n# MAN_OUTPUT.\n# The default directory is: man.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_OUTPUT             = man\n\n# The MAN_EXTENSION tag determines the extension that is added to the generated\n# man pages. In case the manual section does not start with a number, the number\n# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is\n# optional.\n# The default value is: .3.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_EXTENSION          = .3\n\n# The MAN_SUBDIR tag determines the name of the directory created within\n# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by\n# MAN_EXTENSION with the initial . removed.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_SUBDIR             =\n\n# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it\n# will generate one additional man file for each entity documented in the real\n# man page(s). These additional files only source the real man page, but without\n# them the man command would be unable to find the correct page.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_LINKS              = NO\n\n#---------------------------------------------------------------------------\n# Configuration options related to the XML output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that\n# captures the structure of the code including all documentation.\n# The default value is: NO.\n\nGENERATE_XML           = NO\n\n# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: xml.\n# This tag requires that the tag GENERATE_XML is set to YES.\n\nXML_OUTPUT             = xml\n\n# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program\n# listings (including syntax highlighting and cross-referencing information) to\n# the XML output. Note that enabling this will significantly increase the size\n# of the XML output.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_XML is set to YES.\n\nXML_PROGRAMLISTING     = YES\n\n#---------------------------------------------------------------------------\n# Configuration options related to the DOCBOOK output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files\n# that can be used to generate PDF.\n# The default value is: NO.\n\nGENERATE_DOCBOOK       = NO\n\n# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in\n# front of it.\n# The default directory is: docbook.\n# This tag requires that the tag GENERATE_DOCBOOK is set to YES.\n\nDOCBOOK_OUTPUT         = docbook\n\n# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the\n# program listings (including syntax highlighting and cross-referencing\n# information) to the DOCBOOK output. Note that enabling this will significantly\n# increase the size of the DOCBOOK output.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_DOCBOOK is set to YES.\n\nDOCBOOK_PROGRAMLISTING = NO\n\n#---------------------------------------------------------------------------\n# Configuration options for the AutoGen Definitions output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an\n# AutoGen Definitions (see http://autogen.sf.net) file that captures the\n# structure of the code including all documentation. Note that this feature is\n# still experimental and incomplete at the moment.\n# The default value is: NO.\n\nGENERATE_AUTOGEN_DEF   = NO\n\n#---------------------------------------------------------------------------\n# Configuration options related to the Perl module output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module\n# file that captures the structure of the code including all documentation.\n#\n# Note that this feature is still experimental and incomplete at the moment.\n# The default value is: NO.\n\nGENERATE_PERLMOD       = NO\n\n# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary\n# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI\n# output from the Perl module output.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_PERLMOD is set to YES.\n\nPERLMOD_LATEX          = NO\n\n# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely\n# formatted so it can be parsed by a human reader. This is useful if you want to\n# understand what is going on. On the other hand, if this tag is set to NO, the\n# size of the Perl module output will be much smaller and Perl will parse it\n# just the same.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_PERLMOD is set to YES.\n\nPERLMOD_PRETTY         = YES\n\n# The names of the make variables in the generated doxyrules.make file are\n# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful\n# so different doxyrules.make files included by the same Makefile don't\n# overwrite each other's variables.\n# This tag requires that the tag GENERATE_PERLMOD is set to YES.\n\nPERLMOD_MAKEVAR_PREFIX =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the preprocessor\n#---------------------------------------------------------------------------\n\n# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all\n# C-preprocessor directives found in the sources and include files.\n# The default value is: YES.\n\nENABLE_PREPROCESSING   = YES\n\n# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names\n# in the source code. If set to NO, only conditional compilation will be\n# performed. Macro expansion can be done in a controlled way by setting\n# EXPAND_ONLY_PREDEF to YES.\n# The default value is: NO.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nMACRO_EXPANSION        = NO\n\n# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then\n# the macro expansion is limited to the macros specified with the PREDEFINED and\n# EXPAND_AS_DEFINED tags.\n# The default value is: NO.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nEXPAND_ONLY_PREDEF     = NO\n\n# If the SEARCH_INCLUDES tag is set to YES, the include files in the\n# INCLUDE_PATH will be searched if a #include is found.\n# The default value is: YES.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nSEARCH_INCLUDES        = YES\n\n# The INCLUDE_PATH tag can be used to specify one or more directories that\n# contain include files that are not input files but should be processed by the\n# preprocessor.\n# This tag requires that the tag SEARCH_INCLUDES is set to YES.\n\nINCLUDE_PATH           =\n\n# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard\n# patterns (like *.h and *.hpp) to filter out the header-files in the\n# directories. If left blank, the patterns specified with FILE_PATTERNS will be\n# used.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nINCLUDE_FILE_PATTERNS  =\n\n# The PREDEFINED tag can be used to specify one or more macro names that are\n# defined before the preprocessor is started (similar to the -D option of e.g.\n# gcc). The argument of the tag is a list of macros of the form: name or\n# name=definition (no spaces). If the definition and the \"=\" are omitted, \"=1\"\n# is assumed. To prevent a macro definition from being undefined via #undef or\n# recursively expanded use the := operator instead of the = operator.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nPREDEFINED             =\n\n# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this\n# tag can be used to specify a list of macro names that should be expanded. The\n# macro definition that is found in the sources will be used. Use the PREDEFINED\n# tag if you want to use a different macro definition that overrules the\n# definition found in the source code.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nEXPAND_AS_DEFINED      =\n\n# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will\n# remove all references to function-like macros that are alone on a line, have\n# an all uppercase name, and do not end with a semicolon. Such function macros\n# are typically used for boiler-plate code, and will confuse the parser if not\n# removed.\n# The default value is: YES.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nSKIP_FUNCTION_MACROS   = YES\n\n#---------------------------------------------------------------------------\n# Configuration options related to external references\n#---------------------------------------------------------------------------\n\n# The TAGFILES tag can be used to specify one or more tag files. For each tag\n# file the location of the external documentation should be added. The format of\n# a tag file without this location is as follows:\n# TAGFILES = file1 file2 ...\n# Adding location for the tag files is done as follows:\n# TAGFILES = file1=loc1 \"file2 = loc2\" ...\n# where loc1 and loc2 can be relative or absolute paths or URLs. See the\n# section \"Linking to external documentation\" for more information about the use\n# of tag files.\n# Note: Each tag file must have a unique name (where the name does NOT include\n# the path). If a tag file is not located in the directory in which doxygen is\n# run, you must also specify the path to the tagfile here.\n\nTAGFILES               =\n\n# When a file name is specified after GENERATE_TAGFILE, doxygen will create a\n# tag file that is based on the input files it reads. See section \"Linking to\n# external documentation\" for more information about the usage of tag files.\n\nGENERATE_TAGFILE       =\n\n# If the ALLEXTERNALS tag is set to YES, all external class will be listed in\n# the class index. If set to NO, only the inherited external classes will be\n# listed.\n# The default value is: NO.\n\nALLEXTERNALS           = NO\n\n# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed\n# in the modules index. If set to NO, only the current project's groups will be\n# listed.\n# The default value is: YES.\n\nEXTERNAL_GROUPS        = YES\n\n# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in\n# the related pages index. If set to NO, only the current project's pages will\n# be listed.\n# The default value is: YES.\n\nEXTERNAL_PAGES         = YES\n\n# The PERL_PATH should be the absolute path and name of the perl script\n# interpreter (i.e. the result of 'which perl').\n# The default file (with absolute path) is: /usr/bin/perl.\n\nPERL_PATH              = /usr/bin/perl\n\n#---------------------------------------------------------------------------\n# Configuration options related to the dot tool\n#---------------------------------------------------------------------------\n\n# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram\n# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to\n# NO turns the diagrams off. Note that this option also works with HAVE_DOT\n# disabled, but it is recommended to install and use dot, since it yields more\n# powerful graphs.\n# The default value is: YES.\n\nCLASS_DIAGRAMS         = YES\n\n# You can define message sequence charts within doxygen comments using the \\msc\n# command. Doxygen will then run the mscgen tool (see:\n# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the\n# documentation. The MSCGEN_PATH tag allows you to specify the directory where\n# the mscgen tool resides. If left empty the tool is assumed to be found in the\n# default search path.\n\nMSCGEN_PATH            =\n\n# You can include diagrams made with dia in doxygen documentation. Doxygen will\n# then run dia to produce the diagram and insert it in the documentation. The\n# DIA_PATH tag allows you to specify the directory where the dia binary resides.\n# If left empty dia is assumed to be found in the default search path.\n\nDIA_PATH               =\n\n# If set to YES the inheritance and collaboration graphs will hide inheritance\n# and usage relations if the target is undocumented or is not a class.\n# The default value is: YES.\n\nHIDE_UNDOC_RELATIONS   = YES\n\n# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is\n# available from the path. This tool is part of Graphviz (see:\n# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent\n# Bell Labs. The other options in this section have no effect if this option is\n# set to NO\n# The default value is: YES.\n\nHAVE_DOT               = YES\n\n# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed\n# to run in parallel. When set to 0 doxygen will base this on the number of\n# processors available in the system. You can set it explicitly to a value\n# larger than 0 to get control over the balance between CPU load and processing\n# speed.\n# Minimum value: 0, maximum value: 32, default value: 0.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_NUM_THREADS        = 0\n\n# When you want a differently looking font in the dot files that doxygen\n# generates you can specify the font name using DOT_FONTNAME. You need to make\n# sure dot is able to find the font, which can be done by putting it in a\n# standard location or by setting the DOTFONTPATH environment variable or by\n# setting DOT_FONTPATH to the directory containing the font.\n# The default value is: Helvetica.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_FONTNAME           = Helvetica\n\n# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of\n# dot graphs.\n# Minimum value: 4, maximum value: 24, default value: 10.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_FONTSIZE           = 10\n\n# By default doxygen will tell dot to use the default font as specified with\n# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set\n# the path where dot can find it using this tag.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_FONTPATH           =\n\n# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for\n# each documented class showing the direct and indirect inheritance relations.\n# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCLASS_GRAPH            = YES\n\n# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a\n# graph for each documented class showing the direct and indirect implementation\n# dependencies (inheritance, containment, and class references variables) of the\n# class with other documented classes.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCOLLABORATION_GRAPH    = YES\n\n# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for\n# groups, showing the direct groups dependencies.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nGROUP_GRAPHS           = YES\n\n# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and\n# collaboration diagrams in a style similar to the OMG's Unified Modeling\n# Language.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nUML_LOOK               = YES\n\n# If the UML_LOOK tag is enabled, the fields and methods are shown inside the\n# class node. If there are many fields or methods and many nodes the graph may\n# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the\n# number of items for each type to make the size more manageable. Set this to 0\n# for no limit. Note that the threshold may be exceeded by 50% before the limit\n# is enforced. So when you set the threshold to 10, up to 15 fields may appear,\n# but if the number exceeds 15, the total amount of fields shown is limited to\n# 10.\n# Minimum value: 0, maximum value: 100, default value: 10.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nUML_LIMIT_NUM_FIELDS   = 10\n\n# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and\n# collaboration graphs will show the relations between templates and their\n# instances.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nTEMPLATE_RELATIONS     = NO\n\n# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to\n# YES then doxygen will generate a graph for each documented file showing the\n# direct and indirect include dependencies of the file with other documented\n# files.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nINCLUDE_GRAPH          = YES\n\n# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are\n# set to YES then doxygen will generate a graph for each documented file showing\n# the direct and indirect include dependencies of the file with other documented\n# files.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nINCLUDED_BY_GRAPH      = YES\n\n# If the CALL_GRAPH tag is set to YES then doxygen will generate a call\n# dependency graph for every global function or class method.\n#\n# Note that enabling this option will significantly increase the time of a run.\n# So in most cases it will be better to enable call graphs for selected\n# functions only using the \\callgraph command. Disabling a call graph can be\n# accomplished by means of the command \\hidecallgraph.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCALL_GRAPH             = NO\n\n# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller\n# dependency graph for every global function or class method.\n#\n# Note that enabling this option will significantly increase the time of a run.\n# So in most cases it will be better to enable caller graphs for selected\n# functions only using the \\callergraph command. Disabling a caller graph can be\n# accomplished by means of the command \\hidecallergraph.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCALLER_GRAPH           = NO\n\n# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical\n# hierarchy of all classes instead of a textual one.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nGRAPHICAL_HIERARCHY    = YES\n\n# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the\n# dependencies a directory has on other directories in a graphical way. The\n# dependency relations are determined by the #include relations between the\n# files in the directories.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDIRECTORY_GRAPH        = YES\n\n# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images\n# generated by dot. For an explanation of the image formats see the section\n# output formats in the documentation of the dot tool (Graphviz (see:\n# http://www.graphviz.org/)).\n# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order\n# to make the SVG files visible in IE 9+ (other browsers do not have this\n# requirement).\n# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd,\n# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo,\n# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo,\n# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and\n# png:gdiplus:gdiplus.\n# The default value is: png.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_IMAGE_FORMAT       = png\n\n# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to\n# enable generation of interactive SVG images that allow zooming and panning.\n#\n# Note that this requires a modern browser other than Internet Explorer. Tested\n# and working are Firefox, Chrome, Safari, and Opera.\n# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make\n# the SVG files visible. Older versions of IE do not have SVG support.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nINTERACTIVE_SVG        = NO\n\n# The DOT_PATH tag can be used to specify the path where the dot tool can be\n# found. If left blank, it is assumed the dot tool can be found in the path.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_PATH               =\n\n# The DOTFILE_DIRS tag can be used to specify one or more directories that\n# contain dot files that are included in the documentation (see the \\dotfile\n# command).\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOTFILE_DIRS           =\n\n# The MSCFILE_DIRS tag can be used to specify one or more directories that\n# contain msc files that are included in the documentation (see the \\mscfile\n# command).\n\nMSCFILE_DIRS           =\n\n# The DIAFILE_DIRS tag can be used to specify one or more directories that\n# contain dia files that are included in the documentation (see the \\diafile\n# command).\n\nDIAFILE_DIRS           =\n\n# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the\n# path where java can find the plantuml.jar file. If left blank, it is assumed\n# PlantUML is not used or called during a preprocessing step. Doxygen will\n# generate a warning when it encounters a \\startuml command in this case and\n# will not generate output for the diagram.\n\nPLANTUML_JAR_PATH      =\n\n# When using plantuml, the specified paths are searched for files specified by\n# the !include statement in a plantuml block.\n\nPLANTUML_INCLUDE_PATH  =\n\n# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes\n# that will be shown in the graph. If the number of nodes in a graph becomes\n# larger than this value, doxygen will truncate the graph, which is visualized\n# by representing a node as a red box. Note that doxygen if the number of direct\n# children of the root node in a graph is already larger than\n# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that\n# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.\n# Minimum value: 0, maximum value: 10000, default value: 50.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_GRAPH_MAX_NODES    = 50\n\n# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs\n# generated by dot. A depth value of 3 means that only nodes reachable from the\n# root by following a path via at most 3 edges will be shown. Nodes that lay\n# further from the root node will be omitted. Note that setting this option to 1\n# or 2 may greatly reduce the computation time needed for large code bases. Also\n# note that the size of a graph can be further restricted by\n# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.\n# Minimum value: 0, maximum value: 1000, default value: 0.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nMAX_DOT_GRAPH_DEPTH    = 0\n\n# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent\n# background. This is disabled by default, because dot on Windows does not seem\n# to support this out of the box.\n#\n# Warning: Depending on the platform used, enabling this option may lead to\n# badly anti-aliased labels on the edges of a graph (i.e. they become hard to\n# read).\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_TRANSPARENT        = NO\n\n# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output\n# files in one run (i.e. multiple -o and -T options on the command line). This\n# makes dot run faster, but since only newer versions of dot (>1.8.10) support\n# this, this feature is disabled by default.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_MULTI_TARGETS      = NO\n\n# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page\n# explaining the meaning of the various boxes and arrows in the dot generated\n# graphs.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nGENERATE_LEGEND        = YES\n\n# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot\n# files that are used to generate the various graphs.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_CLEANUP            = YES\n"
  },
  {
    "path": "LICENSE",
    "content": "                    GNU AFFERO GENERAL PUBLIC LICENSE\n                       Version 3, 19 November 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU Affero General Public License is a free, copyleft license for\nsoftware and other kinds of works, specifically designed to ensure\ncooperation with the community in the case of network server software.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nour General Public Licenses are intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  Developers that use our General Public Licenses protect your rights\nwith two steps: (1) assert copyright on the software, and (2) offer\nyou this License which gives you legal permission to copy, distribute\nand/or modify the software.\n\n  A secondary benefit of defending all users' freedom is that\nimprovements made in alternate versions of the program, if they\nreceive widespread use, become available for other developers to\nincorporate.  Many developers of free software are heartened and\nencouraged by the resulting cooperation.  However, in the case of\nsoftware used on network servers, this result may fail to come about.\nThe GNU General Public License permits making a modified version and\nletting the public access it on a server without ever releasing its\nsource code to the public.\n\n  The GNU Affero General Public License is designed specifically to\nensure that, in such cases, the modified source code becomes available\nto the community.  It requires the operator of a network server to\nprovide the source code of the modified version running there to the\nusers of that server.  Therefore, public use of a modified version, on\na publicly accessible server, gives the public access to the source\ncode of the modified version.\n\n  An older license, called the Affero General Public License and\npublished by Affero, was designed to accomplish similar goals.  This is\na different license, not a version of the Affero GPL, but Affero has\nreleased a new version of the Affero GPL which permits relicensing under\nthis license.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU Affero General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Remote Network Interaction; Use with the GNU General Public License.\n\n  Notwithstanding any other provision of this License, if you modify the\nProgram, your modified version must prominently offer all users\ninteracting with it remotely through a computer network (if your version\nsupports such interaction) an opportunity to receive the Corresponding\nSource of your version by providing access to the Corresponding Source\nfrom a network server at no charge, through some standard or customary\nmeans of facilitating copying of software.  This Corresponding Source\nshall include the Corresponding Source for any work covered by version 3\nof the GNU General Public License that is incorporated pursuant to the\nfollowing paragraph.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the work with which it is combined will remain governed by version\n3 of the GNU General Public License.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU Affero General Public License from time to time.  Such new versions\nwill be similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU Affero General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU Affero General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU Affero General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU Affero General Public License as published\n    by the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU Affero General Public License for more details.\n\n    You should have received a copy of the GNU Affero General Public License\n    along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If your software can interact with users remotely through a computer\nnetwork, you should also make sure that it provides a way for users to\nget its source.  For example, if your program is a web application, its\ninterface could display a \"Source\" link that leads users to an archive\nof the code.  There are many ways you could offer source, and different\nsolutions will be better for different programs; see section 13 for the\nspecific requirements.\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU AGPL, see\n<https://www.gnu.org/licenses/>.\n"
  },
  {
    "path": "README.md",
    "content": "[![AGPL v3](https://img.shields.io/badge/license-AGPL%20v3-brightgreen.svg)](./LICENSE)\n# UC Project\nUChain is the first public infrastructure blockchain specifically designed for the global sharing economy. Along with other sharing economy enterprises, UChain aims to build its underlying blockchain network to solve the current problems of trust and data abuse. Exercising API's and SDK's provided by UChain , all sharing economy enterprises are able to issue their own token and build their application on top of the UChain network, together making UChain a better global autonomous sharing economy ecosystem.\n<br>UC is implemented based on [libbitcoin project](https://github.com/libbitcoin) and [ICE project](https://github.com/zeroc-ice/ice).Also ZeroMQ,secp256k1,miniupnpc and boost are necessary.\n# UC Achitect\n![image](https://raw.githubusercontent.com/wiki/yangguanglu/pics/uchainachitect.jpeg)\n\n# Build UC\n\n## Compiler requirements\n| Compilier | Minimum Version |  \n| ---------| ---------------- | \n| gcc/g++ |   5.0             |  \n| clang++ |   3.4 (8.0.0)     |  \n\nC++ compiler support [C++14](http://en.cppreference.com/w/cpp/compiler_support). \nUsing `c++ -v` to check c++ version.\n- [Upgrade guide for Debian/ubuntuu](https://github.com/libbitcoin/libbitcoin#debianubuntu)\n- [Upgrade guide for OSX](https://github.com/libbitcoin/libbitcoin#macintosh)\n- [Upgrade guide for windows](https://github.com/libbitcoin/libbitcoin#windows)\n\nDependencies of UC are **static linked** (including libstdc++). \nThus, there is no extra dependency after compilation.\nRecommends Ubuntu 16.04/CentOS 7.2/MinGW to develop/debug/build UC.\n\n## Toolchain requirements\n- cmake 3.0+\n- git\n- automake (speck256k1/ZeroMQ required)\n- make ([MinGW for Windows](http://repo.msys2.org/distrib/x86_64/msys2-x86_64-20180531.exe) is supported)\n\n```bash\n$ yum/brew/apt-get install git cmake\n$ yum/brew/apt-get install autoconf automake libtool pkg-config\n```\n\n# Library Dependencies\n*Needs to configure Library Dependencies firstly.*\nInstalling by bash script (sudo required).\n```bash\n$ chmod +x ./install_thirdlibrary\n$ sudo ./install_thirdlibrary\n```\nBy default, `./install_thirdlibrary` will install `ZeroMQ` `secp256k1`.  \nYou can install more by specify arguments, for example:\n```bash\n# --build-upnpc is needed is you want UPnP supporting.\n$ sudo ./install_thirdlibrary --build-boost --build-upnpc\n```\n\n## boost 1.60(boost is required and 1.60 is recommended)\n```bash\n$ sudo yum/brew/apt-get install libboost-all-dev\n```\n\n## ZeroMQ 4.2.5+(required)\nModules server/explorer required.\n\n```bash\n$ wget https://github.com/zeromq/libzmq/releases/download/v4.2.5/zeromq-4.2.5.tar.gz\n$ tar -xzvf zeromq-4.2.5.tar.gz\n$ cd zeromq-4.2.5\n$ ./autogen.sh\n$ ./configure\n$ make\n$ sudo make install && sudo ldconfig\n```\n\n## secp256k1(required) \nModules blockchain/database required.\n\n```bash\n$ git clone https://github.com/UCHAIN-WORLD/secp256k1\n$ cd secp256k1\n$ ./autogen.sh\n$ ./configure --enable-module-recovery\n$ make\n$ sudo make install && sudo ldconfig\n```\n\n## miniupnpc(if needed)\nModules blockchain/network with UPnP function required.\n\n```bash\n$ wget http://miniupnp.tuxfamily.org/files/miniupnpc-2.0.tar.gz\n$ tar -xzvf miniupnpc-2.0.tar.gz\n$ cd miniupnpc-2.0\n$ make\n$ sudo INSTALLPREFIX=/usr/local make install && sudo ldconfig\n```\n\n## Build UC\n```bash\n$ git clone https://github.com/UCHAIN-WORLD/uchain-fullnode.git\n$ cd UChain && mkdir build && cd build\n$ cmake ..\n$ make\n$ make install\n```\nIf you do not need UPnP support, you can use `\"cmake -DUSE_UPNP=OFF ..\"` to disable it.\n<br>And `\"make -j4`\" may be better (-j4 is not always the rigth parameter... could be j2 or j8 it depends by the cpu).\n<br>Also `\"make install-strip`\" may be better(it strips).\n\n\n# Run UC\nAfter UC is built successfully, there are two executable files in the _bin_ directory:\n\n - **ucd** - server program  \n   Runs a full UChain node in the global peer-to-peer network.\n\n - **uc-cli** - client program  \n   Sent your request to the server, the server will process it and return response to your client.\n\nGo to _bin_ diretory, and run the program.\nMore information please reference to [Command line usage]( https://github.com/UCHAIN-WORLD/uchain-fullnode/wiki/commands).\n```bash\n$ cd bin\n$ ./ucd\n$ ./uc-cli $command $params $options\n```\n"
  },
  {
    "path": "UC-AUTHORS",
    "content": "yangguanglu(416841146@qq.com)\ntony(758033884@qq.com)\n\n"
  },
  {
    "path": "etc/CMakeLists.txt",
    "content": "SET(etc_FILES\n  uc.conf\n)\n\nINSTALL(FILES ${etc_FILES} DESTINATION etc)\n"
  },
  {
    "path": "etc/FindCryptoPP.cmake",
    "content": "# Module for locating the Crypto++ encryption library.\n#\n# Customizable variables:\n#   CRYPTOPP_ROOT_DIR\n#     This variable points to the CryptoPP root directory. On Windows the\n#     library location typically will have to be provided explicitly using the\n#     -D command-line option. The directory should include the include/cryptopp,\n#     lib and/or bin sub-directories.\n#\n# Read-only variables:\n#   CRYPTOPP_FOUND\n#     Indicates whether the library has been found.\n#\n#   CRYPTOPP_INCLUDE_DIRS\n#     Points to the CryptoPP include directory.\n#\n#   CRYPTOPP_LIBRARIES\n#     Points to the CryptoPP libraries that should be passed to\n#     target_link_libararies.\n#\n#\n# Copyright (c) 2012 Sergiu Dotenco\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in all\n# copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\nINCLUDE (FindPackageHandleStandardArgs)\n\nFIND_PATH (CRYPTOPP_ROOT_DIR\n  NAMES cryptopp/cryptlib.h include/cryptopp/cryptlib.h\n  PATHS ENV CRYPTOPPROOT\n  DOC \"CryptoPP root directory\")\n\n# Re-use the previous path:\nFIND_PATH (CRYPTOPP_INCLUDE_DIR\n  NAMES cryptopp/cryptlib.h\n  HINTS ${CRYPTOPP_ROOT_DIR}\n  PATH_SUFFIXES include\n  DOC \"CryptoPP include directory\")\n\nFIND_LIBRARY (CRYPTOPP_LIBRARY_DEBUG\n  NAMES cryptlibd cryptoppd\n  HINTS ${CRYPTOPP_ROOT_DIR}\n  PATH_SUFFIXES lib\n  DOC \"CryptoPP debug library\")\n\nFIND_LIBRARY (CRYPTOPP_LIBRARY_RELEASE\n  NAMES cryptlib cryptopp\n  HINTS ${CRYPTOPP_ROOT_DIR}\n  PATH_SUFFIXES lib\n  DOC \"CryptoPP release library\")\n\nIF (CRYPTOPP_LIBRARY_DEBUG AND CRYPTOPP_LIBRARY_RELEASE)\n  SET (CRYPTOPP_LIBRARY\n    optimized ${CRYPTOPP_LIBRARY_RELEASE}\n    debug ${CRYPTOPP_LIBRARY_DEBUG} CACHE DOC \"CryptoPP library\")\nELSEIF (CRYPTOPP_LIBRARY_RELEASE)\n  SET (CRYPTOPP_LIBRARY ${CRYPTOPP_LIBRARY_RELEASE} CACHE DOC\n    \"CryptoPP library\")\nENDIF (CRYPTOPP_LIBRARY_DEBUG AND CRYPTOPP_LIBRARY_RELEASE)\n\nIF (CRYPTOPP_INCLUDE_DIR)\n  SET (_CRYPTOPP_VERSION_HEADER ${CRYPTOPP_INCLUDE_DIR}/cryptopp/config.h)\n\n  IF (EXISTS ${_CRYPTOPP_VERSION_HEADER})\n    FILE (STRINGS ${_CRYPTOPP_VERSION_HEADER} _CRYPTOPP_VERSION_TMP REGEX\n      \"^#define CRYPTOPP_VERSION[ \\t]+[0-9]+$\")\n\n    STRING (REGEX REPLACE\n      \"^#define CRYPTOPP_VERSION[ \\t]+([0-9]+)\" \"\\\\1\" _CRYPTOPP_VERSION_TMP\n      ${_CRYPTOPP_VERSION_TMP})\n\n    STRING (REGEX REPLACE \"([0-9]+)[0-9][0-9]\" \"\\\\1\" CRYPTOPP_VERSION_MAJOR\n      ${_CRYPTOPP_VERSION_TMP})\n    STRING (REGEX REPLACE \"[0-9]([0-9])[0-9]\" \"\\\\1\" CRYPTOPP_VERSION_MINOR\n      ${_CRYPTOPP_VERSION_TMP})\n    STRING (REGEX REPLACE \"[0-9][0-9]([0-9])\" \"\\\\1\" CRYPTOPP_VERSION_PATCH\n      ${_CRYPTOPP_VERSION_TMP})\n\n    SET (CRYPTOPP_VERSION_COUNT 3)\n    SET (CRYPTOPP_VERSION\n      ${CRYPTOPP_VERSION_MAJOR}.${CRYPTOPP_VERSION_MINOR}.${CRYPTOPP_VERSION_PATCH})\n  ENDIF (EXISTS ${_CRYPTOPP_VERSION_HEADER})\nENDIF (CRYPTOPP_INCLUDE_DIR)\n\nSET (CRYPTOPP_INCLUDE_DIRS ${CRYPTOPP_INCLUDE_DIR})\nSET (CRYPTOPP_LIBRARIES ${CRYPTOPP_LIBRARY})\n\nMARK_AS_ADVANCED (CRYPTOPP_INCLUDE_DIR CRYPTOPP_LIBRARY CRYPTOPP_LIBRARY_DEBUG\n  CRYPTOPP_LIBRARY_RELEASE)\n\nFIND_PACKAGE_HANDLE_STANDARD_ARGS (CryptoPP REQUIRED_VARS CRYPTOPP_ROOT_DIR\n  CRYPTOPP_INCLUDE_DIR CRYPTOPP_LIBRARY VERSION_VAR CRYPTOPP_VERSION)\n"
  },
  {
    "path": "etc/FindIphlpapi.cmake",
    "content": "find_path(iphlpapi_ROOT_DIR\n    NAMES include/iphlpapi.h\n\t)\nfind_library(iphlpapi_LIBRARIES\n    NAMES iphlpapi libiphlpapi\n    HINTS ${iphlpapi_ROOT_DIR}/lib)\n\nfind_path(iphlpapi_INCLUDE_DIRS\n\tNAMES iphlpapi.h\n\tHINTS ${iphlpapi_ROOT_DIR}/include\n)\ninclude(FindPackageHandleStandardArgs)\nfind_package_handle_standard_args(iphlpapi DEFAULT_MSG\n\tiphlpapi_LIBRARIES\n\tiphlpapi_INCLUDE_DIRS\n)\nmark_as_advanced(\n\tiphlpapi_ROOT_DIR\n\tiphlpapi_LIBRARIES\n\tiphlpapi_INCLUDE_DIRS\n)\n"
  },
  {
    "path": "etc/FindZeroMQ.cmake",
    "content": "# hao chen. 2017.03\n# ref: https://github.com/zeromq/azmq/blob/master/config/FindZeroMQ.cmake\n# Variables\n# ZeroMQ_ROOT_DIR - set this to a location where ZeroMQ may be found\n#\n# ZeroMQ_FOUND - True of ZeroMQ found\n# ZeroMQ_INCLUDE_DIRS - Location of ZeroMQ includes\n# ZeroMQ_LIBRARIES - ZeroMQ libraries\n\ninclude(FindPackageHandleStandardArgs)\n\nfind_path(ZeroMQ_ROOT_DIR\n    NAMES include/zmq.h\n)\n\nset(_ZeroMQ_ROOT ${ZeroMQ_ROOT_DIR})\nfind_path(ZeroMQ_INCLUDE_DIRS\n    NAMES zmq.h\n    HINTS ${ZeroMQ_ROOT_DIR}/include\n)\n\nif (ZeroMQ_INCLUDE_DIRS)\n    set(_ZeroMQ_H ${ZeroMQ_INCLUDE_DIRS}/zmq.h)\n\n    function(_zmqver_EXTRACT _ZeroMQ_VER_COMPONENT _ZeroMQ_VER_OUTPUT)\n        set(CMAKE_MATCH_1 \"0\")\n        set(_ZeroMQ_expr \"^[ \\\\t]*#define[ \\\\t]+${_ZeroMQ_VER_COMPONENT}[ \\\\t]+([0-9]+)$\")\n        file(STRINGS \"${_ZeroMQ_H}\" _ZeroMQ_ver REGEX \"${_ZeroMQ_expr}\")\n        string(REGEX MATCH \"${_ZeroMQ_expr}\" ZeroMQ_ver \"${_ZeroMQ_ver}\")\n        set(${_ZeroMQ_VER_OUTPUT} \"${CMAKE_MATCH_1}\" PARENT_SCOPE)\n    endfunction()\n\n    _zmqver_EXTRACT(\"ZMQ_VERSION_MAJOR\" ZeroMQ_VERSION_MAJOR)\n    _zmqver_EXTRACT(\"ZMQ_VERSION_MINOR\" ZeroMQ_VERSION_MINOR)\n    _zmqver_EXTRACT(\"ZMQ_VERSION_PATCH\" ZeroMQ_VERSION_PATCH)\n\n    message(STATUS \"ZeroMQ version: ${ZeroMQ_VERSION_MAJOR}.${ZeroMQ_VERSION_MINOR}.${ZeroMQ_VERSION_PATCH}\")\n\n    # We should provide version to find_package_handle_standard_args in the same format as it was requested,\n    # otherwise it can't check whether version matches exactly.\n    if (ZeroMQ_FIND_VERSION_COUNT GREATER 2)\n        set(ZeroMQ_VERSION \"${ZeroMQ_VERSION_MAJOR}.${ZeroMQ_VERSION_MINOR}.${ZeroMQ_VERSION_PATCH}\")\n    else()\n        # User has requested ZeroMQ version without patch part => user is not interested in specific patch =>\n        # any patch should be an exact match.\n        set(ZeroMQ_VERSION \"${ZeroMQ_VERSION_MAJOR}.${ZeroMQ_VERSION_MINOR}\")\n    endif()\n\n    if (NOT ${CMAKE_CXX_PLATFORM_ID} STREQUAL \"Windows\")\n        if (ANDROID)\n           find_library(ZeroMQ_LIBRARIES NAMES libzmq.a HINTS ${_ZeroMQ_ROOT}/lib)\n        else()\n           find_library(ZeroMQ_LIBRARIES NAMES zmq HINTS ${_ZeroMQ_ROOT}/lib)\n        endif()\n        #        message(zeromqlib ${ZeroMQ_LIBRARIES})\n    else()\n        find_library(\n            ZeroMQ_LIBRARY_RELEASE\n            NAMES\n                zmq\n                libzmq\n                \"libzmq-${CMAKE_VS_PLATFORM_TOOLSET}-mt-${ZeroMQ_VERSION_MAJOR}_${ZeroMQ_VERSION_MINOR}_${ZeroMQ_VERSION_PATCH}\"\n            HINTS\n                ${_ZeroMQ_ROOT}/lib\n            )\n\n        find_library(\n            ZeroMQ_LIBRARY_DEBUG\n            NAMES\n                libzmq_d\n                \"libzmq-${CMAKE_VS_PLATFORM_TOOLSET}-mt-gd-${ZeroMQ_VERSION_MAJOR}_${ZeroMQ_VERSION_MINOR}_${ZeroMQ_VERSION_PATCH}\"\n            HINTS\n                ${_ZeroMQ_ROOT}/lib)\n\n        # On Windows we have to use corresponding version (i.e. Release or Debug) of ZeroMQ because of `errno` CRT global variable\n        # See more at http://www.drdobbs.com/avoiding-the-visual-c-runtime-library/184416623\n        set(ZeroMQ_LIBRARIES optimized \"${ZeroMQ_LIBRARY_RELEASE}\" debug \"${ZeroMQ_LIBRARY_DEBUG}\")\n    endif()\nendif()\n\nfind_package_handle_standard_args(ZeroMQ FOUND_VAR ZeroMQ_FOUND\n    REQUIRED_VARS ZeroMQ_INCLUDE_DIRS ZeroMQ_LIBRARIES\n    VERSION_VAR ZeroMQ_VERSION)\n\nif (ZeroMQ_FOUND)\n    mark_as_advanced(ZeroMQ_ROOT_DIR ZeroMQ_INCLUDE_DIRS ZeroMQ_LIBRARIES ZeroMQ_VERSION\n        ZeroMQ_VERSION_MAJOR ZeroMQ_VERSION_MINOR ZeroMQ_VERSION_PATCH)\nendif()\n"
  },
  {
    "path": "etc/Findminiupnpc.cmake",
    "content": "# Module for locating the miniupnpc library.\nfind_path(miniupnpc_ROOT_DIR\n    NAMES include/miniupnpc/miniupnpc.h\n)\nfind_library(miniupnpc_LIBRARIES\n    NAMES miniupnpc libminiupnpc\n    HINTS ${miniupnpc_ROOT_DIR}/lib\n)\nfind_path(miniupnpc_INCLUDE_DIRS\n    NAMES miniupnpc/miniupnpc.h\n    HINTS ${miniupnpc_ROOT_DIR}/include\n)\ninclude(FindPackageHandleStandardArgs)\nfind_package_handle_standard_args(miniupnpc DEFAULT_MSG\n    miniupnpc_LIBRARIES\n    miniupnpc_INCLUDE_DIRS\n)\nmark_as_advanced(\n    miniupnpc_ROOT_DIR\n    miniupnpc_LIBRARIES\n    miniupnpc_INCLUDE_DIRS\n)\n"
  },
  {
    "path": "etc/Findsecp256k1.cmake",
    "content": "find_path(secp256k1_ROOT_DIR\n    NAMES include/secp256k1.h\n)\nfind_library(secp256k1_LIBRARIES\n    NAMES secp256k1 libsecp256k1\n    HINTS ${secp256k1_ROOT_DIR}/lib\n)\nfind_path(secp256k1_INCLUDE_DIRS\n    NAMES secp256k1.h\n    HINTS ${secp256k1_ROOT_DIR}/include\n)\ninclude(FindPackageHandleStandardArgs)\nfind_package_handle_standard_args(secp256k1 DEFAULT_MSG\n    secp256k1_LIBRARIES\n    secp256k1_INCLUDE_DIRS\n)\nmark_as_advanced(\n    secp256k1_ROOT_DIR\n    secp256k1_LIBRARIES\n    secp256k1_INCLUDE_DIRS\n)\n\n#if (secp256k1_INCLUDE_DIRS)\n#\tset(secp256k1_LIB_VERSION 0)\n#\tfile(STRINGS \"${Boost_INCLUDE_DIR}/zmq.h\" _zmq_VERSION_H_CONTENTS REGEX \"#define ZMQ_VERSION_*\")\n#endif()\n"
  },
  {
    "path": "etc/uc-full-setting-template.conf",
    "content": "# uc configuration file exmaple\n\n[network]\n# The minimum number of threads in the application threadpool, defaults to 50.\nthreads = 10\n# The network protocol version, defaults to 70012.\nprotocol = 70012\n# The magic number for message headers\nidentifier = 0x6d73766d\n# The port for incoming connections, defaults to 5682 (15678 for testnet).\ninbound_port = 5682\n# The target number of incoming network connections, defaults to 8 when upnp_map_port and be_found are true.\ninbound_connections = 128\n# The target number of outgoing network connections, defaults to 8.\noutbound_connections = 8\n# The attempt limit for manual connection establishment, defaults to 0 (forever).\nmanual_attempt_limit = 0\n# The number of concurrent attempts to estalish one connection, defaults to 5.\nconnect_batch_size = 5\n# The time limit for connection establishment, defaults to 5.\nconnect_timeout_seconds = 5\n# The time limit to complete the connection handshake, defaults to 30.\nchannel_handshake_seconds = 30\n# The time between ping messages, defaults to 5.\nchannel_heartbeat_minutes = 5\n# The inactivity time limit for any connection, defaults to 30.\nchannel_inactivity_minutes = 30\n# The maximum age limit for an outbound connection, defaults to 1440.\nchannel_expiration_minutes = 1440\n# The maximum time limit for obtaining seed addresses, defaults to 30.\nchannel_germination_seconds = 30\n# The maximum number of peer hosts in the pool, defaults to 1000.\nhost_pool_capacity = 1000\n# Request that peers relay transactions, defaults to true.\nrelay_transactions = true\n# Re-connect the seed nodes to refresh local hosts cache, when the actual number of outgoing network connection <= 1.\nenable_re_seeding = true\n# The peer hosts cache file path, defaults to 'hosts.cache'.\nhosts_file = hosts.cache\n# The debug log file path, defaults to 'debug.log'.\ndebug_file = debug.log\n# The error log file path, defaults to 'error.log'.\nerror_file = error.log\n# The advertised public address of this node, defaults to none.\nself = 127.0.0.1:0\n# IP address to disallow as a peer, multiple entries allowed.\n#blacklist = 127.0.0.1\n# Persistent host:port channels, multiple entries allowed.\n#peer = obelisk.airbitz.co:5682\n# A seed node for initializing the host pool, multiple entries allowed, defaults shown.\n#seed = main-uchain-a.live:5682\n#seed = main-uchain-b.live:5682\n#seed = main-uchain-c.live:5682\n#seed = main-uchain-d.live:5682\n#seed = main-uchain-e.live:5682\n#seed = main-uchain-f.live:5682\n# Testnet seed nodes.\n#seed = test-uchain-a.live:15678\n#seed = test-uchain-a.live:15678\n#seed = test-uchain-a.live:15678\n#seed = test-uchain-a.live:15678\n#seed = test-uchain-a.live:15678\n#seed = test-uchain-a.live:15678\n# Add a upnp map port in your router which has a extern address to allow connections to your local address.\nupnp_map_port = true\n# If broadcast your upnp extern address on the network to allow others find you and connect you.\nbe_found = true\n\n[database]\n# The lower limit of spend indexing, defaults to 0.\nhistory_start_height = 0\n# The lower limit of stealth indexing, defaults to 350000.\nstealth_start_height = 350000\n# The blockchain database directory, defaults to 'mainnet-blockchain'.\ndirectory = mainnet\n\n[blockchain]\n# The maximum number of orphan blocks in the pool, defaults to 50.\nblock_pool_capacity = 5000\n# The maximum number of transactions in the pool, defaults to 2000.\ntx_pool_capacity = 2000\n# Enforce consistency between the pool and the blockchain, defaults to false.\ntx_pool_consistency = false\n# Use testnet rules for determination of work required, defaults to false.\nuse_testnet_rules = false\n# A hash:height checkpoint, multiple entries allowed, defaults shown.\n#checkpoint = b0a3db8153352dc4384c605f17240dde1c63e55c582b2cdd0000d6f2eaedcaea:0\n#checkpoint = b0a3db8153352dc4384c605f17240dde1c63e55c582b2cdd0000d6f2eaedcaea:1000\n#checkpoint = b0a3db8153352dc4384c605f17240dde1c63e55c582b2cdd0000d6f2eaedcaea:10000\n#checkpoint = b0a3db8153352dc4384c605f17240dde1c63e55c582b2cdd0000d6f2eaedcaea:100000\n\n[node]\n# The time limit for block receipt during initial block download, defaults to 5.\nblock_timeout_seconds = 5\n# The maximum number of connections for initial block download, defaults to 8.\ndownload_connections = 8\n# Refresh the transaction pool on reorganization and channel start, defaults to true.\ntx_pool_refresh = true\n\n[server]\n# The maximum number of query worker threads per endpoint, defaults to 1.\nquery_workers = 1\n# The heartbeat interval, defaults to 5.\nheartbeat_interval_seconds = 5\n# The subscription expiration time, defaults to 10.\nsubscription_expiration_minutes = 10\n# The maximum number of subscriptions, defaults to 100000000.\nsubscription_limit = 100000000\n# mongoose listen port\n# for private\n#mongoose_listen = 127.0.0.1:8707\n# for public\n#mongoose_listen = 0.0.0.0:8707\n# Write service requests to the log, defaults to false.\nlog_requests = false\n# Disable public endpoints, defaults to false.\nsecure_only = false\n# Enable the query service, defaults to true.\nquery_service_enabled = true\n# Enable the heartbeat service, defaults to false.\nheartbeat_service_enabled = false\n# Enable the block publishing service, defaults to false.\nblock_service_enabled = false\n# Enable the transaction publishing service, defaults to false.\ntx_service_enabled = false\n# The public query endpoint, defaults to 'tcp://*:18707'.\npublic_query_endpoint = tcp://*:18707\n# The public heartbeat endpoint, defaults to 'tcp://*:9092'.\npublic_heartbeat_endpoint = tcp://*:9002\n# The public block publishing endpoint, defaults to 'tcp://*:9093'.\npublic_block_endpoint = tcp://*:9003\n# The public transaction publishing endpoint, defaults to 'tcp://*:9094'.\npublic_transaction_endpoint = tcp://*:9004\n# The secure query endpoint, defaults to 'tcp://*:9081'.\nsecure_query_endpoint = tcp://*:9081\n# The secure heartbeat endpoint, defaults to 'tcp://*:9082'.\nsecure_heartbeat_endpoint = tcp://*:9082\n# The secure block publishing endpoint, defaults to 'tcp://*:9083'.\nsecure_block_endpoint = tcp://*:9083\n# The secure transaction publishing endpoint, defaults to 'tcp://*:9084'.\nsecure_transaction_endpoint = tcp://*:9084\n# The Z85-encoded private key of the server, enables secure endpoints.\n#server_private_key =\n# Allowed Z85-encoded public key of the client, multiple entries allowed.\n#client_public_key =\n# Allowed client IP address, multiple entries allowed.\n#client_address = 127.0.0.1\n"
  },
  {
    "path": "etc/uc-test.conf",
    "content": "# uc configuration in common usage for TESTNET\n\n[network]\n# The port for incoming connections, defaults to 5682 (15678 for testnet).\ninbound_port = 15678\n# The target number of incoming network connections, defaults to 8 when upnp_map_port and be_found are true.\ninbound_connections = 32\n# The target number of outgoing network connections, defaults to 8.\noutbound_connections = 8\n# The cached peer hosts when startup\nhosts_file = hosts-test.cache\n# The debug log file path, defaults to 'debug.log'.\ndebug_file = debug.log\n# The error log file path, defaults to 'error.log'.\nerror_file = error.log\n# The advertised public address of this node, defaults to none.\n#self = your_own_public_ip_address:port\n# IP address to disallow as a peer, multiple entries allowed.\nblacklist = 127.0.0.1\n# Persistent host:port channels, multiple entries allowed.\n#peer = main-uchain-a.live:15678\n# Add a upnp map port in your router which has a extern address to allow connections to your local address.\nupnp_map_port = true\n# If broadcast your upnp extern address on the network to allow others find you and connect you.\nbe_found = true\n\n[database]\n# The blockchain database directory, defaults to 'mainnet' of below default path.\n# Windows   : %HOMEPATH%\\AppData\\Roaming\\UChain\n# Apple OSX : ~/Library/Application\\ Support/UChain\n# Linux/Uinx: ~/.UChain\n# Eg:\n# directory = D:\\UC\\ChainData\\UChain\n# directory = /var/local/UChain\n\n[server]\n# The maximum number of query worker threads per endpoint, defaults to 1.\nquery_workers = 1\n\n# local http RPC call listen port\nmongoose_listen = 127.0.0.1:8707\n\n# Write service requests to the log, defaults to false.\nlog_level = DEBUG\n\n"
  },
  {
    "path": "etc/uc.conf",
    "content": "# uc configuration in common usage in MAINNET\n# uc.conf default in path as below\n# Windows   : %HOMEPATH%\\AppData\\Roaming\\UChain\n# Apple OSX : ~/Library/Application\\ Support/UChain\n# Linux/Uinx: ~/.UChain\n\n[network]\n# The port for incoming connections, defaults to 5682 (15678 for testnet).\ninbound_port = 5682\n# The target number of incoming network connections, defaults to 8 when upnp_map_port and be_found are true.\ninbound_connections = 128\n# The target number of outgoing network connections, defaults to 8.\noutbound_connections = 8\n# The cached peer hosts when startup\nhosts_file = hosts.cache\n# The debug log file path, defaults to 'debug.log'.\ndebug_file = debug.log\n# The error log file path, defaults to 'error.log'.\nerror_file = error.log\n# The advertised public address of this node, defaults to none.\n#self = your_own_public_ip_address:port\n# IP address to disallow as a peer, multiple entries allowed.\nblacklist = 127.0.0.1\n# Persistent host:port channels, multiple entries allowed.\n# peer = seed.getuc.org:5682\n# Add a upnp map port in your router which has a extern address to allow connections to your local address.\nupnp_map_port = true\n# If broadcast your upnp extern address on the network to allow others find you and connect you.\nbe_found = true\n\n[database]\n# The blockchain database directory, defaults to 'mainnet' of below default path.\n# Windows   : %HOMEPATH%\\AppData\\Roaming\\UChain\n# Apple OSX : ~/Library/Application\\ Support/UChain\n# Linux/Uinx: ~/.UChain\n# Eg:\n# directory = D:\\UC\\ChainData\\UChain\n# directory = /var/local/UChain\n\n[server]\n# local http RPC call listen port\nmongoose_listen = 127.0.0.1:8707\n\n# Write service requests to the log, defaults to false.\nlog_level = DEBUG\n#if true, some api cannot be permitted: send_tx, createwallet, deletewallet, changepass, addaddress, \\\n# importwallet, exportkeyfile, \"exportwalletasfile\", importkeyfile, \"importwalletfromfile\", \\\n# shutdown, addpeer, stopmining, \"stop\", startmining, \"start\", createrawtx, \\\n# signrawtx, sendrawtx, createmultisigaddress, deletemultisigaddress, createmultisigtx, \\\n# signmultisigtx, deposit, sendto, \"uidsendto\", sendtomulti, \"uidsendtomulti\", \\\n# sendfrom, \"uidsendfrom\", createtoken, deletetoken, \"deletetoken\", registertoken, \\\n# sendtokento, \"uidsendtokento\", sendtokenfrom, \"uidsendtokenfrom\", destroy, vote, \\\n# registercandidate, transfercandidate, registeruid, transferuid, checkwalletinfo, \\\n# showaddresses, showbalances, showbalance, showwallettoken, decoderawtx, \\\n# checkpublickey\nread_only = false\n\n"
  },
  {
    "path": "include/CMakeLists.txt",
    "content": "INSTALL(DIRECTORY \"${PROJECT_SOURCE_DIR}/include/UChain\"\n                  DESTINATION include\n                  FILES_MATCHING\n                  PATTERN \"*.h\"\n                  PATTERN \"*.hpp\")\nINSTALL(DIRECTORY \"${PROJECT_SOURCE_DIR}/include/UChainService\"\n                  DESTINATION include\n                  FILES_MATCHING\n                  PATTERN \"*.h\"\n                  PATTERN \"*.hpp\")\nINSTALL(DIRECTORY \"${PROJECT_SOURCE_DIR}/include/UChainApp\"\n                  DESTINATION include\n                  FILES_MATCHING\n                  PATTERN \"*.h\"\n                  PATTERN \"*.hpp\")\nINSTALL(DIRECTORY \"${PROJECT_SOURCE_DIR}/thirdparty/mongoose\"\n                  DESTINATION include/UChain\n                  FILES_MATCHING\n                  PATTERN \"*.h\"\n                  PATTERN \"*.hpp\")\nINSTALL(DIRECTORY \"${PROJECT_SOURCE_DIR}/thirdparty/json\"\n                  DESTINATION include/UChain\n                  FILES_MATCHING\n                  PATTERN \"*.h\"\n                  PATTERN \"*.hpp\")\n"
  },
  {
    "path": "include/UChain/blockchain/block.hpp",
    "content": "/*\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_BLOCKCHAIN_BLOCK_LOCATOR_INDEXES_HPP\n#define UC_BLOCKCHAIN_BLOCK_LOCATOR_INDEXES_HPP\n\n#include <cstdint>\n#include <UChain/coin.hpp>\n#include <UChain/blockchain/define.hpp>\n#include <UChain/coin/chain/header.hpp>\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\n\nBCB_API u256 block_work(u256 bits);\n\nBCB_API chain::block::indexes block_locator_indexes(size_t top_height);\n\n} // namespace blockchain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/blockchain/block_chain.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_BLOCKCHAIN_BLOCK_CHAIN_HPP\n#define UC_BLOCKCHAIN_BLOCK_CHAIN_HPP\n\n#include <cstdint>\n#include <functional>\n#include <memory>\n#include <vector>\n#include <UChain/coin.hpp>\n#include <UChain/blockchain/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\n\nclass organizer;\n\n/// This intrface is thread safe.\n/// A high level interface for encapsulation of the blockchain database.\n/// Implementations are expected to be thread safe.\nclass BCB_API block_chain\n{\n  public:\n    typedef handle0 result_handler;\n    typedef handle0 block_import_handler;\n    typedef handle1<uint64_t> block_store_handler;\n    typedef handle1<chain::header> block_header_fetch_handler;\n    typedef handle1<chain::block::ptr> block_fetch_handler;\n    typedef handle1<message::merkle_block::ptr> merkle_block_fetch_handler;\n    typedef handle1<hash_list> block_locator_fetch_handler;\n    typedef handle1<hash_list> locator_block_hashes_fetch_handler;\n    typedef handle1<chain::header::list> locator_block_headers_fetch_handler;\n    typedef handle1<hash_list> transaction_hashes_fetch_handler;\n    typedef handle1<uint64_t> block_height_fetch_handler;\n    typedef handle1<uint64_t> last_height_fetch_handler;\n    typedef handle1<chain::transaction> transaction_fetch_handler;\n    typedef handle1<std::shared_ptr<chain::transaction::list>> transactions_fetch_handler;\n    typedef handle1<chain::input_point> spend_fetch_handler;\n    typedef handle1<chain::history_compact::list> history_fetch_handler;\n    typedef handle1<chain::stealth_compact::list> stealth_fetch_handler;\n    typedef handle2<uint64_t, uint64_t> transaction_index_fetch_handler;\n\n    typedef std::function<bool(const code &, uint64_t,\n                               const message::block_msg::ptr_list &,\n                               const message::block_msg::ptr_list &)>\n        reorganize_handler;\n\n    virtual bool start() = 0;\n    virtual bool stop() = 0;\n    virtual bool close() = 0;\n\n    virtual void store(message::block_msg::ptr block,\n                       block_store_handler handler) = 0;\n\n    virtual void fetch_block(uint64_t height,\n                             block_fetch_handler handler) = 0;\n    virtual void fetch_block(const hash_digest &hash,\n                             block_fetch_handler handler) = 0;\n\n    virtual void fetch_block_header(uint64_t height,\n                                    block_header_fetch_handler handler) = 0;\n    virtual void fetch_block_headers(uint64_t start,\n                                     uint64_t end, bool order, locator_block_headers_fetch_handler handler, uint32_t count = 0) = 0;\n    virtual void fetch_block_header(const hash_digest &hash,\n                                    block_header_fetch_handler handler) = 0;\n\n    virtual void fetch_merkle_block(uint64_t height,\n                                    merkle_block_fetch_handler handler) = 0;\n    virtual void fetch_merkle_block(const hash_digest &hash,\n                                    merkle_block_fetch_handler handler) = 0;\n\n    virtual void fetch_block_transaction_hashes(uint64_t height,\n                                                transaction_hashes_fetch_handler handler) = 0;\n    virtual void fetch_block_transaction_hashes(const hash_digest &hash,\n                                                transaction_hashes_fetch_handler handler) = 0;\n\n    virtual void fetch_block_locator(block_locator_fetch_handler handler) = 0;\n\n    virtual void fetch_locator_block_hashes(const message::get_blocks &locator,\n                                            const hash_digest &threshold, size_t limit,\n                                            locator_block_hashes_fetch_handler handler) = 0;\n\n    virtual void fetch_locator_block_headers(\n        const message::get_headers &locator, const hash_digest &threshold,\n        size_t limit, locator_block_headers_fetch_handler handler) = 0;\n\n    virtual void fetch_block_height(const hash_digest &hash,\n                                    block_height_fetch_handler handler) = 0;\n\n    virtual void fetch_last_height(last_height_fetch_handler handler) = 0;\n\n    virtual void fetch_transaction(const hash_digest &hash,\n                                   transaction_fetch_handler handler) = 0;\n\n    virtual void fetch_transaction_index(const hash_digest &hash,\n                                         transaction_index_fetch_handler handler) = 0;\n\n    virtual void fetch_spend(const chain::output_point &outpoint,\n                             spend_fetch_handler handler) = 0;\n\n    virtual void fetch_history(const bc::wallet::payment_address &address,\n                               uint64_t limit, uint64_t from_height,\n                               history_fetch_handler handler) = 0;\n\n    virtual void fetch_stealth(const binary &filter, uint64_t from_height,\n                               stealth_fetch_handler handler) = 0;\n\n    virtual void filter_blocks(message::get_data::ptr message,\n                               result_handler handler) = 0;\n\n    virtual void filter_orphans(message::get_data::ptr message,\n                                result_handler handler) = 0;\n\n    virtual void filter_transactions(message::get_data::ptr message,\n                                     result_handler handler) = 0;\n\n    virtual void subscribe_reorganize(reorganize_handler handler) = 0;\n\n    virtual void fired() = 0; // used for removing out of date action\n    virtual organizer &get_organizer() = 0;\n};\n\n} // namespace blockchain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/blockchain/block_chain_impl.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_BLOCKCHAIN_BLOCK_CHAIN_IMPL_HPP\n#define UC_BLOCKCHAIN_BLOCK_CHAIN_IMPL_HPP\n\n#include <atomic>\n#include <cstddef>\n#include <cstdint>\n#include <vector>\n#include <functional>\n#include <UChain/coin.hpp>\n#include <UChain/database.hpp>\n#include <UChain/blockchain/block_chain.hpp>\n#include <UChain/blockchain/define.hpp>\n#include <UChain/blockchain/organizer.hpp>\n#include <UChain/blockchain/settings.hpp>\n#include <UChain/blockchain/simple_chain.hpp>\n#include <UChain/blockchain/tx_pool.hpp>\n#include <UChain/coin/chain/header.hpp>\n#include <UChain/coin/chain/header.hpp>\n\n#define LOG_BLOCK_CHAIN_IMPL \"block_chain_impl\"\nusing namespace libbitcoin::message;\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\n\ntypedef console_result operation_result;\n\n/// The simple_chain interface portion of this class is not thread safe.\nclass BCB_API block_chain_impl\n    : public block_chain,\n      public simple_chain\n{\n  public:\n    block_chain_impl(threadpool &pool,\n                     const blockchain::settings &chain_settings,\n                     const database::settings &database_settings);\n\n    /// The database is closed on destruct, threads must be joined.\n    ~block_chain_impl();\n\n    /// This class is not copyable.\n    block_chain_impl(const block_chain_impl &) = delete;\n    void operator=(const block_chain_impl &) = delete;\n\n    // Properties (thread safe).\n    // ------------------------------------------------------------------------\n\n    // Get a reference to the transaction pool.\n    tx_pool &pool();\n\n    // Get a reference to the blockchain configuration settings.\n    const settings &chain_settings() const;\n\n    // block_chain start/stop (thread safe).\n    // ------------------------------------------------------------------------\n\n    /// Start or restart the blockchain.\n    virtual bool start();\n\n    /// Signal stop of current work, speeds shutdown with multiple threads.\n    virtual bool stop();\n\n    /// Close the blockchain, threads must first be joined, can be restarted.\n    virtual bool close();\n\n    // simple_chain (NOT THREAD SAFE).\n    // ------------------------------------------------------------------------\n\n    /// Return the first and last gaps in the blockchain, or false if none.\n    bool get_gap_range(uint64_t &out_first, uint64_t &out_last) const;\n\n    /// Return the next chain gap at or after the specified start height.\n    bool get_next_gap(uint64_t &out_height, uint64_t start_height) const;\n\n    /// Get the dificulty of a block at the given height.\n    bool get_difficulty(u256 &out_difficulty, uint64_t height) const;\n\n    /// Get the header of the block at the given height.\n    bool get_header(chain::header &out_header, uint64_t height) const;\n\n    /// Get the height of the block with the given hash.\n    bool get_height(uint64_t &out_height, const hash_digest &block_hash) const;\n\n    /// Get height of latest block.\n    bool get_last_height(uint64_t &out_height) const;\n\n    /// Get the hash digest of the transaction of the outpoint.\n    bool get_outpoint_transaction(hash_digest &out_transaction,\n                                  const chain::output_point &outpoint) const;\n\n    /// Get the transaction of the given hash and its block height.\n    bool get_transaction(chain::transaction &out_transaction,\n                         uint64_t &out_block_height, const hash_digest &transaction_hash) const;\n\n    /// Import a block to the blockchain.\n    bool import(chain::block::ptr block, uint64_t height);\n\n    /// Append the block to the top of the chain.\n    bool push(block_info::ptr block);\n\n    /// Remove blocks at or above the given height, returning them in order.\n    bool pop_from(block_info::list &out_blocks, uint64_t height);\n\n    // block_chain queries (thread safe).\n    // ------------------------------------------------------------------------\n\n    /// Store a block to the blockchain, with indexing and validation.\n    void store(message::block_msg::ptr block,\n               block_store_handler handler);\n\n    /// fetch a block by height.\n    void fetch_block(uint64_t height, block_fetch_handler handler);\n\n    /// fetch a block by height.\n    void fetch_block(const hash_digest &hash, block_fetch_handler handler);\n\n    void fetch_latest_transactions(uint32_t index, uint32_t count,\n                                   transactions_fetch_handler handler);\n    /// fetch block header by height.\n    void fetch_block_header(uint64_t height,\n                            block_header_fetch_handler handler);\n    // fetch blocks header by height range.\n    void fetch_block_headers(uint64_t start,\n                             uint64_t end, bool order, locator_block_headers_fetch_handler handler, uint32_t count = 0);\n    /// fetch block header by hash.\n    void fetch_block_header(const hash_digest &hash,\n                            block_header_fetch_handler handler);\n\n    /// fetch a merkle block by height.\n    void fetch_merkle_block(uint64_t height,\n                            merkle_block_fetch_handler handler);\n\n    /// fetch a merkle block by height.\n    void fetch_merkle_block(const hash_digest &hash,\n                            merkle_block_fetch_handler handler);\n\n    /// fetch hashes of transactions for a block, by block height.\n    void fetch_block_transaction_hashes(uint64_t height,\n                                        transaction_hashes_fetch_handler handler);\n\n    /// fetch hashes of transactions for a block, by block hash.\n    void fetch_block_transaction_hashes(const hash_digest &hash,\n                                        transaction_hashes_fetch_handler handler);\n\n    /// fetch a block locator relative to the current top and threshold.\n    void fetch_block_locator(block_locator_fetch_handler handler);\n\n    /// fetch the set of block hashes indicated by the block locator.\n    void fetch_locator_block_hashes(const message::get_blocks &locator,\n                                    const hash_digest &threshold, size_t limit,\n                                    locator_block_hashes_fetch_handler handler);\n\n    /// fetch the set of block headers indicated by the block locator.\n    void fetch_locator_block_headers(const message::get_headers &locator,\n                                     const hash_digest &threshold, size_t limit,\n                                     locator_block_headers_fetch_handler handler);\n\n    /// fetch height of block by hash.\n    void fetch_block_height(const hash_digest &hash,\n                            block_height_fetch_handler handler);\n\n    /// fetch height of latest block.\n    void fetch_last_height(last_height_fetch_handler handler);\n\n    /// fetch transaction by hash.\n    void fetch_transaction(const hash_digest &hash,\n                           transaction_fetch_handler handler);\n\n    /// fetch height and offset within block of transaction by hash.\n    void fetch_transaction_index(const hash_digest &hash,\n                                 transaction_index_fetch_handler handler);\n\n    /// fetch spend of an output point.\n    void fetch_spend(const chain::output_point &outpoint,\n                     spend_fetch_handler handler);\n\n    /// fetch outputs, values and spends for an address.\n    void fetch_history(const bc::wallet::payment_address &address,\n                       uint64_t limit, uint64_t from_height, history_fetch_handler handler);\n\n    bool fetch_history(const bc::wallet::payment_address &address,\n                       uint64_t limit, uint64_t from_height, history_compact::list &history);\n\n    history::list get_address_history(const bc::wallet::payment_address &addr, bool add_memory_pool = false, uint64_t from_height = 0);\n\n    /// fetch stealth results.\n    void fetch_stealth(const binary &filter, uint64_t from_height,\n                       stealth_fetch_handler handler);\n\n    /// filter out block hashes that exist in the store.\n    virtual void filter_blocks(message::get_data::ptr message,\n                               result_handler handler);\n\n    /// filter out block hashes that exist in the orphan pool.\n    virtual void filter_orphans(message::get_data::ptr message,\n                                result_handler handler);\n\n    /// filter out transaction hashes that exist in the store.\n    virtual void filter_transactions(message::get_data::ptr message,\n                                     result_handler handler);\n\n    /// Subscribe to blockchain reorganizations.\n    virtual void subscribe_reorganize(reorganize_handler handler);\n\n    inline hash_digest get_hash(const std::string &str);\n    inline short_hash get_short_hash(const std::string &str);\n\n    std::shared_ptr<chain::transaction> get_spends_output(const input_point &input);\n\n    // wallet related api\n    std::shared_ptr<libbitcoin::chain::wallet> is_wallet_passwd_valid(const std::string &name, const std::string &passwd);\n    std::string is_wallet_lastwd_valid(const libbitcoin::chain::wallet &acc, std::string &auth, const std::string &lastwd);\n    void set_wallet_passwd(const std::string &name, const std::string &passwd);\n    bool is_wallet_exist(const std::string &name);\n    bool is_admin_wallet(const std::string &name);\n    operation_result store_wallet(std::shared_ptr<libbitcoin::chain::wallet> acc);\n    std::shared_ptr<libbitcoin::chain::wallet> get_wallet(const std::string &name);\n    std::shared_ptr<std::vector<libbitcoin::chain::wallet>> get_wallets();\n    operation_result delete_wallet(const std::string &name);\n    operation_result delete_wallet_address(const std::string &name);\n\n    operation_result delete_n_wallet_address(const std::string &name, uint64_t count);\n\n    std::shared_ptr<business_history::list> get_address_business_history(\n        const std::string &addr, business_kind kind, uint8_t confirmed);\n    std::shared_ptr<business_history::list> get_address_business_history(\n        const std::string &addr, business_kind kind, uint32_t time_begin, uint32_t time_end);\n    std::shared_ptr<business_history::list> get_address_business_history(const std::string &addr);\n\n    // wallet token api\n    operation_result store_wallet_token(const token_detail &detail, const std::string &name);\n    operation_result store_wallet_token(std::shared_ptr<token_detail> detail, const std::string &name);\n    operation_result delete_wallet_token(const std::string &name);\n    std::shared_ptr<business_address_token::list> get_wallet_token(\n        const std::string &name, const std::string &token_name, business_kind kind);\n    std::shared_ptr<business_address_token::list> get_wallet_token(\n        const std::string &name, const std::string &token);\n    std::shared_ptr<business_address_token::list> get_wallet_tokens(const std::string &name);\n    std::shared_ptr<business_address_token::list> get_wallet_tokens(\n        const std::string &name, business_kind kind);\n    uint64_t get_address_token_volume(const std::string &address, const std::string &token);\n    uint64_t get_wallet_token_volume(const std::string &wallet, const std::string &token);\n    uint64_t get_token_volume(const std::string &token);\n\n    // token api\n    bool is_token_exist(const std::string &token_name, bool check_local_db = true);\n    uint64_t get_token_height(const std::string &token_name) const;\n    std::shared_ptr<token_detail::list> get_local_tokens();\n    std::shared_ptr<token_detail::list> get_issued_tokens(const std::string &symbol = \"\");\n    std::shared_ptr<token_detail> get_issued_token(const std::string &symbol);\n    std::shared_ptr<business_address_token::list> get_wallet_tokens();\n    std::shared_ptr<business_address_token::list> get_wallet_unissued_tokens(const std::string &name);\n    std::shared_ptr<token_detail> get_wallet_unissued_token(\n        const std::string &name, const std::string &symbol);\n\n    std::shared_ptr<blockchain_token::list> get_token_register_output(const std::string &symbol);\n    // cert api\n    bool is_token_cert_exist(const std::string &symbol, token_cert_type cert_type);\n    uint64_t get_token_cert_height(const std::string &cert_symbol, const token_cert_type &cert_type);\n    std::shared_ptr<token_cert::list> get_issued_token_certs();\n    std::shared_ptr<token_cert> get_wallet_token_cert(\n        const std::string &wallet, const std::string &symbol, token_cert_type cert_type);\n    std::shared_ptr<business_address_token_cert::list> get_wallet_token_certs(\n        const std::string &wallet, const std::string &symbol, token_cert_type cert_type);\n    std::shared_ptr<business_address_token_cert::list> get_address_token_certs(\n        const std::string &address, const std::string &symbol, token_cert_type cert_type);\n\n    // identifiable token\n    bool is_candidate_exist(const std::string &symbol);\n    uint64_t get_candidate_height(const std::string &candidate_symbol) const;\n    std::shared_ptr<candidate_info> get_registered_candidate(const std::string &symbol);\n    std::shared_ptr<candidate_info::list> get_registered_candidates();\n    std::shared_ptr<candidate_info::list> get_candidate_history(const std::string &symbol,\n                                                                uint64_t limit = 0, uint64_t page_number = 0);\n    std::shared_ptr<candidate::list> get_wallet_candidates(\n        const std::string &wallet, const std::string &symbol = \"\");\n    bool exist_in_candidates(std::string uid);\n\n    // wallet uid api\n    bool is_uid_exist(const std::string &symbol);\n    uint64_t get_uid_height(const std::string &symbol) const;\n    bool is_address_registered_uid(const std::string &address, uint64_t fork_index = max_uint64);\n    bool is_wallet_owned_uid(const std::string &wallet, const std::string &symbol);\n    std::string get_uid_from_address(const std::string &address, uint64_t fork_index = max_uint64);\n    std::shared_ptr<uid_detail> get_registered_uid(const std::string &symbol);\n    std::shared_ptr<uid_detail::list> get_registered_uids();\n    std::shared_ptr<uid_detail::list> get_wallet_uids(const std::string &wallet);\n\n    //get history addresses from uid symbol\n    std::shared_ptr<blockchain_uid::list> get_uid_history_addresses(const std::string &symbol);\n\n    std::shared_ptr<business_history::list> get_wallet_business_history(\n        const std::string &name, business_kind kind, uint32_t time_begin, uint32_t time_end);\n    std::shared_ptr<business_history::list> get_address_business_history(\n        const std::string &addr, const std::string &symbol, business_kind kind, uint8_t confirmed);\n    std::shared_ptr<business_record::list> get_address_business_record(\n        const std::string &addr, size_t from_height = 0, size_t limit = 0);\n    std::shared_ptr<business_record::list> get_address_business_record(\n        const std::string &addr, uint64_t start, uint64_t end, const std::string &symbol);\n    std::shared_ptr<business_record::list> get_address_business_record(\n        const std::string &address, const std::string &symbol, size_t start_height, size_t end_height,\n        uint64_t limit, uint64_t page_number) const;\n    std::shared_ptr<wallet_address::list> get_addresses();\n\n    // wallet message api\n    std::shared_ptr<business_address_message::list> get_wallet_messages(const std::string &name);\n\n    // wallet adress related api\n    operation_result store_wallet_address(std::shared_ptr<wallet_address> address);\n    std::shared_ptr<wallet_address> get_wallet_address(const std::string &name, const std::string &address);\n    std::shared_ptr<wallet_address::list> get_wallet_addresses(const std::string &name);\n    void uppercase_symbol(std::string &symbol);\n\n    static bool is_valid_address(const std::string &address);\n    static bool is_payment_address(const std::string &address);\n    static bool is_stealth_address(const std::string &address);\n    static bool is_script_address(const std::string &address);\n    static bool is_blackhole_address(const std::string &address);\n\n    void fired();\n    organizer &get_organizer();\n    bool get_transaction(const hash_digest &hash,\n                         chain::transaction &tx, uint64_t &tx_height);\n    bool get_transaction_callback(const hash_digest &hash,\n                                  std::function<void(const code &, const chain::transaction &)> handler);\n    bool get_history_callback(const payment_address &address,\n                              size_t limit, size_t from_height,\n                              std::function<void(const code &, chain::history::list &)> handler);\n    bool get_history(const bc::wallet::payment_address &address,\n                     uint64_t limit, uint64_t from_height, history_compact::list &history);\n    code validate_tx_engine(const chain::transaction &tx);\n    code broadcast_transaction(const chain::transaction &tx);\n    bool get_tx_inputs_ucn_value(chain::transaction &tx, uint64_t &ucn_val);\n    void safe_store_wallet(libbitcoin::chain::wallet &acc, const std::vector<std::shared_ptr<wallet_address>> &addresses);\n\n  private:\n    typedef std::function<bool(database::handle)> perform_read_functor;\n\n    template <typename Handler, typename... Args>\n    bool finish_fetch(database::handle handle, Handler handler, Args &&... args)\n    {\n        if (!database_.is_read_valid(handle))\n            return false;\n\n        handler(std::forward<Args>(args)...);\n        return true;\n    }\n\n    template <typename Handler, typename... Args>\n    void stop_write(Handler handler, Args &&... args)\n    {\n        const auto result = database_.end_write();\n        BITCOIN_ASSERT(result);\n        handler(std::forward<Args>(args)...);\n    }\n\n    void stop_write();\n    void start_write();\n    void do_store(message::block_msg::ptr block,\n                  block_store_handler handler);\n\n    ////void fetch_ordered(perform_read_functor perform_read);\n    ////void fetch_parallel(perform_read_functor perform_read);\n    void fetch_serial(perform_read_functor perform_read);\n    bool stopped() const;\n\n    std::string get_token_symbol_from_asset_data(const asset_data &data);\n\n  private:\n    std::atomic<bool> stopped_;\n    const settings &settings_;\n\n    // These are thread safe.\n    organizer organizer_;\n    ////dispatcher read_dispatch_;\n    ////dispatcher write_dispatch_;\n    blockchain::tx_pool tx_pool_;\n\n    // This is protected by mutex.\n    database::data_base database_;\n    mutable shared_mutex mutex_;\n};\n\n} // namespace blockchain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/blockchain/block_fetcher.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_BLOCKCHAIN_BLOCK_FETCHER_HPP\n#define UC_BLOCKCHAIN_BLOCK_FETCHER_HPP\n\n#include <cstdint>\n#include <memory>\n#include <system_error>\n#include <UChain/coin.hpp>\n#include <UChain/blockchain/define.hpp>\n#include <UChain/blockchain/block_chain.hpp>\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\n\n/**\n * Fetch a block by height.\n *\n * If the blockchain reorganises this call may fail.\n *\n * @param[in]   chain           Blockchain service\n * @param[in]   height          Height of block to fetch.\n * @param[in]   handle_fetch    Completion handler for fetch operation.\n */\nBCB_API void fetch_block(block_chain &chain, uint64_t height,\n                         block_chain::block_fetch_handler handle_fetch);\n\nBCB_API void fetch_latest_transactions(block_chain &chain, uint64_t height,\n                                       uint32_t index, uint32_t count, block_chain::transactions_fetch_handler handle_fetch);\n/**\n * Fetch a block by hash.\n *\n * If the blockchain reorganises this call may fail.\n *\n * @param[in]   chain           Blockchain service\n * @param[in]   hash            Block hash\n * @param[in]   handle_fetch    Completion handler for fetch operation.\n */\nBCB_API void fetch_block(block_chain &chain, const hash_digest &hash,\n                         block_chain::block_fetch_handler handle_fetch);\n\n} // namespace blockchain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/blockchain/block_info.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_BLOCKCHAIN_BLOCK_DETAIL_HPP\n#define UC_BLOCKCHAIN_BLOCK_DETAIL_HPP\n\n#include <atomic>\n#include <memory>\n#include <vector>\n#include <UChain/coin.hpp>\n#include <UChain/blockchain/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\n\n/// A block with metadata.\n/// This class is thread safe though property consistency is not guaranteed.\nclass BCB_API block_info\n{\n  public:\n    typedef std::shared_ptr<block_info> ptr;\n    typedef std::vector<block_info::ptr> list;\n    typedef message::block_msg::ptr block_ptr;\n\n    /// Construct a block detail instance.\n    block_info(block_ptr actual_block);\n    block_info(chain::block &&actual_block);\n\n    block_ptr actual() const;\n\n    /// Set a flag indicating validation has been completed.\n    void set_processed();\n    bool processed() const;\n\n    /// Set the accepted block height (non-zero).\n    void set_height(uint64_t height);\n    uint64_t height() const;\n\n    /// Set the validation failure code.\n    void set_error(const code &code);\n    code error() const;\n\n    /// This method is thread safe.\n    //- remove & from hash_digest\n    const hash_digest hash() const;\n\n    // Set if work proof is checked.\n    void set_is_checked_work_proof(bool is_checked);\n    bool get_is_checked_work_proof() const;\n\n  private:\n    bc::atomic<code> code_;\n    std::atomic<bool> processed_;\n    std::atomic<uint64_t> height_;\n    const block_ptr actual_block_;\n    std::atomic<bool> is_checked_work_proof_;\n};\n\n} // namespace blockchain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/blockchain/define.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_BLOCKCHAIN_DEFINE_HPP\n#define UC_BLOCKCHAIN_DEFINE_HPP\n\n#include <cstdint>\n#include <vector>\n#include <UChain/coin.hpp>\n\n// Now we use the generic helper definitions in libbitcoin to\n// define BCB_API and BCB_INTERNAL.\n// BCB_API is used for the public API symbols. It either DLL imports or\n// DLL exports (or does nothing for static build)\n// BCB_INTERNAL is used for non-api symbols.\n\n#if defined BCB_STATIC\n#define BCB_API\n#define BCB_INTERNAL\n#elif defined BCB_DLL\n#define BCB_API BC_HELPER_DLL_EXPORT\n#define BCB_INTERNAL BC_HELPER_DLL_LOCAL\n#else\n#define BCB_API BC_HELPER_DLL_IMPORT\n#define BCB_INTERNAL BC_HELPER_DLL_LOCAL\n#endif\n\n// Now we use the generic helper definitions in libbitcoin to\n// define BCD_API and BCD_INTERNAL.\n// BCD_API is used for the public API symbols. It either DLL imports or\n// DLL exports (or does nothing for static build)\n// BCD_INTERNAL is used for non-api symbols.\n\n//#if defined BCB_STATIC\n//    #define BCD_API\n//    #define BCD_INTERNAL\n//#elif defined BCB_DLL\n//    #define BCD_API      BC_HELPER_DLL_EXPORT\n//    #define BCD_INTERNAL BC_HELPER_DLL_LOCAL\n//#else\n//    #define BCD_API      BC_HELPER_DLL_IMPORT\n//    #define BCD_INTERNAL BC_HELPER_DLL_LOCAL\n//#endif\n\n// Log name.\n#define LOG_BLOCKCHAIN \"blockchain\"\n\ntypedef uint32_t index_type;\ntypedef uint64_t position_type;\n\n#endif\n"
  },
  {
    "path": "include/UChain/blockchain/organizer.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_BLOCKCHAIN_ORGANIZER_HPP\n#define UC_BLOCKCHAIN_ORGANIZER_HPP\n\n#include <unordered_map>\n#include <atomic>\n#include <cstdint>\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/blockchain/define.hpp>\n#include <UChain/blockchain/block_info.hpp>\n#include <UChain/blockchain/orphan_pool.hpp>\n#include <UChain/blockchain/settings.hpp>\n#include <UChain/blockchain/simple_chain.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <boost/thread.hpp>\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\n\n// TODO: This is not an interface, collapse with organizer_impl.\n\n/// This class is thread safe, with the exception of organize().\n/// Structure which organises the blocks from the orphan pool to the blockchain.\nclass BCB_API organizer\n{\n  public:\n    typedef handle0 result_handler;\n    typedef std::shared_ptr<organizer> ptr;\n    typedef message::block_msg::ptr_list list;\n    typedef resubscriber<const code &, uint64_t, const list &, const list &>\n        reorganize_subscriber;\n    typedef std::function<bool(const code &, uint64_t, const list &, const list &)>\n        reorganize_handler;\n\n    /// Construct an instance.\n    organizer(threadpool &pool, simple_chain &chain, const settings &settings);\n\n    /// This method is NOT thread safe.\n    virtual void organize();\n\n    virtual void start();\n    virtual void stop();\n    virtual bool add(block_info::ptr block);\n    virtual void subscribe_reorganize(reorganize_handler handler);\n    virtual void filter_orphans(message::get_data::ptr message);\n\n    void fired();\n    std::unordered_map<hash_digest, uint64_t> get_fork_chain_last_block_hashes();\n    void add_fork_chain_hash(const hash_digest &);\n    void delete_fork_chain_hash(const hash_digest &);\n\n  protected:\n    virtual bool stopped();\n\n  private:\n    typedef block_info::list detail_list;\n\n    static uint64_t count_inputs(const chain::block &block);\n\n    bool strict(uint64_t fork_point) const;\n\n    /// These methods are NOT thread safe.\n    virtual code verify(uint64_t fork_index,\n                        const block_info::list &orphan_chain, uint64_t orphan_index);\n    void process(block_info::ptr process_block);\n    void replace_chain(uint64_t fork_index, detail_list &orphan_chain);\n    void remove_processed(block_info::ptr remove_block);\n    void clip_orphans(detail_list &orphan_chain, uint64_t orphan_index,\n                      const code &invalid_reason);\n\n    /// This method is thread safe.\n    void notify_reorganize(uint64_t fork_point,\n                           const detail_list &orphan_chain, const detail_list &replaced_chain);\n\n    std::atomic<bool> stopped_;\n    const bool use_testnet_rules_;\n    const config::checkpoint::list checkpoints_;\n\n    // These are protected by the caller protecting organize().\n    simple_chain &chain_;\n    block_info::list process_queue_;\n\n    // These are thread safe.\n    orphan_pool orphan_pool_;\n    reorganize_subscriber::ptr subscriber_;\n    std::unordered_map<hash_digest, uint64_t> fork_chain_last_block_hashes_;\n    boost::mutex mutex_fork_chain_last_block_hashes_;\n};\n\n} // namespace blockchain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/blockchain/orphan_pool.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_BLOCKCHAIN_orphan_pool_HPP\n#define UC_BLOCKCHAIN_orphan_pool_HPP\n\n#include <cstddef>\n#include <memory>\n#include <boost/circular_buffer.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/blockchain/define.hpp>\n#include <UChain/blockchain/block_info.hpp>\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\n\n/// This class is thread safe.\n/// An unordered memory pool for orphan blocks.\nclass BCB_API orphan_pool\n{\n  public:\n    typedef std::shared_ptr<orphan_pool> ptr;\n\n    orphan_pool(size_t capacity);\n\n    /// Add a block to the pool.\n    bool add(block_info::ptr block);\n\n    /// Remove a block from the pool.\n    void remove(block_info::ptr block);\n\n    /// Remove from the message all vectors that match orphans.\n    void filter(message::get_data::ptr message) const;\n\n    /// Get the longest connected chain of orphans after 'end'.\n    block_info::list trace(block_info::ptr end) const;\n\n    /// Get the set of unprocessed orphans.\n    block_info::list unprocessed() const;\n\n    bool add_pending_block(const hash_digest &needed_block, const block_info::ptr &pending_block);\n    block_info::ptr delete_pending_block(const hash_digest &needed_block);\n\n  private:\n    //    typedef boost::circular_buffer<block_info::ptr> buffer;\n    typedef std::vector<block_info::ptr> buffer;\n    typedef buffer::const_iterator const_iterator;\n    typedef buffer::const_reverse_iterator const_reverse_iterator;\n\n    bool exists(const hash_digest &hash) const;\n    bool exists(const chain::header &header) const;\n    const_iterator find(buffer::const_iterator begin, const hash_digest &hash) const;\n    const_reverse_iterator rfind(buffer::const_reverse_iterator begin, const hash_digest &hash) const;\n\n    // The buffer is protected by mutex.\n    buffer buffer_;\n    mutable upgrade_mutex mutex_;\n\n    std::multimap<hash_digest, block_info::ptr> pending_blocks_;\n    std::set<hash_digest> pending_blocks_hash_;\n};\n\n} // namespace blockchain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/blockchain/settings.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-blockchain.\n *\n * UChain-blockchain is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_BLOCKCHAIN_SETTINGS_HPP\n#define UC_BLOCKCHAIN_SETTINGS_HPP\n\n#include <cstdint>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/blockchain/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\n\n/// Common database configuration settings, properties not thread safe.\nclass BCB_API settings\n{\n  public:\n    settings();\n    settings(bc::settings context);\n\n    /// Properties.\n    uint32_t block_pool_capacity;\n    uint32_t tx_pool_capacity;\n    bool tx_pool_consistency;\n    bool use_testnet_rules;\n    config::checkpoint::list checkpoints;\n};\n\n} // namespace blockchain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/blockchain/simple_chain.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_BLOCKCHAIN_SIMPLE_CHAIN_HPP\n#define UC_BLOCKCHAIN_SIMPLE_CHAIN_HPP\n\n#include <cstddef>\n#include <UChain/coin.hpp>\n#include <UChain/blockchain/define.hpp>\n#include <UChain/blockchain/block_info.hpp>\n\nnamespace libbitcoin {\nnamespace blockchain {\n\n/// A low level interface for encapsulation of the blockchain database.\n/// Caller must ensure the database is not otherwise in use during these calls.\n/// Implementations are NOT expected to be thread safe with the exception\n/// that the import method may itself be called concurrently.\nclass BCB_API simple_chain\n{\npublic:\n    /// Return the first and last gaps in the blockchain, or false if none.\n    virtual bool get_gap_range(uint64_t& out_first,\n        uint64_t& out_last) const = 0;\n\n    /// Return the next chain gap at or after the specified start height.\n    virtual bool get_next_gap(uint64_t& out_height,\n        uint64_t start_height) const = 0;\n\n    /// Get the dificulty of a block at the given height.\n    virtual bool get_difficulty(u256& out_difficulty,\n        uint64_t height) const = 0;\n\n    /// Get the header of the block at the given height.\n    virtual bool get_header(chain::header& out_header,\n        uint64_t height) const = 0;\n\n    /// Get the height of the block with the given hash.\n    virtual bool get_height(uint64_t& out_height,\n        const hash_digest& block_hash) const = 0;\n\n    /// Get height of latest block.\n    virtual bool get_last_height(uint64_t& out_height) const = 0;\n\n    /// Get the hash digest of the transaction of the outpoint.\n    virtual bool get_outpoint_transaction(hash_digest& out_transaction,\n        const chain::output_point& outpoint) const = 0;\n\n    /// Get the transaction of the given hash and its block height.\n    virtual bool get_transaction(chain::transaction& out_transaction,\n        uint64_t& out_block_height,\n        const hash_digest& transaction_hash) const = 0;\n\n    /// Import a block for the given height.\n    virtual bool import(chain::block::ptr block, uint64_t height) = 0;\n\n    /// Append the block to the top of the chain.\n    virtual bool push(block_info::ptr block) = 0;\n\n    /// Remove blocks at or above the given height, returning them in order.\n    virtual bool pop_from(block_info::list& out_blocks,\n        uint64_t height) = 0;\n};\n\n} // namespace blockchain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/blockchain/tx_pool.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_BLOCKCHAIN_TRANSACTION_POOL_HPP\n#define UC_BLOCKCHAIN_TRANSACTION_POOL_HPP\n\n#include <atomic>\n#include <cstddef>\n#include <functional>\n#include <boost/circular_buffer.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/blockchain/define.hpp>\n#include <UChain/blockchain/block_chain.hpp>\n#include <UChain/blockchain/settings.hpp>\n#include <UChain/blockchain/tx_pool_index.hpp>\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\n\n/// This class is thread safe.\nclass BCB_API tx_pool\n{\n  public:\n    typedef chain::point::indexes indexes;\n    typedef message::get_data::ptr get_data_ptr;\n    typedef message::tx_message::ptr transaction_ptr;\n\n    typedef handle0 result_handler;\n    typedef handle1<transaction_ptr> fetch_handler;\n    typedef handle1<std::vector<transaction_ptr>> fetch_all_handler;\n    typedef handle1<transaction_ptr> confirm_handler;\n    typedef handle2<transaction_ptr, indexes> validate_handler;\n    typedef std::function<bool(const code &, const indexes &, transaction_ptr)>\n        transaction_handler;\n    typedef resubscriber<const code &, const indexes &, transaction_ptr>\n        transaction_subscriber;\n\n    static bool is_spent_by_tx(const chain::output_point &outpoint,\n                               const transaction_ptr tx);\n\n    /// Construct a transaction memory pool.\n    tx_pool(threadpool &pool, block_chain &chain,\n                     const settings &settings);\n\n    /// Clear the pool, threads must be joined.\n    ~tx_pool();\n\n    /// This class is not copyable.\n    tx_pool(const tx_pool &) = delete;\n    void operator=(const tx_pool &) = delete;\n\n    /// Start the transaction pool.\n    void start();\n\n    /// Signal stop of current work, speeds shutdown.\n    void stop();\n\n    void fired();\n\n    void inventory(message::inventory::ptr inventory);\n    void fetch(const hash_digest &tx_hash, fetch_handler handler);\n    void fetch(fetch_all_handler handler);\n    void delete_tx(const hash_digest &tx_hash);\n    void fetch_history(const bc::wallet::payment_address &address, size_t limit,\n                       size_t from_height, block_chain::history_fetch_handler handler);\n    void exists(const hash_digest &tx_hash, result_handler handler);\n    void filter(get_data_ptr message, result_handler handler);\n    void validate(transaction_ptr tx, validate_handler handler);\n    void store(transaction_ptr tx, confirm_handler confirm_handler,\n               validate_handler validate_handler);\n\n    /// Subscribe to transaction acceptance into the mempool.\n    void subscribe_transaction(transaction_handler handler);\n\n  protected:\n    /// This is analogous to the orphan pool's block_info.\n    struct entry\n    {\n        transaction_ptr tx;\n        confirm_handler handle_confirm;\n    };\n\n    typedef boost::circular_buffer<entry> buffer;\n    typedef buffer::const_iterator const_iterator;\n\n    typedef std::function<bool(const chain::input &)> input_compare;\n    typedef message::block_msg::ptr_list block_list;\n\n    bool stopped();\n    const_iterator find(const hash_digest &tx_hash) const;\n\n    bool handle_reorganized(const code &ec, size_t fork_point,\n                            const block_list &new_blocks, const block_list &replaced_blocks);\n    void handle_validated(const code &ec, transaction_ptr tx,\n                          const indexes &unconfirmed, validate_handler handler);\n\n    void do_validate(transaction_ptr tx, validate_handler handler);\n    void do_store(const code &ec, transaction_ptr tx,\n                  const indexes &unconfirmed, confirm_handler handle_confirm,\n                  validate_handler handle_validate);\n\n    void notify_transaction(const chain::point::indexes &unconfirmed,\n                            transaction_ptr tx);\n\n    void add(transaction_ptr tx, confirm_handler handler);\n    void remove(const block_list &blocks);\n    void clear(const code &ec);\n\n    code check_symbol_repeat(transaction_ptr tx);\n\n    // These would be private but for test access.\n    void delete_spent_in_blocks(const block_list &blocks);\n    void delete_confirmed_in_blocks(const block_list &blocks);\n    void delete_dependencies(const hash_digest &tx_hash, const code &ec);\n    void delete_dependencies(const chain::output_point &point, const code &ec);\n    void delete_dependencies(input_compare is_dependency, const code &ec);\n    void delete_package(const code &ec);\n    void delete_package(transaction_ptr tx, const code &ec);\n    bool delete_single(const hash_digest &tx_hash, const code &ec);\n\n    // The buffer is protected by non-concurrent dispatch.\n    buffer buffer_;\n    std::atomic<bool> stopped_;\n\n  private:\n    // Unsafe methods limited to friend caller.\n    friend class validate_tx_engine;\n\n    // These methods are NOT thread safe.\n    bool is_in_pool(const hash_digest &tx_hash) const;\n    bool is_spent_in_pool(transaction_ptr tx) const;\n    bool is_spent_in_pool(const chain::transaction &tx) const;\n    bool is_spent_in_pool(const chain::output_point &outpoint) const;\n    bool find(transaction_ptr &out_tx, const hash_digest &tx_hash) const;\n    bool find(chain::transaction &out_tx, const hash_digest &tx_hash) const;\n\n    // These are thread safe.\n    dispatcher dispatch_;\n    block_chain &blockchain_;\n    tx_pool_index index_;\n    transaction_subscriber::ptr subscriber_;\n    const bool maintain_consistency_;\n};\n\n} // namespace blockchain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/blockchain/tx_pool_index.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-node.\n *\n * UChain-node is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_BLOCKCHAIN_TRANSACTION_POOL_INDEX_HPP\n#define UC_BLOCKCHAIN_TRANSACTION_POOL_INDEX_HPP\n\n#include <atomic>\n#include <cstddef>\n#include <cstdint>\n#include <unordered_map>\n#include <UChain/coin.hpp>\n#include <UChain/blockchain/define.hpp>\n#include <UChain/blockchain/block_chain.hpp>\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\n\n/// This class is thread safe.\nclass BCB_API tx_pool_index\n{\n  public:\n    typedef handle0 completion_handler;\n    typedef handle2<chain::spend_info::list, chain::output_info::list>\n        query_handler;\n    typedef block_chain::history_fetch_handler fetch_handler;\n\n    tx_pool_index(threadpool &pool, block_chain &blockchain);\n\n    /// This class is not copyable.\n    tx_pool_index(const tx_pool_index &) = delete;\n    void operator=(const tx_pool_index &) = delete;\n\n    /// Start the transaction pool.\n    void start();\n\n    /// Signal stop of current work, speeds shutdown.\n    void stop();\n\n    void fetch_all_history(const bc::wallet::payment_address &address,\n                           size_t limit, size_t from_height, fetch_handler handler);\n\n    void fetch_index_history(const bc::wallet::payment_address &address,\n                             query_handler handler);\n\n    void add(const chain::transaction &tx, completion_handler handler);\n    void remove(const chain::transaction &tx, completion_handler handler);\n\n  private:\n    typedef chain::spend_info spend_info;\n    typedef chain::output_info output_info;\n    typedef chain::history_compact::list history_list;\n    typedef bc::wallet::payment_address payment_address;\n    typedef std::unordered_multimap<payment_address, spend_info> spends_map;\n    typedef std::unordered_multimap<payment_address, output_info> outputs_map;\n\n    static bool exists(history_list &history, const spend_info &spend);\n    static bool exists(history_list &history, const output_info &output);\n    static void add(history_list &history, const spend_info &spend);\n    static void add(history_list &history, const output_info &output);\n    static void add(history_list &history, const spend_info::list &spends);\n    static void add(history_list &history, const output_info::list &outputs);\n    static void index_history_fetched(const code &ec,\n                                      const spend_info::list &spends, const output_info::list &outputs,\n                                      const history_list &history, fetch_handler handler);\n\n    void blockchain_history_fetched(const code &ec,\n                                    const history_list &history, const bc::wallet::payment_address &address,\n                                    fetch_handler handler);\n\n    void do_add(const chain::transaction &tx, completion_handler handler);\n    void do_remove(const chain::transaction &tx, completion_handler handler);\n    void do_fetch(const bc::wallet::payment_address &payaddr,\n                  query_handler handler);\n\n    // This is protected by mutex.\n    spends_map spends_map_;\n    upgrade_mutex spends_mutex_;\n\n    // This is protected by mutex.\n    outputs_map outputs_map_;\n    upgrade_mutex outputs_mutex_;\n\n    // These are thread safe.\n    dispatcher dispatch_;\n    block_chain &blockchain_;\n    std::atomic<bool> stopped_;\n};\n\n} // namespace blockchain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/blockchain/validate_block.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_BLOCKCHAIN_VALIDATE_HPP\n#define UC_BLOCKCHAIN_VALIDATE_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <system_error>\n#include <vector>\n#include <UChain/coin.hpp>\n#include <UChain/blockchain/define.hpp>\n#include <UChain/blockchain/block_chain_impl.hpp>\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\n\n// Max block size (1000000 bytes).\nconstexpr uint32_t max_block_size = 1000000;\n\n// Maximum signature operations per block (20000).\nconstexpr uint32_t max_block_script_sigops = max_block_size / 50;\n\n// TODO: this is not an interface, collapse with validate_block_impl.\n/// This class is not thread safe.\nclass BCB_API validate_block\n{\n  public:\n    code check_block(blockchain::block_chain_impl &chain) const;\n    code accept_block() const;\n    code connect_block(hash_digest &err_tx, blockchain::block_chain_impl &chain) const;\n\n    /// Required to call before calling accept_block or connect_block.\n    void initialize_context();\n    static size_t legacy_sigops_count(const chain::transaction &tx);\n    static bool script_hash_signature_operations_count(size_t &out_count, const chain::script &output_script, const chain::script &input_script);\n\n    bool get_transaction(const hash_digest &tx_hash, chain::transaction &prev_tx, size_t &prev_height) const;\n\n    virtual std::string get_uid_from_address_consider_orphan_chain(const std::string &address, const std::string &uid_symbol) const = 0;\n    virtual bool is_uid_match_address_in_orphan_chain(const std::string &symbol, const std::string &address) const = 0;\n    virtual bool is_uid_in_orphan_chain(const std::string &symbol) const = 0;\n    virtual bool is_token_in_orphan_chain(const std::string &symbol) const = 0;\n    virtual bool is_token_cert_in_orphan_chain(const std::string &symbol, token_cert_type cert_type) const = 0;\n    virtual bool is_candidate_in_orphan_chain(const std::string &symbol) const = 0;\n\n    virtual size_t get_fork_index() const { return max_size_t; }\n\n  protected:\n    typedef std::vector<uint8_t> versions;\n    typedef std::function<bool()> stopped_callback;\n\n    validate_block(size_t height, const chain::block &block,\n                   bool testnet, const config::checkpoint::list &checks,\n                   stopped_callback stop_callback);\n\n    virtual bool check_get_coinage_reward_transaction(const chain::transaction &coinage_reward_coinbase, const chain::output &tx, bool is_candidate) const = 0;\n    virtual uint64_t median_time_past() const = 0;\n    //virtual u256 previous_block_bits() const = 0;\n    virtual uint64_t actual_time_span(size_t interval) const = 0;\n    virtual versions preceding_block_versions(size_t count) const = 0;\n    virtual chain::header fetch_block(size_t fetch_height) const = 0;\n    virtual bool transaction_exists(const hash_digest &tx_hash) const = 0;\n    virtual bool fetch_transaction(chain::transaction &tx, size_t &tx_height,\n                                   const hash_digest &tx_hash) const = 0;\n    virtual bool is_output_spent(const chain::output_point &outpoint) const = 0;\n    virtual bool is_output_spent(const chain::output_point &previous_output,\n                                 size_t index_in_parent, size_t input_index) const = 0;\n\n    // These have default implementations that can be overriden.\n    virtual bool connect_input(size_t index_in_parent,\n                               const chain::transaction &current_tx, size_t input_index,\n                               uint64_t &value_in, size_t &total_sigops) const;\n    virtual bool validate_inputs(const chain::transaction &tx,\n                                 size_t index_in_parent, uint64_t &value_in,\n                                 size_t &total_sigops) const;\n\n    // These are protected virtual for testability.\n    bool stopped() const;\n    virtual bool is_valid_version() const;\n    virtual bool is_active(chain::script_context flag) const;\n    bool is_spent_duplicate(const chain::transaction &tx) const;\n    bool is_valid_time_stamp(uint32_t timestamp) const;\n    bool check_time_stamp(uint32_t timestamp, const asio::seconds &window) const;\n    //u256 work_required(bool is_testnet) const;\n\n    static bool is_distinct_tx_set(const chain::transaction::list &txs);\n    //virtual bool is_valid_proof_of_work(const chain::header& header)const = 0;\n    static bool is_valid_coinbase_height(size_t height,\n                                         const chain::block &block);\n    //static size_t legacy_sigops_count(const chain::transaction& tx);\n    static size_t legacy_sigops_count(const chain::transaction::list &txs);\n\n  private:\n    bool testnet_;\n    const size_t height_;\n    uint32_t activations_;\n    uint32_t minimum_version_;\n    const chain::block &current_block_;\n    const config::checkpoint::list &checkpoints_;\n    const stopped_callback stop_callback_;\n};\n\n} // namespace blockchain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/blockchain/validate_block_impl.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_BLOCKCHAIN_IMPL_VALIDATE_BLOCK_H\n#define UC_BLOCKCHAIN_IMPL_VALIDATE_BLOCK_H\n\n#include <cstddef>\n#include <cstdint>\n#include <vector>\n#include <UChain/coin.hpp>\n#include <UChain/blockchain/simple_chain.hpp>\n#include <UChain/blockchain/validate_block.hpp>\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\n\n/// This class is not thread safe.\nclass BCB_API validate_block_impl\n    : public validate_block\n{\n  public:\n    validate_block_impl(simple_chain &chain, size_t fork_index,\n                        const block_info::list &orphan_chain, size_t orphan_index,\n                        size_t height, const chain::block &block, bool testnet,\n                        const config::checkpoint::list &checkpoints,\n                        stopped_callback stopped);\n    //virtual bool is_valid_proof_of_work(const chain::header& header) const;\n    virtual bool check_get_coinage_reward_transaction(const chain::transaction &coinage_reward_coinbase, const chain::output &output, bool is_candidate) const;\n\n    virtual std::string get_uid_from_address_consider_orphan_chain(const std::string &address, const std::string &uid_symbol) const override;\n    virtual bool is_uid_match_address_in_orphan_chain(const std::string &symbol, const std::string &address) const override;\n    virtual bool is_uid_in_orphan_chain(const std::string &symbol) const override;\n    virtual bool is_token_in_orphan_chain(const std::string &symbol) const override;\n    virtual bool is_token_cert_in_orphan_chain(const std::string &symbol, token_cert_type cert_type) const override;\n    virtual bool is_candidate_in_orphan_chain(const std::string &symbol) const override;\n\n    virtual size_t get_fork_index() const override { return fork_index_; }\n\n  protected:\n    uint64_t median_time_past() const;\n    //u256 previous_block_bits() const;\n    uint64_t actual_time_span(size_t interval) const;\n    versions preceding_block_versions(size_t maximum) const;\n    chain::header fetch_block(size_t fetch_height) const;\n    bool fetch_transaction(chain::transaction &tx, size_t &tx_height,\n                           const hash_digest &tx_hash) const;\n    bool is_output_spent(const chain::output_point &outpoint) const;\n    bool is_output_spent(const chain::output_point &previous_output,\n                         size_t index_in_parent, size_t input_index) const;\n    bool transaction_exists(const hash_digest &tx_hash) const;\n\n  private:\n    bool fetch_orphan_transaction(chain::transaction &tx,\n                                  size_t &previous_height, const hash_digest &tx_hash) const;\n    bool orphan_is_spent(const chain::output_point &previous_output,\n                         size_t skip_tx, size_t skip_input) const;\n\n    simple_chain &chain_;\n    size_t height_;\n    size_t fork_index_;\n    size_t orphan_index_;\n    const block_info::list &orphan_chain_;\n};\n\n} // namespace blockchain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/blockchain/validate_tx_engine.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_BLOCKCHAIN_VALIDATE_TRANSACTION_HPP\n#define UC_BLOCKCHAIN_VALIDATE_TRANSACTION_HPP\n\n#include <cstdint>\n#include <cstddef>\n#include <functional>\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/blockchain/define.hpp>\n#include <UChain/blockchain/tx_pool.hpp>\n#include <UChain/blockchain/block_chain_impl.hpp>\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\n\nclass validate_block;\n\n/// This class is not thread safe.\n/// This is a utility for tx_pool::validate and validate_block.\nclass BCB_API validate_tx_engine\n    : public enable_shared_from_base<validate_tx_engine>\n{\n  public:\n    typedef std::shared_ptr<validate_tx_engine> ptr;\n    typedef message::tx_message::ptr transaction_ptr;\n    typedef std::function<void(const code &, transaction_ptr,\n                               chain::point::indexes)>\n        validate_handler;\n\n    validate_tx_engine(block_chain &chain, const chain::transaction &tx,\n                         const tx_pool &pool, dispatcher &dispatch);\n\n    validate_tx_engine(block_chain &chain, const chain::transaction &tx,\n                         const validate_block &validate_block);\n\n    void start(validate_handler handler);\n\n    static bool check_consensus(const chain::script &prevout_script,\n                                const chain::transaction &current_tx, size_t input_index,\n                                uint32_t flags);\n\n    code check_transaction_connect_input(size_t last_height);\n    code check_transaction() const;\n    code check_transaction_basic() const;\n    code check_token_issue_transaction() const;\n    code check_token_cert_transaction() const;\n    code check_secondaryissue_transaction() const;\n    code check_candidate_transaction() const;\n    code check_uid_transaction() const;\n    bool connect_uid_input(const uid &info) const;\n    bool is_uid_match_address_in_orphan_chain(const std::string &symbol, const std::string &address) const;\n    bool is_uid_in_orphan_chain(const std::string &uid) const;\n    code check_asset_to_uid(const output &output) const;\n    code connect_asset_from_uid(const output &output) const;\n\n    bool connect_input(const chain::transaction &previous_tx, size_t parent_height);\n\n    static bool tally_fees(blockchain::block_chain_impl &chain,\n                           const chain::transaction &tx, uint64_t value_in, uint64_t &fees);\n    static bool check_special_fees(bool is_testnet, const chain::transaction &tx, uint64_t fees);\n\n    bool check_token_amount(const transaction &tx) const;\n    bool check_token_symbol(const transaction &tx) const;\n    bool check_token_certs(const transaction &tx) const;\n    bool check_candidate(const transaction &tx) const;\n    bool check_address_registered_uid(const std::string &address) const;\n\n    //check input uid match output uid\n    bool check_uid_symbol_match(const transaction &tx) const;\n\n    static bool is_uid_feature_activated(blockchain::block_chain_impl &chain);\n\n    bool get_previous_tx(chain::transaction &prev_tx, uint64_t &prev_height, const chain::input &) const;\n\n    transaction &get_tx() { return *tx_; }\n    const transaction &get_tx() const { return *tx_; }\n    blockchain::block_chain_impl &get_blockchain() { return blockchain_; }\n    const blockchain::block_chain_impl &get_blockchain() const { return blockchain_; }\n\n  private:\n    code basic_checks() const;\n    bool is_standard() const;\n    void handle_duplicate_check(const code &ec);\n    void reset(size_t last_height);\n\n    // Last height used for checking coinbase maturity.\n    void set_last_height(const code &ec, size_t last_height);\n\n    // Begin looping through the inputs, fetching the previous tx\n    void next_previous_transaction();\n    void previous_tx_index(const code &ec, size_t parent_height);\n\n    // If previous_tx_index uidn't find it then check in pool instead\n    void search_pool_previous_tx();\n    void handle_previous_tx(const code &ec,\n                            const chain::transaction &previous_tx, size_t parent_height);\n\n    // After running connect_input, we check whether this validated previous\n    // output was not already spent by another input in the blockchain.\n    // is_spent() earlier already checked in the pool.\n    void check_double_spend(const code &ec, const chain::input_point &point);\n    void check_fees() const;\n    code check_tx_connect_input() const;\n    code check_tx_connect_output() const;\n    bool check_uid_exist(const std::string &uid) const;\n    bool check_token_exist(const std::string &symbol) const;\n    bool check_token_cert_exist(const std::string &cert, token_cert_type cert_type) const;\n    bool check_candidate_exist(const std::string &candidate) const;\n\n    block_chain_impl &blockchain_;\n    const transaction_ptr tx_;\n    const tx_pool *const pool_;\n    dispatcher *const dispatch_;\n    const validate_block *const validate_block_;\n\n    const hash_digest tx_hash_;\n    size_t last_block_height_;\n    uint64_t value_in_;\n    uint64_t token_amount_in_;\n    std::vector<token_cert_type> token_certs_in_;\n    std::string old_symbol_in_;      // used for check same token/uid/candidate symbol in previous outputs\n    std::string old_cert_symbol_in_; // used for check same cert symbol in previous outputs\n    uint32_t current_input_;\n    chain::point::indexes unconfirmed_;\n    validate_handler handle_validate_;\n};\n\n} // namespace blockchain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/blockchain/version.hpp",
    "content": "///////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 2011-2018 libbitcoin developers\n// Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n//\n//        GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY\n//\n///////////////////////////////////////////////////////////////////////////////\n#ifndef UC_BLOCKCHAIN_VERSION_HPP\n#define UC_BLOCKCHAIN_VERSION_HPP\n\n/**\n * The semantic version of this repository as: [major].[minor].[patch]\n * For interpretation of the versioning scheme see: http://semver.org\n * 0.0.2 for blocktime attack fix\n */\n\n#define UC_BLOCKCHAIN_VERSION \"0.0.6\"\n#define UC_BLOCKCHAIN_MAJOR_VERSION 0\n#define UC_BLOCKCHAIN_MINOR_VERSION 0\n#define UC_BLOCKCHAIN_PATCH_VERSION 6\n\n#endif\n"
  },
  {
    "path": "include/UChain/blockchain/wallet_security_strategy.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UChain_WALLET_SECURITY_STRATEGY_HPP\n#define UChain_WALLET_SECURITY_STRATEGY_HPP\n\n#include <cstdint>\n#include <string>\n\n#include <UChain/coin/utility/thread.hpp>\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\nenum class auth_type : uint8_t\n{\n    AUTH_PASSWD = 0,\n    AUTH_LASTWD = 1,\n\n    AUTH_TYPE_CNT,\n};\n\nstruct WalletInfo\n{\n    uint8_t counter;\n    uint32_t lock_start;\n\n    void lock();\n};\n\nclass wallet_security_strategy\n{\n  public:\n    static wallet_security_strategy *get_instance();\n\n    void check_locked(const std::string &wallet_name);\n    void on_auth_passwd(const std::string &wallet_name, const bool &result);\n    void on_auth_lastwd(const std::string &wallet_name, const bool &result);\n\n  private:\n    wallet_security_strategy(const uint8_t &passwd_max_try, const uint8_t &lastwd_max_try, const uint32_t &max_lock_time);\n    virtual ~wallet_security_strategy();\n\n    wallet_security_strategy(const wallet_security_strategy &) = delete;\n    void operator=(const wallet_security_strategy &) = delete;\n\n    void on_auth(const std::string &wallet_name, const bool &result, const auth_type &type);\n\n    const uint8_t MAX_TRY[static_cast<uint8_t>(auth_type::AUTH_TYPE_CNT)];\n    const uint32_t MAX_LOCK_TIME; //seconds\n\n    std::map<const std::string, WalletInfo> acc_info_[static_cast<uint8_t>(auth_type::AUTH_TYPE_CNT)];\n\n    mutable shared_mutex mutex_;\n\n    static wallet_security_strategy *instance;\n};\n\n} // namespace blockchain\n} // namespace libbitcoin\n#endif //UChain_WALLET_SECURITY_STRATEGY_HPP\n"
  },
  {
    "path": "include/UChain/blockchain.hpp",
    "content": "///////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 2014-2018 libbitcoin-blockchain developers (see COPYING).\n//\n//        GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY\n//\n///////////////////////////////////////////////////////////////////////////////\n#ifndef UC_BLOCKCHAIN_HPP\n#define UC_BLOCKCHAIN_HPP\n\n/**\n * API Users: Include only this header. Direct use of other headers is fragile\n * and unsupported as header organization is subject to change.\n *\n * Maintainers: Do not include this header internal to this library.\n */\n\n#include <UChain/database.hpp>\n\n#ifdef WITH_CONSENSUS\n#include <UChainService/consensus.hpp>\n#endif\n\n#include <UChain/blockchain/block.hpp>\n#include <UChain/blockchain/block_chain.hpp>\n#include <UChain/blockchain/block_chain_impl.hpp>\n#include <UChain/blockchain/block_info.hpp>\n#include <UChain/blockchain/block_fetcher.hpp>\n#include <UChain/blockchain/define.hpp>\n#include <UChain/blockchain/organizer.hpp>\n#include <UChain/blockchain/orphan_pool.hpp>\n#include <UChain/blockchain/settings.hpp>\n#include <UChain/blockchain/simple_chain.hpp>\n#include <UChain/blockchain/tx_pool.hpp>\n#include <UChain/blockchain/tx_pool_index.hpp>\n#include <UChain/blockchain/validate_block.hpp>\n#include <UChain/blockchain/validate_block_impl.hpp>\n#include <UChain/blockchain/validate_tx_engine.hpp>\n#include <UChain/blockchain/version.hpp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/client/dealer.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-client.\n *\n * UChain-client is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CLIENT_DEALER_HPP\n#define UC_CLIENT_DEALER_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <functional>\n#include <map>\n#include <UChain/coin.hpp>\n#include <UChain/client/define.hpp>\n#include <UChain/client/stream.hpp>\n\nnamespace libbitcoin\n{\nnamespace client\n{\n\n// This class is not thread safe.\n/// Matches replies and outgoing messages, walleting for timeouts and retries.\n// This class is a pure proxy; it does not talk directly to zeromq.\nclass BCC_API dealer\n    : public stream\n{\n  public:\n    typedef std::function<void(const code &)> error_handler;\n    typedef std::function<void(const std::string &)> unknown_handler;\n    typedef std::function<void(const binary &, size_t, const hash_digest &,\n                               const chain::transaction &)>\n        stealth_update_handler;\n    typedef std::function<void(const bc::wallet::payment_address &, size_t,\n                               const hash_digest &, const chain::transaction &)>\n        update_handler;\n\n    /// Resend is unrelated to connections.\n    /// Timeout is capped at max_int32 (vs. max_uint32).\n    dealer(stream &out, unknown_handler on_unknown_command,\n           uint32_t timeout_milliseconds, uint8_t resends);\n\n    virtual ~dealer();\n\n    /// True if there are no outstanding requests.\n    bool empty() const;\n\n    /// Clear all handlers with the specified error code.\n    void clear(const code &code);\n\n    /// Accessors.\n    virtual void set_on_update(update_handler on_update);\n    virtual void set_on_stealth_update(stealth_update_handler on_update);\n\n    // stream interface.\n    //-------------------------------------------------------------------------\n\n    /// Resend any timed out work and return the smallest time remaining.\n    virtual int32_t refresh();\n\n    /// Read from this stream onto the specified stream.\n    virtual bool read(stream &stream) override;\n\n    /// Write the specified data to this stream.\n    virtual bool write(const data_stack &data) override;\n\n  protected:\n    // Decodes a message and calls the appropriate callback.\n    typedef std::function<bool(reader &payload)> decoder;\n\n    struct obelisk_message\n    {\n        std::string command;\n        uint32_t id;\n        data_chunk payload;\n    };\n\n    struct pending_request\n    {\n        obelisk_message message;\n        error_handler on_error;\n        decoder on_reply;\n        uint32_t resends;\n        asio::time_point deadline;\n    };\n\n    // Calculate the number of milliseconds remaining in the deadline.\n    static int32_t remaining(const asio::time_point &deadline);\n\n    // send_request->send\n    bool send(const obelisk_message &message);\n\n    // write->receive->decode_reply\n    bool receive(const obelisk_message &message);\n\n    // Sends an outgoing request, and adds handlers to pending request table.\n    bool send_request(const std::string &command, const data_chunk &payload,\n                      error_handler on_error, decoder on_reply);\n\n    // Decodes an incoming message, invoking the error and/or reply handler.\n    // The reply handler must not invoke its handler if there is an error.\n    void decode_reply(const obelisk_message &message, error_handler &on_error,\n                      decoder &on_reply);\n\n    // Payment address notification update.\n    void decode_payment_update(const obelisk_message &message);\n\n    // Stealth address notification update.\n    void decode_stealth_update(const obelisk_message &message);\n\n    uint32_t last_request_index_;\n    const uint8_t resends_;\n    const int32_t timeout_milliseconds_;\n    const unknown_handler on_unknown_;\n    update_handler on_update_;\n    stealth_update_handler on_stealth_update_;\n    std::map<uint32_t, pending_request> pending_;\n    stream &out_;\n};\n\n} // namespace client\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/client/define.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-client.\n *\n * UChain-client is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CLIENT_DEFINE_HPP\n#define UC_CLIENT_DEFINE_HPP\n\n#include <UChain/coin.hpp>\n\n// We use the generic helper definitions in libbitcoin to define BCX_API\n// and BCX_INTERNAL. BCX_API is used for the public API symbols. It either DLL\n// imports or DLL exports (or does nothing for static build) BCX_INTERNAL is\n// used for non-api symbols.\n\n#if defined BCC_STATIC\n#define BCC_API\n#define BCC_INTERNAL\n#elif defined BCC_DLL\n#define BCC_API      BC_HELPER_DLL_EXPORT\n#define BCC_INTERNAL BC_HELPER_DLL_LOCAL\n#else\n#define BCC_API      BC_HELPER_DLL_IMPORT\n#define BCC_INTERNAL BC_HELPER_DLL_LOCAL\n#endif\n\n#endif\n"
  },
  {
    "path": "include/UChain/client/obelisk_client.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-client.\n *\n * UChain-client is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CLIENT_OBELISK_CLIENT_HPP\n#define UC_CLIENT_OBELISK_CLIENT_HPP\n\n#include <cstdint>\n#include <UChain/protocol.hpp>\n#include <UChain/client/define.hpp>\n#include <UChain/client/proxy.hpp>\n#include <UChain/client/socket_stream.hpp>\n\nnamespace libbitcoin {\nnamespace client {\n\n/// Structure used for passing connection settings for a server.\nstruct BCC_API connection_type\n{\n    uint8_t retries;\n    uint16_t timeout_seconds;\n    config::endpoint server;\n    config::sodium server_public_key;\n    config::sodium client_private_key;\n};\n\n/// Client proxy with session management.\nclass BCC_API obelisk_client\n  : public proxy\n{\npublic:\n    /// Construct an instance of the client using timeout/retries from channel.\n    obelisk_client(const connection_type& channel);\n\n    /// Construct an instance of the client using the specified parameters.\n    obelisk_client(uint16_t timeout_seconds, uint8_t retries);\n\n    /// Connect to the specified endpoint.\n    virtual bool connect(const config::endpoint& address);\n\n    /// Connect to the specified endpoint using the provided keys.\n    virtual bool connect(const config::endpoint& address,\n        const bc::config::sodium& server_public_key,\n        const bc::config::sodium& client_private_key);\n\n    /// Connect to the specified endpoint using the provided channel config.\n    virtual bool connect(const connection_type& channel);\n\n    /// Wait for server to respond, until timeout.\n    void wait();\n\n    /// Monitor for subscription notifications, until timeout.\n    void monitor(uint32_t timeout_seconds);\n\nprivate:\n    protocol::zmq::context context_;\n    protocol::zmq::socket socket_;\n    socket_stream stream_;\n    const uint8_t retries_;\n};\n\n} // namespace client\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/client/proxy.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-client.\n *\n * UChain-client is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CLIENT_PROXY_HPP\n#define UC_CLIENT_PROXY_HPP\n\n#include <functional>\n#include <UChain/coin.hpp>\n#include <UChain/client/dealer.hpp>\n#include <UChain/client/define.hpp>\n#include <UChain/client/stream.hpp>\n\nnamespace libbitcoin\n{\nnamespace client\n{\n\n/// Decodes and encodes messages in the obelisk protocol.\n/// This class is a pure proxy; it does not talk directly to zeromq.\nclass BCC_API proxy\n    : public dealer\n{\n  public:\n    /// Resend is unrelated to connections.\n    /// Timeout is capped at max_int32 (vs. max_uint32).\n    proxy(stream &out, unknown_handler on_unknown_command,\n          uint32_t timeout_milliseconds, uint8_t resends);\n\n    // Fetch handler types.\n    //-------------------------------------------------------------------------\n\n    typedef std::function<void()> empty_handler;\n    typedef std::function<void(size_t)> height_handler;\n    typedef std::function<void(size_t, size_t)> transaction_index_handler;\n    typedef std::function<void(const chain::header &)> block_header_handler;\n    typedef std::function<void(const std::vector<chain::header> &)> block_headers_handler;\n    typedef std::function<void(const chain::history::list &)> history_handler;\n    typedef std::function<void(const chain::stealth::list &)> stealth_handler;\n    typedef std::function<void(const chain::transaction &)> transaction_handler;\n    typedef std::function<void(const chain::point::indexes &)> validate_handler;\n    typedef std::function<void(const chain::points_info &)> points_info_handler;\n\n    // Fetchers.\n    //-------------------------------------------------------------------------\n\n    void protocol_broadcast_transaction(error_handler on_error,\n                                        empty_handler on_reply, const chain::transaction &tx);\n\n    void tx_pool_validate(error_handler on_error,\n                                   validate_handler on_reply, const chain::transaction &tx);\n\n    void tx_pool_fetch_transaction(error_handler on_error,\n                                            transaction_handler on_reply, const hash_digest &tx_hash);\n\n    void blockchain_fetch_transaction(error_handler on_error,\n                                      transaction_handler on_reply, const hash_digest &tx_hash);\n\n    void blockchain_fetch_last_height(error_handler on_error,\n                                      height_handler on_reply);\n\n    void blockchain_fetch_block_header(error_handler on_error,\n                                       block_header_handler on_reply, uint32_t height);\n    void blockchain_fetch_block_headers(error_handler on_error,\n                                        block_headers_handler on_reply, uint32_t start, uint32_t end, bool order);\n    void blockchain_fetch_block_header(error_handler on_error,\n                                       block_header_handler on_reply, const hash_digest &block_hash);\n\n    void blockchain_fetch_transaction_index(error_handler on_error,\n                                            transaction_index_handler on_reply, const hash_digest &tx_hash);\n\n    void blockchain_fetch_stealth(error_handler on_error,\n                                  stealth_handler on_reply, const binary &prefix,\n                                  uint32_t from_height = 0);\n\n    void blockchain_fetch_history(error_handler on_error,\n                                  history_handler on_reply, const bc::wallet::payment_address &address,\n                                  uint32_t from_height = 0);\n\n    /// sx and bs 2.0 only (obsolete in bs 3.0).\n    void address_fetch_history(error_handler on_error,\n                               history_handler on_reply, const bc::wallet::payment_address &address,\n                               uint32_t from_height = 0);\n\n    /// bs 2.0 and later.\n    void address_fetch_history2(error_handler on_error,\n                                history_handler on_reply, const bc::wallet::payment_address &address,\n                                uint32_t from_height = 0);\n\n    void address_fetch_unspent_outputs(error_handler on_error,\n                                       points_info_handler on_reply, const bc::wallet::payment_address &address,\n                                       const uint64_t satoshi,\n                                       const bc::wallet::select_outputs::algorithm algorithm);\n\n    // Subscribers.\n    //-------------------------------------------------------------------------\n\n    void address_subscribe(error_handler on_error, empty_handler on_reply,\n                           const bc::wallet::payment_address &address);\n\n    void address_subscribe(error_handler on_error, empty_handler on_reply,\n                           chain::subscribe_type type, const binary &prefix);\n\n  private:\n    // Response handlers.\n    //-------------------------------------------------------------------------\n    static bool decode_empty(reader &payload, empty_handler &handler);\n    static bool decode_transaction(reader &payload,\n                                   transaction_handler &handler);\n    static bool decode_height(reader &payload, height_handler &handler);\n    static bool decode_block_header(reader &payload,\n                                    block_header_handler &handler);\n    static bool decode_block_headers(reader &payload,\n                                     block_headers_handler &handler);\n    static bool decode_transaction_index(reader &payload,\n                                         transaction_index_handler &handler);\n    static bool decode_validate(reader &payload, validate_handler &handler);\n    static bool decode_stealth(reader &payload, stealth_handler &handler);\n    static bool decode_history(reader &payload, history_handler &handler);\n    static bool decode_expanded_history(reader &payload,\n                                        history_handler &handler);\n\n    // Utilities.\n    //-------------------------------------------------------------------------\n    static chain::stealth::list expand(chain::stealth_compact::list &compact);\n    static chain::history::list expand(chain::history_compact::list &compact);\n};\n\n} // namespace client\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/client/socket_stream.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-client.\n *\n * UChain-client is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CLIENT_SOCKET_STREAM_HPP\n#define UC_CLIENT_SOCKET_STREAM_HPP\n\n#include <memory>\n#include <UChain/protocol.hpp>\n#include <UChain/client/define.hpp>\n#include <UChain/client/stream.hpp>\n\nnamespace libbitcoin\n{\nnamespace client\n{\n\n/// This is the only class in the client with a direct protocol dependency.\nclass BCC_API socket_stream\n    : public stream\n{\n  public:\n    socket_stream(protocol::zmq::socket &socket);\n\n    protocol::zmq::socket &socket();\n\n    // stream interface.\n    virtual int32_t refresh();\n    virtual bool read(stream &stream);\n    virtual bool write(const data_stack &data);\n\n  private:\n    protocol::zmq::socket &socket_;\n};\n\n} // namespace client\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/client/stream.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-client.\n *\n * UChain-client is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CLIENT_STREAM_HPP\n#define UC_CLIENT_STREAM_HPP\n\n#include <cstdint>\n#include <UChain/coin.hpp>\n#include <UChain/client/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace client\n{\n\n/// A stream of multi-part messages.\n/// This interface breaks the link between zeromq networking and messaging.\nclass BCC_API stream\n{\n  public:\n    /// Resend any timed out work and return the smallest time remaining.\n    virtual int32_t refresh() = 0;\n\n    /// Read from this stream onto the specified stream.\n    virtual bool read(stream &stream) = 0;\n\n    /// Write the specified data to this stream.\n    virtual bool write(const data_stack &data) = 0;\n};\n\n} // namespace client\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/client/version.hpp",
    "content": "///////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 2011-2018 libbitcoin developers \n// Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n//\n//        GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY\n//\n///////////////////////////////////////////////////////////////////////////////\n#ifndef UC_CLIENT_VERSION_HPP\n#define UC_CLIENT_VERSION_HPP\n\n/**\n * The semantic version of this repository as: [major].[minor].[patch]\n * For interpretation of the versioning scheme see: http://semver.org\n */\n\n#define UC_CLIENT_VERSION \"0.0.6\"\n#define UC_CLIENT_MAJOR_VERSION 0\n#define UC_CLIENT_MINOR_VERSION 0\n#define UC_CLIENT_PATCH_VERSION 6\n\n#endif\n"
  },
  {
    "path": "include/UChain/client.hpp",
    "content": "///////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 2014-2018 libbitcoin-client developers (see COPYING).\n//\n//        GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY\n//\n///////////////////////////////////////////////////////////////////////////////\n#ifndef UC_CLIENT_HPP\n#define UC_CLIENT_HPP\n\n/**\n * API Users: Include only this header. Direct use of other headers is fragile\n * and unsupported as header organization is subject to change.\n *\n * Maintainers: Do not include this header internal to this library.\n */\n\n#include <UChain/coin.hpp>\n#include <UChain/protocol.hpp>\n#include <UChain/client/dealer.hpp>\n#include <UChain/client/define.hpp>\n#include <UChain/client/obelisk_client.hpp>\n#include <UChain/client/proxy.hpp>\n#include <UChain/client/socket_stream.hpp>\n#include <UChain/client/stream.hpp>\n#include <UChain/client/version.hpp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/chain/block.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_BLOCK_HPP\n#define UC_CHAIN_BLOCK_HPP\n\n#include <cstdint>\n#include <istream>\n#include <memory>\n#include <string>\n#include <vector>\n#include <UChain/coin/chain/header.hpp>\n#include <UChain/coin/chain/transaction.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nclass BC_API block\n{\n  public:\n    typedef std::vector<block> list;\n    typedef std::shared_ptr<block> ptr;\n    typedef std::vector<ptr> ptr_list;\n    typedef std::vector<size_t> indexes;\n\n    static block factory_from_data(const data_chunk &data,\n                                   bool with_transaction_count = true);\n    static block factory_from_data(std::istream &stream,\n                                   bool with_transaction_count = true);\n    static block factory_from_data(reader &source,\n                                   bool with_transaction_count = true);\n    static hash_digest generate_merkle_root(\n        const transaction::list &transactions);\n    static block genesis_mainnet();\n    static block genesis_testnet();\n\n    block();\n    block(const block &other);\n    block(const chain::header &header,\n          const chain::transaction::list &transactions);\n\n    block(block &&other);\n    block(chain::header &&header,\n          chain::transaction::list &&transactions);\n\n    /// This class is move assignable but not copy assignable.\n    block &operator=(block &&other);\n    void operator=(const block &) = delete;\n\n    bool from_data(const data_chunk &data, bool with_transaction_count = true);\n    bool from_data(std::istream &stream, bool with_transaction_count = true);\n    bool from_data(reader &source, bool with_transaction_count = true);\n    data_chunk to_data(bool with_transaction_count = true) const;\n    void to_data(std::ostream &stream, bool with_transaction_count = true) const;\n    void to_data(writer &sink, bool with_transaction_count = true) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(bool with_transaction_count = true) const;\n\n    chain::header header;\n    transaction::list transactions;\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/chain/header.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_HEADER_HPP\n#define UC_CHAIN_HEADER_HPP\n\n#include <boost/multiprecision/cpp_int.hpp>\n#include <functional>\n#include <cstdint>\n#include <istream>\n#include <string>\n#include <memory>\n#include <vector>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/thread.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\n#include <UChainService/consensus/libdevcore/FixedHash.h>\n#include <UChainService/consensus/libdevcore/Common.h>\n#include <UChainService/consensus/libdevcore/RLP.h>\n#include <UChainService/consensus/libdevcore/SHA3.h>\n\nnamespace libbitcoin\n{\nusing bigint = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>>;\nusing u64 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<64, 64, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;\nusing u128 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<128, 128, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;\nusing u256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;\n\nnamespace chain\n{\n\nclass BC_API header\n{\n  public:\n    typedef std::vector<header> list;\n    typedef std::shared_ptr<header> ptr;\n    typedef std::vector<ptr> ptr_list;\n\n    static header factory_from_data(const data_chunk &data,\n                                    bool with_transaction_count = true);\n    static header factory_from_data(std::istream &stream,\n                                    bool with_transaction_count = true);\n    static header factory_from_data(reader &source,\n                                    bool with_transaction_count = true);\n    static uint64_t satoshi_fixed_size_without_transaction_count();\n\n    header();\n    header(const header &other);\n    header(uint32_t version, const hash_digest &previous_block_hash,\n           const hash_digest &merkle, uint32_t timestamp, /*const u256& bits,\n        u64 nonce, const u256& mixhash,*/\n           uint32_t number, uint64_t transaction_count = 0);\n\n    header(header &&other);\n    header(uint32_t version, hash_digest &&previous_block_hash,\n           hash_digest &&merkle, uint32_t timestamp, /* const u256& bits,\n        u64 nonce, const u256& mixhash,*/\n           uint32_t number, uint64_t transaction_count = 0);\n\n    /// This class is move assignable but not copy assignable.\n    header &operator=(header &&other);\n\n    // TODO: eliminate blockchain transaction copies and then delete this.\n    header &operator=(const header &other) /*= delete*/;\n\n    bool from_data(const data_chunk &data, bool with_transaction_count = true);\n    bool from_data(std::istream &stream, bool with_transaction_count = true);\n    bool from_data(reader &source, bool with_transaction_count = true);\n    data_chunk to_data(bool with_transaction_count = true) const;\n    void to_data(std::ostream &stream, bool with_transaction_count = true) const;\n    void to_data(writer &sink, bool with_transaction_count = true) const;\n    hash_digest hash() const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(bool with_transaction_count = true) const;\n\n    uint32_t version;\n    hash_digest previous_block_hash;\n    hash_digest merkle;\n    uint32_t timestamp;\n    //u256 bits;\n    //u64 nonce;\n    //u256 mixhash;\n    uint32_t number;\n\n    // The longest size (64) of a protocol variable int is deserialized here.\n    // WHen writing a block the size of the transaction collection is used.\n    uint64_t transaction_count;\n\n  private:\n    mutable upgrade_mutex mutex_;\n    mutable std::shared_ptr<hash_digest> hash_;\n};\n\nBC_API bool operator==(const header &left, const header &right);\nBC_API bool operator!=(const header &left, const header &right);\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/chain/history.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_HISTORY_HPP\n#define UC_CHAIN_HISTORY_HPP\n\n#include <cstdint>\n#include <vector>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/chain/point.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\n/// Use \"kind\" for union differentiation.\nenum class point_kind : uint32_t\n{\n    output = 0,\n    spend = 1\n};\n\n/// This structure models the client-server protocol in v1/v2/v3.\n/// The height value here is 64 bit, but 32 bits on the wire.\nstruct BC_API history_compact\n{\n    typedef std::vector<history_compact> list;\n\n    // The type of point (output or spend).\n    point_kind kind;\n\n    /// The point that identifies the record.\n    chain::point point;\n\n    /// The height of the point.\n    uint64_t height;\n\n    union {\n        /// If output, then satoshi value of output.\n        uint64_t value;\n\n        /// If spend, then checksum hash of previous output point\n        /// To match up this row with the output, recompute the\n        /// checksum from the output row with spend_checksum(row.point)\n        uint64_t previous_checksum;\n    };\n};\n\n/// This structure is used between client and API callers in v3.\n/// This structure models the client-server protocol in v1/v2.\n/// The height values here are 64 bit, but 32 bits on the wire.\nstruct BC_API history\n{\n    typedef std::vector<history> list;\n\n    /// If there is no output this is null_hash:max.\n    output_point output;\n    uint64_t output_height;\n\n    /// The satoshi value of the output.\n    uint64_t value;\n\n    /// If there is no spend this is null_hash:max.\n    input_point spend;\n\n    union {\n        /// The height of the spend or max if no spend.\n        uint64_t spend_height;\n\n        /// During expansion this value temporarily doubles as a checksum.\n        uint64_t temporary_checksum;\n    };\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/chain/input.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_INPUT_HPP\n#define UC_CHAIN_INPUT_HPP\n\n#include <cstdint>\n#include <istream>\n#include <UChain/coin/chain/point.hpp>\n#include <UChain/coin/chain/script/script.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n#include <UChain/coin/wallet/payment_address.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nclass BC_API input\n{\n  public:\n    typedef std::vector<input> list;\n\n    static input factory_from_data(const data_chunk &data);\n    static input factory_from_data(std::istream &stream);\n    static input factory_from_data(reader &source);\n    static uint64_t satoshi_fixed_size();\n\n    bool from_data(const data_chunk &data);\n    bool from_data(std::istream &stream);\n    bool from_data(reader &source);\n    data_chunk to_data() const;\n    void to_data(std::ostream &stream) const;\n    void to_data(writer &sink) const;\n    std::string to_string(uint32_t flags) const;\n    bool is_valid() const;\n    void reset();\n    bool is_final() const;\n    uint64_t serialized_size() const;\n    std::string get_script_address() const;\n\n    output_point previous_output;\n    chain::script script;\n    uint32_t sequence;\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/chain/output.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_OUTPUT_HPP\n#define UC_CHAIN_OUTPUT_HPP\n\n#include <cstdint>\n#include <istream>\n#include <vector>\n#include <UChain/coin/error.hpp>\n#include <UChain/coin/chain/point.hpp>\n#include <UChain/coin/chain/script/script.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n#include <UChainService/txs/asset.hpp> // added for token issue/transfer\n#include <UChainService/txs/uid/uid.hpp>\n\n// forward declaration\nnamespace libbitcoin\n{\nnamespace blockchain\n{\nclass block_chain_impl;\n}\n} // namespace libbitcoin\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nclass BC_API output\n{\n  public:\n    typedef std::vector<output> list;\n\n    static output factory_from_data(const data_chunk &data);\n    static output factory_from_data(std::istream &stream);\n    static output factory_from_data(reader &source);\n    static uint64_t satoshi_fixed_size();\n    static bool is_valid_symbol(const std::string &symbol, uint32_t tx_version);\n    static bool is_valid_uid_symbol(const std::string &symbol, bool check_sensitive = false);\n    static bool is_valid_candidate_symbol(const std::string &symbol, bool check_sensitive = false);\n    bool from_data(const data_chunk &data);\n    bool from_data(std::istream &stream);\n    bool from_data(reader &source);\n    data_chunk to_data() const;\n    void to_data(std::ostream &stream) const;\n    void to_data(writer &sink) const;\n    std::string to_string(uint32_t flags) const;\n    bool is_valid() const;\n    code check_asset_address(bc::blockchain::block_chain_impl &chain) const;\n    std::string get_script_address() const;\n    void reset();\n    uint64_t serialized_size() const;\n    uint64_t get_token_amount() const;\n    std::string get_from_uid() const;\n    std::string get_to_uid() const;\n    std::string get_token_symbol() const;\n    std::string get_token_issuer() const;\n    std::string get_token_address() const;\n    std::string get_token_cert_symbol() const;\n    std::string get_candidate_symbol() const;\n    std::string get_token_cert_owner() const;\n    std::string get_token_cert_address() const;\n    token_cert_type get_token_cert_type() const;\n    const data_chunk &get_attenuation_model_param() const;\n    bool is_token() const;\n    bool is_vote() const;\n    bool is_token_transfer() const;\n    bool is_token_issue() const;\n    bool is_token_secondaryissue() const;\n    bool is_candidate() const;\n    bool is_candidate_register() const;\n    bool is_candidate_transfer() const;\n    bool is_token_cert() const;\n    bool is_token_cert_issue() const;\n    bool is_token_cert_transfer() const;\n    bool is_token_cert_autoissue() const;\n    bool is_ucn() const;\n    bool is_ucn_award() const;\n    bool is_message() const;\n    bool is_uid() const;\n    bool is_uid_register() const;\n    bool is_uid_transfer() const;\n    bool is_fromuid_filled() const;\n    bool is_touid_filled() const;\n    bool is_uid_full_filled() const;\n    token_detail get_token_detail() const;\n    token_transfer get_token_transfer() const;\n    token_cert get_token_cert() const;\n    candidate get_candidate() const;\n    std::string get_uid_symbol() const;\n    std::string get_uid_address() const;\n    uid get_uid() const;\n\n    uint64_t value;\n    chain::script script;\n    asset attach_data; // added for token issue/transfer\n};\n\nstruct BC_API output_info\n{\n    typedef std::vector<output_info> list;\n\n    output_point point;\n    uint64_t value;\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/chain/point.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_POINT_HPP\n#define UC_CHAIN_POINT_HPP\n\n#include <cstdint>\n#include <istream>\n#include <string>\n#include <vector>\n#include <boost/functional/hash.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/chain/point_iterator.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nclass BC_API point\n{\n  public:\n    typedef std::vector<point> list;\n    typedef std::vector<uint32_t> indexes;\n\n    static point factory_from_data(const data_chunk &data);\n    static point factory_from_data(std::istream &stream);\n    static point factory_from_data(reader &source);\n    static uint64_t satoshi_fixed_size();\n\n    uint64_t checksum() const;\n\n    bool is_null() const;\n    bool from_data(const data_chunk &data);\n    bool from_data(std::istream &stream);\n    bool from_data(reader &source);\n    data_chunk to_data() const;\n    void to_data(std::ostream &stream) const;\n    void to_data(writer &sink) const;\n    std::string to_string() const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size() const;\n\n    point_iterator begin() const;\n    point_iterator end() const;\n\n    hash_digest hash;\n    uint32_t index;\n};\n\nBC_API bool operator==(const point &left, const point &right);\nBC_API bool operator!=(const point &left, const point &right);\n\nBC_API bool operator<(const point &left, const point &right);\n\ntypedef point input_point;\ntypedef point output_point;\n\nstruct BC_API points_info\n{\n    output_point::list points;\n    uint64_t change;\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\nnamespace std\n{\n\n// Extend std namespace with our hash wrapper, used as database hash.\ntemplate <>\nstruct hash<bc::chain::point>\n{\n    // Changes to this function invalidate existing database files.\n    size_t operator()(const bc::chain::point &point) const\n    {\n        size_t seed = 0;\n        boost::hash_combine(seed, point.hash);\n        boost::hash_combine(seed, point.index);\n        return seed;\n    }\n};\n\n// Extend std namespace with the size of our point, used as database key size.\ntemplate <>\nstruct tuple_size<bc::chain::point>\n{\n    static const size_t value = std::tuple_size<bc::hash_digest>::value +\n                                sizeof(uint32_t);\n\n    operator std::size_t() const\n    {\n        return value;\n    }\n};\n\n} // namespace std\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/chain/point_iterator.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_POINT_ITERATOR_HPP\n#define UC_CHAIN_POINT_ITERATOR_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <iterator>\n#include <UChain/coin/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nclass point;\n\nclass BC_API point_iterator\n{\n  public:\n    typedef uint8_t pointer;\n    typedef uint8_t reference;\n    typedef uint8_t value_type;\n    typedef ptrdiff_t difference_type;\n    typedef std::bidirectional_iterator_tag iterator_category;\n\n    typedef point_iterator iterator;\n    typedef point_iterator const_iterator;\n\n    // constructors\n    point_iterator(const point &value);\n    point_iterator(const point &value, bool end);\n    point_iterator(const point &value, uint8_t offset);\n\n    operator bool() const;\n\n    // iterator methods\n    reference operator*() const;\n    pointer operator->() const;\n\n    bool operator==(const iterator &other) const;\n    bool operator!=(const iterator &other) const;\n\n    iterator &operator++();\n    iterator operator++(int);\n    iterator &operator--();\n    iterator operator--(int);\n\n  protected:\n    void increment();\n    void decrement();\n\n  private:\n    const point &point_;\n    uint8_t offset_;\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/chain/script/opcode.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_OPCODE_HPP\n#define UC_CHAIN_OPCODE_HPP\n\n#include <cstdint>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nenum class opcode : uint8_t\n{\n    zero = 0,\n    special = 1,\n    pushdata1 = 76,\n    pushdata2 = 77,\n    pushdata4 = 78,\n    negative_1 = 79,\n    // reserved does nothing\n    reserved = 80,\n    op_1 = 81,\n    op_2 = 82,\n    op_3 = 83,\n    op_4 = 84,\n    op_5 = 85,\n    op_6 = 86,\n    op_7 = 87,\n    op_8 = 88,\n    op_9 = 89,\n    op_10 = 90,\n    op_11 = 91,\n    op_12 = 92,\n    op_13 = 93,\n    op_14 = 94,\n    op_15 = 95,\n    op_16 = 96,\n    nop = 97,\n    ver = 98,\n    if_ = 99,\n    notif = 100,\n    verif = 101,\n    vernotif = 102,\n    else_ = 103,\n    endif = 104,\n    verify = 105,\n    return_ = 106,\n    toaltstack = 107,\n    fromaltstack = 108,\n    op_2drop = 109,\n    op_2dup = 110,\n    op_3dup = 111,\n    op_2over = 112,\n    op_2rot = 113,\n    op_2swap = 114,\n    ifdup = 115,\n    depth = 116,\n    drop = 117,\n    dup = 118,\n    nip = 119,\n    over = 120,\n    pick = 121,\n    roll = 122,\n    rot = 123,\n    swap = 124,\n    tuck = 125,\n    cat = 126,    // disabled\n    substr = 127, // disabled\n    left = 128,   // disabled\n    right = 129,  // disabled\n    size = 130,\n    invert = 131, // disabled\n    and_ = 132,   // disabled\n    or_ = 133,    // disabled\n    xor_ = 134,   // disabled\n    equal = 135,\n    equalverify = 136,\n    reserved1 = 137,\n    reserved2 = 138,\n    op_1add = 139,\n    op_1sub = 140,\n    op_2mul = 141, // disabled\n    op_2div = 142, // disabled\n    negate = 143,\n    abs = 144,\n    not_ = 145,\n    op_0notequal = 146,\n    add = 147,\n    sub = 148,\n    mul = 149,    // disabled\n    div = 150,    // disabled\n    mod = 151,    // disabled\n    lshift = 152, // disabled\n    rshift = 153, // disabled\n    booland = 154,\n    boolor = 155,\n    numequal = 156,\n    numequalverify = 157,\n    numnotequal = 158,\n    lessthan = 159,\n    greaterthan = 160,\n    lessthanorequal = 161,\n    greaterthanorequal = 162,\n    min = 163,\n    max = 164,\n    within = 165,\n    ripemd160 = 166,\n    sha1 = 167,\n    sha256 = 168,\n    hash160 = 169,\n    hash256 = 170,\n    codeseparator = 171,\n    checksig = 172,\n    checksigverify = 173,\n    checkmultisig = 174,\n    checkmultisigverify = 175,\n    op_nop1 = 176,\n    checklocktimeverify = 177,    // op_nop2\n    checkattenuationverify = 178, // op_nop3\n    op_nop4 = 179,\n    op_nop5 = 180,\n    op_nop6 = 181,\n    op_nop7 = 182,\n    op_nop8 = 183,\n    op_nop9 = 184,\n    op_nop10 = 185,\n    bad_operation,\n    raw_data\n};\n\nenum script_context : uint32_t\n{\n    none_enabled = 0,\n\n    /// pay-to-script-hash enabled\n    bip16_enabled = 1 << 0,\n\n    /// no duplicated unspent transaction ids\n    bip30_enabled = 1 << 1,\n\n    /// coinbase must include height\n    bip34_enabled = 1 << 2,\n\n    /// strict DER signatures required\n    bip66_enabled = 1 << 3,\n\n    /// nop2 becomes check locktime verify\n    bip65_enabled = 1 << 4,\n\n    /// nop3 becomes check attenuation verify\n    attenuation_enabled = 1 << 5,\n\n    all_enabled = 0xffffffff\n};\n\nBC_API std::string opcode_to_string(opcode value, uint32_t flags);\nBC_API opcode string_to_opcode(const std::string &value);\nBC_API opcode data_to_opcode(const data_chunk &value);\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/chain/script/operation.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_OPERATION_HPP\n#define UC_CHAIN_OPERATION_HPP\n\n#include <cstddef>\n#include <iostream>\n#include <vector>\n#include <UChain/coin/chain/script/opcode.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/elliptic_curve.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\n// forward declaration\nclass point;\n\n/// Script patterms.\n/// Comments from: bitcoin.org/en/developer-guide#signature-hash-types\nenum class script_pattern\n{\n    /// Null Data\n    /// Pubkey Script: OP_RETURN <0 to 80 bytes of data> (formerly 40 bytes)\n    /// Null data scripts cannot be spent, so there's no signature script.\n    null_data,\n\n    /// Pay to Multisig [BIP11]\n    /// Pubkey script: <m> <A pubkey>[B pubkey][C pubkey...] <n> OP_CHECKMULTISIG\n    /// Signature script: OP_0 <A sig>[B sig][C sig...]\n    pay_multisig,\n\n    /// Pay to Public Key (obsolete)\n    pay_public_key,\n\n    /// Pay to Public Key Hash [P2PKH]\n    /// Pubkey script: OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG\n    /// Signature script: <sig> <pubkey>\n    pay_key_hash,\n\n    pay_key_hash_with_lock_height,\n\n    /// Pay to Script Hash [P2SH/BIP16]\n    /// The redeem script may be any pay type, but only multisig makes sense.\n    /// Pubkey script: OP_HASH160 <Hash160(redeemScript)> OP_EQUAL\n    /// Signature script: <sig>[sig][sig...] <redeemScript>\n    pay_script_hash,\n\n    /// Sign Multisig script [BIP11]\n    sign_multisig,\n\n    /// Sign Public Key (obsolete)\n    sign_public_key,\n\n    /// Sign Public Key Hash [P2PKH]\n    sign_key_hash,\n\n    sign_key_hash_with_lock_height,\n\n    /// Sign Script Hash [P2SH/BIP16]\n    sign_script_hash,\n\n    /// The script is valid but does not conform to the standard tempaltes.\n    /// Such scripts are always accepted if they are mined into blocks, but\n    /// transactions with non-standard scripts may not be forwarded by peers.\n    non_standard,\n\n    /// Pay to black hole address\n    pay_blackhole_address,\n\n    /// Pay to Public Key Hash [P2PKH] with attenuation model\n    /// Pubkey script:\n    ///     <model_param> <input_point> OP_CHECKATTENUATIONVERIFY\n    ///     OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG\n    /// Signature script: <sig> <pubkey>\n    pay_key_hash_with_attenuation_model,\n\n};\n\nclass BC_API operation\n{\n  public:\n    typedef std::vector<operation> stack;\n\n    static const size_t max_null_data_size;\n\n    static operation factory_from_data(const data_chunk &data);\n    static operation factory_from_data(std::istream &stream);\n    static operation factory_from_data(reader &source);\n\n    static bool is_push_only(const operation::stack &operations);\n\n    /// unspendable pattern (standard)\n    static bool is_null_data_pattern(const operation::stack &ops);\n\n    /// payment script patterns (standard)\n    static bool is_pay_multisig_pattern(const operation::stack &ops);\n    static bool is_pay_public_key_pattern(const operation::stack &ops);\n    static bool is_pay_key_hash_pattern(const operation::stack &ops);\n    static bool is_pay_key_hash_with_lock_height_pattern(const operation::stack &ops);\n    static bool is_pay_script_hash_pattern(const operation::stack &ops);\n    static bool is_pay_blackhole_pattern(const operation::stack &ops);\n    static bool is_pay_key_hash_with_attenuation_model_pattern(const operation::stack &ops);\n\n    /// signature script patterns (standard)\n    static bool is_sign_multisig_pattern(const operation::stack &ops);\n    static bool is_sign_public_key_pattern(const operation::stack &ops);\n    static bool is_sign_key_hash_pattern(const operation::stack &ops);\n    static bool is_sign_key_hash_with_lock_height_pattern(const operation::stack &ops);\n    static bool is_sign_script_hash_pattern(const operation::stack &ops);\n\n    static uint64_t get_lock_height_from_sign_key_hash_with_lock_height(const operation::stack &ops);\n    static uint64_t get_lock_height_from_pay_key_hash_with_lock_height(const operation::stack &ops);\n    static const data_chunk &get_model_param_from_pay_key_hash_with_attenuation_model(const operation::stack &ops);\n    static const data_chunk &get_input_point_from_pay_key_hash_with_attenuation_model(const operation::stack &ops);\n\n    /// stack factories\n    static stack to_null_data_pattern(data_slice data);\n    static stack to_pay_multisig_pattern(uint8_t signatures,\n                                         const point_list &points);\n    static stack to_pay_multisig_pattern(uint8_t signatures,\n                                         const data_stack &points);\n    static stack to_pay_public_key_pattern(data_slice point);\n    static stack to_pay_key_hash_pattern(const short_hash &hash);\n    static stack to_pay_key_hash_with_lock_height_pattern(const short_hash &hash, uint32_t block_height);\n    static stack to_pay_script_hash_pattern(const short_hash &hash);\n    static stack to_pay_blackhole_pattern(const short_hash &hash);\n    static stack to_pay_key_hash_with_attenuation_model_pattern(\n        const short_hash &hash, const std::string &model_param, const point &input_point);\n\n    bool from_data(const data_chunk &data);\n    bool from_data(std::istream &stream);\n    bool from_data(reader &source);\n    data_chunk to_data() const;\n    void to_data(std::ostream &stream) const;\n    void to_data(writer &sink) const;\n    std::string to_string(uint32_t flags) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size() const;\n\n    opcode code;\n    data_chunk data;\n\n  private:\n    static bool is_push(const opcode code);\n    static uint64_t count_non_push(const operation::stack &operations);\n    static bool must_read_data(opcode code);\n    static bool read_opcode_data_size(uint32_t &count, opcode code,\n                                      uint8_t byte, reader &source);\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/chain/script/script.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_SCRIPT_HPP\n#define UC_CHAIN_SCRIPT_HPP\n\n#include <cstdint>\n#include <istream>\n#include <string>\n#include <vector>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/chain/script/operation.hpp>\n#include <UChain/coin/math/elliptic_curve.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nclass BC_API transaction;\n\n/// Signature hash types.\n/// Comments from: bitcoin.org/en/developer-guide#standard-transactions\nenum signature_hash_algorithm : uint32_t\n{\n    /// The default, signs all the inputs and outputs, protecting everything\n    /// except the signature scripts against modification.\n    all = 0x01,\n\n    /// Signs all of the inputs but none of the outputs, allowing anyone to\n    /// change where the satoshis are going unless other signatures using\n    /// other signature hash flags protect the outputs.\n    none = 0x02,\n\n    /// The only output signed is the one corresponding to this input (the\n    /// output with the same output index number as this input), ensuring\n    /// nobody can change your part of the transaction but allowing other\n    /// signers to change their part of the transaction. The corresponding\n    /// output must exist or the value '1' will be signed, breaking the\n    /// security scheme. This input, as well as other inputs, are included\n    /// in the signature. The sequence numbers of other inputs are not\n    /// included in the signature, and can be updated.\n    single = 0x03,\n\n    /// The above types can be modified with this flag, creating three new\n    /// combined types.\n    anyone_can_pay = 0x80,\n\n    /// Signs all of the outputs but only this one input, and it also allows\n    /// anyone to add or remove other inputs, so anyone can contribute\n    /// additional satoshis but they cannot change how many satoshis are\n    /// sent nor where they go.\n    all_anyone_can_pay = all | anyone_can_pay,\n\n    /// Signs only this one input and allows anyone to add or remove other\n    /// inputs or outputs, so anyone who gets a copy of this input can spend\n    /// it however they'd like.\n    none_anyone_can_pay = none | anyone_can_pay,\n\n    /// Signs this one input and its corresponding output. Allows anyone to\n    /// add or remove other inputs.\n    single_anyone_can_pay = single | anyone_can_pay,\n\n    /// Used to mask off the anyone_can_pay flag to access the enumeration.\n    mask = ~anyone_can_pay\n};\n\n// All prefix = true\n// All parse_mode = script::parse_mode::strict\n\nclass BC_API script\n{\n  public:\n    enum class parse_mode\n    {\n        strict,\n        raw_data,\n        raw_data_fallback\n    };\n\n    static script factory_from_data(const data_chunk &data, bool prefix,\n                                    parse_mode mode);\n    static script factory_from_data(std::istream &stream, bool prefix,\n                                    parse_mode mode);\n    static script factory_from_data(reader &source, bool prefix,\n                                    parse_mode mode);\n\n    static bool verify(const script &input_script,\n                       const script &output_script, const transaction &parent_tx,\n                       uint32_t input_index, uint32_t flags);\n\n    static hash_digest generate_signature_hash(const transaction &parent_tx,\n                                               uint32_t input_index, const script &script_code, uint8_t sighash_type);\n\n    static bool create_endorsement(endorsement &out, const ec_secret &secret,\n                                   const script &prevout_script, const transaction &new_tx,\n                                   uint32_t input_index, uint8_t sighash_type);\n\n    static bool is_active(uint32_t flags, script_context flag);\n\n    static bool check_signature(const ec_signature &signature,\n                                uint8_t sighash_type, const data_chunk &public_key,\n                                const script &script_code, const transaction &parent_tx,\n                                uint32_t input_index);\n\n    script_pattern pattern() const;\n    bool is_raw_data() const;\n    bool from_data(const data_chunk &data, bool prefix, parse_mode mode);\n    bool from_data(std::istream &stream, bool prefix, parse_mode mode);\n    bool from_data(reader &source, bool prefix, parse_mode mode);\n    data_chunk to_data(bool prefix) const;\n    void to_data(std::ostream &stream, bool prefix) const;\n    void to_data(writer &sink, bool prefix) const;\n\n    bool from_string(const std::string &human_readable);\n    std::string to_string(uint32_t flags) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t satoshi_content_size() const;\n    uint64_t serialized_size(bool prefix) const;\n\n    operation::stack operations;\n\n  private:\n    bool deserialize(const data_chunk &raw_script, parse_mode mode);\n    bool parse(const data_chunk &raw_script);\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/chain/spend.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_SPEND_HPP\n#define UC_CHAIN_SPEND_HPP\n\n#include <vector>\n#include <UChain/coin/chain/point.hpp>\n#include <UChain/coin/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nstruct BC_API spend\n{\n    bool valid;\n    uint32_t index;\n    hash_digest hash;\n};\n\nstruct BC_API spend_info\n{\n    typedef std::vector<spend_info> list;\n\n    input_point point;\n    output_point previous_output;\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/chain/stealth.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_STEALTH_HPP\n#define UC_CHAIN_STEALTH_HPP\n\n#include <cstdint>\n#include <vector>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/elliptic_curve.hpp>\n#include <UChain/coin/math/hash.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\n/// Differentiate subscription to payment address or stealth address.\n/// v2 (deprecated) requires an explicit subscription type.\n/// v3 eliminates the subscription type, which we map to 'unspecified'.\nenum class subscribe_type : uint8_t\n{\n    payment = 0,\n    stealth = 1,\n    unspecified = 2,\n    unsubscribe = 3\n};\n\n/// This structure is used in the client-server protocol in v2/v3.\n/// The stealth row excludes the sign byte (0x02) of the ephemeral public key.\nstruct BC_API stealth_compact\n{\n    typedef std::vector<stealth_compact> list;\n\n    hash_digest ephemeral_public_key_hash;\n    short_hash public_key_hash;\n    hash_digest transaction_hash;\n};\n\n/// This structure is used between client and API callers in v2/v3.\n/// The normal stealth row includes the sign byte of the ephemeral public key.\nstruct BC_API stealth\n{\n    typedef std::vector<stealth> list;\n\n    ec_compressed ephemeral_public_key;\n    short_hash public_key_hash;\n    hash_digest transaction_hash;\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/chain/transaction.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_TRANSACTION_HPP\n#define UC_CHAIN_TRANSACTION_HPP\n\n#include <cstdint>\n#include <istream>\n#include <memory>\n#include <string>\n#include <vector>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/chain/input.hpp>\n#include <UChain/coin/chain/output.hpp>\n#include <UChain/coin/math/elliptic_curve.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/thread.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nenum transaction_version\n{\n    first = 1,               //the frist version\n    check_output_script = 2, //add check output script\n    check_uid_testnet = 3,\n    check_uid_feature = 4,\n    max_version = 5\n};\n\nclass BC_API transaction\n{\n  public:\n    typedef std::vector<transaction> list;\n    typedef std::shared_ptr<transaction> ptr;\n    typedef std::vector<ptr> ptr_list;\n    typedef std::vector<size_t> indexes;\n\n    static transaction factory_from_data(const data_chunk &data);\n    static transaction factory_from_data(std::istream &stream);\n    static transaction factory_from_data(reader &source);\n    static uint64_t satoshi_fixed_size();\n\n    transaction();\n    transaction(const transaction &other);\n    transaction(uint32_t version, uint32_t locktime, const input::list &inputs,\n                const output::list &outputs);\n\n    transaction(transaction &&other);\n    transaction(uint32_t version, uint32_t locktime, input::list &&inputs,\n                output::list &&outputs);\n\n    /// This class is move assignable [but not copy assignable].\n    transaction &operator=(transaction &&other);\n\n    // TODO: eliminate blockchain transaction copies and then delete this.\n    transaction &operator=(const transaction &other) /*= delete*/;\n\n    bool from_data(const data_chunk &data);\n    bool from_data(std::istream &stream);\n    bool from_data(reader &source);\n    data_chunk to_data() const;\n    void to_data(std::ostream &stream) const;\n    void to_data(writer &sink) const;\n    std::string to_string(uint32_t flags) const;\n    bool is_valid() const;\n    void reset();\n    hash_digest hash() const;\n\n    // sighash_type is used by OP_CHECKSIG\n    hash_digest hash(uint32_t sighash_type) const;\n    bool is_coinbase() const;\n    bool is_strict_coinbase() const;\n    bool is_token_block_coinbase() const;\n    bool is_final(uint64_t block_height, uint32_t block_time) const;\n    bool is_locktime_conflict() const;\n    uint64_t total_output_value() const;\n    uint64_t serialized_size() const;\n    uint64_t total_output_transfer_amount() const;\n    uint64_t total_output_vote_amount() const;\n    bool has_token_issue() const;\n    bool has_token_secondary_issue() const;\n    bool has_token_transfer() const;\n    bool has_token_vote() const;\n    bool has_token_cert() const;\n    bool has_candidate_transfer() const;\n    bool has_candidate_register() const;\n\n    bool has_uid_register() const;\n    bool has_uid_transfer() const;\n    std::string get_uid_transfer_old_address() const;\n\n    uint32_t version;\n    uint32_t locktime;\n    input::list inputs;\n    output::list outputs;\n\n  private:\n    mutable upgrade_mutex mutex_;\n    mutable std::shared_ptr<hash_digest> hash_;\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/compat.h",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_COMPAT_H\n#define UC_COMPAT_H\n\n#ifdef _MSC_VER\n/* There is no <endian.h> for MSVC but it is always little endian. */\n#ifndef __LITTLE_ENDIAN__\n#undef __BIG_ENDIAN__\n#define __LITTLE_ENDIAN__\n#endif\n#endif\n\n#ifdef _MSC_VER\n#define BC_C_INLINE __inline\n#else\n#define BC_C_INLINE inline\n#endif\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/compat.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_COMPAT_HPP\n#define UC_COMPAT_HPP\n\n#include <cstdint>\n#include <limits>\n\n// CTP_Nov2013 implements noexcept but unfortunately VC12 and CTP_Nov2013\n// both identify as _MSC_VER = 1800, otherwise we could include CTP_Nov2013.\n#if defined(_MSC_VER) && (_MSC_VER <= 1800)\n#define BC_NOEXCEPT _NOEXCEPT\n#define BC_CONSTEXPR const\n#define BC_CONSTFUNC inline\n#else\n#define BC_NOEXCEPT noexcept\n#define BC_CONSTEXPR constexpr\n#define BC_CONSTFUNC constexpr\n#endif\n\n// TODO: prefix names with BC_\n#ifdef _MSC_VER\n#define MIN_INT64 INT64_MIN\n#define MAX_INT64 INT64_MAX\n#define MIN_INT32 INT32_MIN\n#define MAX_INT32 INT32_MAX\n#define MAX_UINT64 UINT64_MAX\n#define MAX_UINT32 UINT32_MAX\n#define MAX_UINT16 UINT16_MAX\n#define MAX_UINT8 UINT8_MAX\n#define BC_MAX_SIZE SIZE_MAX\n#else\n#define MIN_INT64 std::numeric_limits<int64_t>::min()\n#define MAX_INT64 std::numeric_limits<int64_t>::max()\n#define MIN_INT32 std::numeric_limits<int32_t>::min()\n#define MAX_INT32 std::numeric_limits<int32_t>::max()\n#define MAX_UINT64 std::numeric_limits<uint64_t>::max()\n#define MAX_UINT32 std::numeric_limits<uint32_t>::max()\n#define MAX_UINT16 std::numeric_limits<uint16_t>::max()\n#define MAX_UINT8 std::numeric_limits<uint8_t>::max()\n#define BC_MAX_SIZE std::numeric_limits<size_t>::max()\n#endif\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/config/authority.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CONFIG_AUTHORITY_HPP\n#define UC_CONFIG_AUTHORITY_HPP\n\n#include <cstdint>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/message/network_address.hpp>\n#include <UChain/coin/utility/asio.hpp>\n\nnamespace libbitcoin\n{\nnamespace config\n{\n\n/**\n * Serialization helper for a network authority.\n * This is a container for a {ip address, port} tuple.\n */\nclass BC_API authority\n{\n  public:\n    /**\n     * A list of authorities.\n     * This must provide operator<< for ostream in order to be used as a\n     * boost::program_options default_value.\n     */\n    typedef std::vector<authority> list;\n    typedef std::shared_ptr<authority> ptr;\n\n    /**\n     * Default constructor.\n     */\n    authority();\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    authority(const authority &other);\n\n    /**\n     * Initialization constructor.\n     * Deserialize a IPv4 or IPv6 address-based hostname[:port].\n     * The port is optional and will be set to zero if not provided.\n     * @param[in]  authority  The initial value in one of two forms:\n     *                        [2001:db8::2]:port or 1.2.240.1:port\n     */\n    authority(const std::string &authority);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  net  The network address (ip and port) to initialize with.\n     */\n    authority(const message::network_address &address);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  ip    The ip addresss to initialize with.\n     * @param[in]  port  The port to initialize with.\n     */\n    authority(const message::ip_address &ip, uint16_t port);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  host  The host to initialize with in one of three forms:\n     *                   [2001:db8::2] or 2001:db8::2 or 1.2.240.1\n     * @param[in]  port  The port to initialize with.\n     */\n    authority(const std::string &host, uint16_t port);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  ip    The boost ip addresss to initialize with.\n     * @param[in]  port  The port to initialize with.\n     */\n    authority(const asio::address &ip, uint16_t port);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  endpoint  The boost endpoint addresss to initialize with.\n     */\n    authority(const asio::endpoint &endpoint);\n\n    /**\n     * Getter.\n     * @return The ip address of the authority.\n     */\n    message::ip_address ip() const;\n\n    /**\n     * Getter.\n     * @return The tcp port of the authority.\n     */\n    uint16_t port() const;\n\n    /**\n     * Get the hostname of the authority as a string.\n     * The form of the return is determined by the type of address.\n     * @return The hostname in one of two forms: 2001:db8::2 or 1.2.240.1\n     */\n    std::string to_hostname() const;\n\n    /**\n     * Get the authority as a string.\n     * The form of the return is determined by the type of address.\n     * The port is optional and not included if zero-valued.\n     * @return The authority in one of two forms:\n     *         [2001:db8::2]:port or 1.2.240.1:port\n     */\n    std::string to_string() const;\n\n    /**\n     * Convert to bitcoin network address type.\n     * @return  The authority converted to a network address.\n     */\n    message::network_address to_network_address() const;\n\n    /**\n     * Override the equality operator.\n     * @param[in]  other  The other object with which to compare.\n     */\n    bool operator==(const authority &other) const;\n\n    /**\n     * Override the inequality operator.\n     * @param[in]  other  The other object with which to compare.\n     */\n    bool operator!=(const authority &other) const;\n\n    bool operator<(const authority &other) const;\n\n    /**\n     * Define stream in. Throws if input is invalid.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    authority &argument);\n\n    /**\n     * Define stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const authority &argument);\n\n  private:\n    asio::ipv6 ip_;\n    uint16_t port_;\n};\n\n} // namespace config\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/config/base16.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CONFIG_BASE16_HPP\n#define UC_CONFIG_BASE16_HPP\n\n#include <array>\n#include <iostream>\n#include <string>\n#include <cstdint>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\nnamespace config\n{\n\n/**\n * Serialization helper for base16 encoded data.\n */\nclass BC_API base16\n{\n  public:\n    /**\n     * Default constructor.\n     */\n    base16();\n\n    /**\n     * Initialization constructor.\n     * @param[in]  hexcode  The value to initialize with.\n     */\n    base16(const std::string &hexcode);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  value  The value to initialize with.\n     */\n    base16(const data_chunk &value);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  value  The value to initialize with.\n     */\n    template <size_t Size>\n    base16(const byte_array<Size> &value)\n        : value_(value.begin(), value.end())\n    {\n    }\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    base16(const base16 &other);\n\n    /**\n     * Overload cast to internal type.\n     * @return  This object's value cast to internal type reference.\n     */\n    operator const data_chunk &() const;\n\n    /**\n     * Overload cast to generic data reference.\n     * @return  This object's value cast to a generic data.\n     */\n    operator data_slice() const;\n\n    /**\n     * Overload stream in. If input is invalid sets no bytes in argument.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    base16 &argument);\n\n    /**\n     * Overload stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const base16 &argument);\n\n  private:\n    /**\n     * The state of this object.\n     */\n    data_chunk value_;\n};\n\n} // namespace config\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/config/base2.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CONFIG_BASE2_HPP\n#define UC_CONFIG_BASE2_HPP\n\n#include <cstddef>\n#include <iostream>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/binary.hpp>\n\nnamespace libbitcoin\n{\nnamespace config\n{\n\n/**\n * Serialization helper for base2 encoded data.\n */\nclass BC_API base2\n{\n  public:\n    /**\n     * Default constructor.\n     */\n    base2();\n\n    /**\n     * Initialization constructor.\n     * @param[in]  bin  The value to initialize with.\n     */\n    base2(const std::string &binary);\n\n    /**\n     * @param[in]  value  The value to initialize with.\n     */\n    base2(const binary &value);\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    base2(const base2 &other);\n\n    /**\n     * Get number of bits in value.\n     */\n    size_t size() const;\n\n    /**\n     * Overload cast to internal type.\n     * @return  This object's value cast to internal type reference.\n     */\n    operator const binary &() const;\n\n    /**\n     * Overload stream in. If input is invalid sets no bytes in argument.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    base2 &argument);\n\n    /**\n     * Overload stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const base2 &argument);\n\n  private:\n    /**\n     * The state of this object.\n     */\n    binary value_;\n};\n\n} // namespace config\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/config/base58.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CONFIG_BASE58_HPP\n#define UC_CONFIG_BASE58_HPP\n\n#include <iostream>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\nnamespace config\n{\n\n/**\n * Serialization helper for base58 encoded text.\n */\nclass BC_API base58\n{\n  public:\n    /**\n     * Default constructor.\n     */\n    base58();\n\n    /**\n     * Initialization constructor.\n     * @param[in]  base58  The value to initialize with.\n     */\n    base58(const std::string &base58);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  value  The value to initialize with.\n     */\n    base58(const data_chunk &value);\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    base58(const base58 &other);\n\n    /**\n     * Overload cast to internal type.\n     * @return  This object's value cast to internal type reference.\n     */\n    operator const data_chunk &() const;\n\n    /**\n     * Overload cast to generic data reference.\n     * @return  This object's value cast to a generic data.\n     */\n    operator data_slice() const;\n\n    /**\n     * Overload stream in. Throws if input is invalid.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    base58 &argument);\n\n    /**\n     * Overload stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const base58 &argument);\n\n  private:\n    /**\n     * The state of this object.\n     */\n    data_chunk value_;\n};\n\n} // namespace config\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/config/base64.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CONFIG_BASE64_HPP\n#define UC_CONFIG_BASE64_HPP\n\n#include <iostream>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\nnamespace config\n{\n\n/**\n * Serialization helper for base64 encoded data.\n */\nclass BC_API base64\n{\n  public:\n    /**\n     * Default constructor.\n     */\n    base64();\n\n    /**\n     * Initialization constructor.\n     * @param[in]  base64  The value to initialize with.\n     */\n    base64(const std::string &base64);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  value  The value to initialize with.\n     */\n    base64(const data_chunk &value);\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    base64(const base64 &other);\n\n    /**\n     * Overload cast to internal type.\n     * @return  This object's value cast to internal type reference.\n     */\n    operator const data_chunk &() const;\n\n    /**\n     * Overload cast to generic data reference.\n     * @return  This object's value cast to a generic data.\n     */\n    operator data_slice() const;\n\n    /**\n     * Overload stream in. Throws if input is invalid.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    base64 &argument);\n\n    /**\n     * Overload stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const base64 &argument);\n\n  private:\n    /**\n     * The state of this object.\n     */\n    data_chunk value_;\n};\n\n} // namespace config\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/config/checkpoint.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CONFIG_CHECKPOINT_HPP\n#define UC_CONFIG_CHECKPOINT_HPP\n\n#include <cstddef>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/formats/base_16.hpp>\n\nnamespace libbitcoin\n{\nnamespace config\n{\n\n/**\n * Serialization helper for a blockchain checkpoint.\n * This is a container for a {block hash, block height} tuple.\n */\nclass BC_API checkpoint\n{\n  public:\n    /**\n     * A list of checkpoints.\n     * This must provide operator<< for ostream in order to be used as a\n     * boost::program_options default_value.\n     */\n    typedef std::vector<checkpoint> list;\n\n    /**\n     * Created a sorted copy of the list of checkpoints.\n     * @param[in]  checks  The list of checkpoints.\n     * @return             The sorted list of checkpoints.\n     */\n    static list sort(const list &checks);\n\n    /**\n     * Validate a checkpoint against a list of checkpoints.\n     * @param[in]  hash    The hash of the checkpoint.\n     * @param[in]  height  The height of checkpoint.\n     * @param[in]  checks  The list of checkpoints.\n     */\n    static bool validate(const hash_digest &hash, size_t height,\n                         const list &checks);\n\n    /**\n     * Default constructor.\n     */\n    checkpoint();\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    checkpoint(const checkpoint &other);\n\n    /**\n     * Initialization constructor.\n     * The height is optional and will be set to zero if not provided.\n     * @param[in]  value  The value of the hash[:height] form.\n     */\n    checkpoint(const std::string &value);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  hash    The string block hash for the checkpoint.\n     * @param[in]  height  The height of the hash.\n     */\n    checkpoint(const std::string &hash, size_t height);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  hash    The block hash for the checkpoint.\n     * @param[in]  height  The height of the hash.\n     */\n    checkpoint(const hash_digest &hash, size_t height);\n\n    /**\n     * Getter.\n     * @return The block hash of the checkpoint.\n     */\n    hash_digest hash() const;\n\n    /**\n     * Getter.\n     * @return The block height of the checkpoint.\n     */\n    size_t height() const;\n\n    /**\n     * Get the checkpoint as a string.\n     * @return The ip address of the authority in the hash:height form.\n     */\n    std::string to_string() const;\n\n    /**\n     * Override the equality operator.\n     * @param[in]  other  The other object with which to compare.\n     */\n    bool operator==(const checkpoint &other) const;\n\n    /**\n     * Define stream in. Throws if input is invalid.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    checkpoint &argument);\n\n    /**\n     * Define stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const checkpoint &argument);\n\n  private:\n    hash_digest hash_;\n    size_t height_;\n};\n\n} // namespace config\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/config/directory.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CONFIG_DIRECTORY_HPP\n#define UC_CONFIG_DIRECTORY_HPP\n\n#include <string>\n#include <boost/filesystem.hpp>\n#include <UChain/coin/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace config\n{\n\n// Declare config_default_path() via BC_DECLARE_CONFIG_DEFAULT_PATH(relative).\n#define CONFIG_DEFAULT_PATH(directory, subdirectory)     \\\n    static boost::filesystem::path config_default_path() \\\n    {                                                    \\\n        const boost::filesystem::path folder(directory); \\\n        return folder / subdirectory;                    \\\n    }\n\n// The SYSCONFDIR symbol must be defined at compile for the project.\n// Therefore this must be compiled directly into the relevant project(s).\n#ifdef _MSC_VER\n#define BC_DECLARE_CONFIG_DEFAULT_PATH(relative) \\\n    CONFIG_DEFAULT_PATH(bc::config::windows_config_directory(), relative)\n#else\n#define SYSCONFDIR \"conf\"\n#define BC_DECLARE_CONFIG_DEFAULT_PATH(relative) \\\n    CONFIG_DEFAULT_PATH(SYSCONFDIR, relative)\n#endif\n\n/**\n * Get the windows configuration directory.\n * @return Path or empty string if unable to retrieve.\n */\nBC_API std::string windows_config_directory();\n\n} // namespace config\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/config/endpoint.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CONFIG_ENDPOINT_HPP\n#define UC_CONFIG_ENDPOINT_HPP\n\n#include <cstdint>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <boost/asio.hpp>\n#include <UChain/coin/config/authority.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/formats/base_16.hpp>\n\nnamespace libbitcoin\n{\nnamespace config\n{\n\n/**\n * Serialization helper for a network endpoint in URI format.\n * This is a container for a {scheme, host, port} tuple.\n */\nclass BC_API endpoint\n{\n  public:\n    /**\n     * A list of endpoints.\n     * This must provide operator<< for ostream in order to be used as a\n     * boost::program_options default_value.\n     */\n    typedef std::vector<endpoint> list;\n\n    /**\n     * Default constructor.\n     */\n    endpoint();\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    endpoint(const endpoint &other);\n\n    /**\n     * Initialization constructor.\n     * The scheme and port may be undefined, in which case the port is reported\n     * as zero and the scheme is reported as an empty string.\n     * @param[in]  value  The initial value of the [scheme://]host[:port] form.\n     */\n    endpoint(const std::string &value);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  authority  The value to initialize with.\n     */\n    endpoint(const authority &authority);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  host  The host name or ip address to initialize with.\n     * @param[in]  port  The port to initialize with.\n     */\n    endpoint(const std::string &host, uint16_t port);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  endpoint  The endpoint addresss to initialize with.\n     */\n    endpoint(const asio::endpoint &host);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  ip    The boost ip addresss to initialize with.\n     * @param[in]  port  The port to initialize with.\n     */\n    endpoint(const asio::address &ip, uint16_t port);\n\n    /**\n     * Getter.\n     * @return True if the endpoint is initialized.\n     */\n    operator bool() const;\n\n    /**\n     * Getter.\n     * @return The scheme of the endpoint or empty string.\n     */\n    const std::string &scheme() const;\n\n    /**\n     * Getter.\n     * @return The host name or ip address of the endpoint.\n     */\n    const std::string &host() const;\n\n    /**\n     * Getter.\n     * @return The tcp port of the endpoint.\n     */\n    uint16_t port() const;\n\n    /**\n     * Get the endpoint as a string.\n     * An empty scheme and/or empty port is omitted.\n     * @return The endpoint in the [scheme://]host[:port] form.\n     */\n    std::string to_string() const;\n\n    /**\n     * Override the equality operator.\n     * @param[in]  other  The other object with which to compare.\n     */\n    bool operator==(const endpoint &other) const;\n\n    /**\n     * Define stream in. Throws if input is invalid.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    endpoint &argument);\n\n    /**\n     * Define stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const endpoint &argument);\n\n  private:\n    std::string scheme_;\n    std::string host_;\n    uint16_t port_;\n};\n\n} // namespace config\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/config/hash160.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CONFIG_HASH160_HPP\n#define UC_CONFIG_HASH160_HPP\n\n#include <iostream>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/hash.hpp>\n\nnamespace libbitcoin\n{\nnamespace config\n{\n\n/**\n * Serialization helper for a bitcoin 160 bit hash.\n */\nclass BC_API hash160\n{\n  public:\n    /**\n     * Default constructor.\n     */\n    hash160();\n\n    /**\n     * Initialization constructor.\n     * @param[in]  hexcode  The value to initialize with.\n     */\n    hash160(const std::string &hexcode);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  value  The value to initialize with.\n     */\n    hash160(const short_hash &value);\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    hash160(const hash160 &other);\n\n    /**\n     * Overload cast to internal type.\n     * @return  This object's value cast to internal type.\n     */\n    operator const short_hash &() const;\n\n    /**\n     * Overload stream in. Throws if input is invalid.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    hash160 &argument);\n\n    /**\n     * Overload stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const hash160 &argument);\n\n  private:\n    /**\n     * The state of this object.\n     */\n    short_hash value_;\n};\n\n} // namespace config\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/config/hash256.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CONFIG_HASH256_HPP\n#define UC_CONFIG_HASH256_HPP\n\n#include <iostream>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/hash.hpp>\n\nnamespace libbitcoin\n{\nnamespace config\n{\n\n/**\n * Serialization helper for a bitcoin 256 bit hash.\n */\nclass BC_API hash256\n{\n  public:\n    /**\n     * A list of bitcoin 256 bit hashes.\n     * This must provide operator<< for ostream in order to be used as a\n     * boost::program_options default_value.\n     */\n    typedef std::vector<hash256> list;\n\n    /**\n     * Default constructor.\n     */\n    hash256();\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    hash256(const hash256 &other);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  hexcode  The hash value in string hexidecimal form.\n     */\n    hash256(const std::string &hexcode);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  value  The hash value to initialize with.\n     */\n    hash256(const hash_digest &value);\n\n    /**\n     * Get the hash as a string.\n     * @return The hash in the string hexidecimal form.\n     */\n    std::string to_string() const;\n\n    /**\n     * Override the equality operator.\n     * @param[in]  other  The other object with which to compare.\n     */\n    bool operator==(const hash256 &other) const;\n\n    /**\n     * Cast to internal type.\n     * @return  This object's value cast to internal type.\n     */\n    operator const hash_digest &() const;\n\n    /**\n     * Define stream in. Throws if input is invalid.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    hash256 &argument);\n\n    /**\n     * Define stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const hash256 &argument);\n\n  private:\n    hash_digest value_;\n};\n\n} // namespace config\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/config/parameter.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CONFIG_PARAMETER_HPP\n#define UC_CONFIG_PARAMETER_HPP\n\n#include <string>\n#include <utility>\n#include <vector>\n#include <boost/program_options.hpp>\n#include <UChain/coin/define.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace config\n{\n\n/**\n * Shorthand for property declarations in parameter class.\n */\n#define BC_PROPERTY(type, name)                              \\\n  public:                                                    \\\n    virtual type get_##name() const { return name##_; }      \\\n                                                             \\\n  public:                                                    \\\n    virtual void set_##name(type value) { name##_ = value; } \\\n                                                             \\\n  private:                                                   \\\n    type name##_\n\n/**\n * A tuple to represent a positional argument name count.\n */\ntypedef std::pair<const std::string, int> argument_pair;\n\n/**\n * A type to represent the list of positional argument name counts.\n */\ntypedef std::vector<argument_pair> argument_list;\n\n/**\n * A type to represent a list of parameter structures.\n */\nclass parameter;\ntypedef std::vector<parameter> parameter_list;\n\n/**\n * Normalized storage for command line arguments and options.\n * TEST: option_metadata does not provide virtual methods so must wrap to mock.\n */\nclass BC_API parameter\n{\n  private:\n    /**\n     * Enumerated options for selecting the canonical name.\n     */\n    enum search_options : int\n    {\n        /** --name/-n */\n        dashed_both_prefer_long = 1,\n\n        /** name/-n */\n        dashed_short_prefer_long = 2,\n\n        /** -n/name */\n        dashed_short_prefer_short = 4\n    };\n\n  public:\n    /**\n     * Sentinel - the option is not a positional argument.\n     */\n    static const int not_positional;\n\n    /**\n     * Sentinel - there is no short name.\n     */\n    static const char no_short_name;\n\n    /**\n     * The character used to prefix command line options.\n     */\n    static const char option_prefix_char;\n\n    /**\n     * Populate with normalized parameter data.\n     * @param[in]  option     The metadata of the option to test.\n     * @param[in]  arguments  The list of supported positional arguments.\n     */\n    virtual void initialize(\n        const boost::program_options::option_description &option,\n        const argument_list &arguments);\n\n    /**\n     * Determine if the option is an argument by testing for it by name in the\n     * positional options collection and if so return the position.\n     * @param[in]  option     The metadata of the option to position.\n     * @param[in]  arguments  The list of supported positional arguments.\n     * @return                Relative position or -1 if not positional.\n     */\n    virtual int position(\n        const boost::program_options::option_description &option,\n        const argument_list &arguments) const;\n\n    /**\n     * Get the value for the args_limit property.\n     * @param[in]  position   The option's position (or -1 of arg).\n     * @param[in]  option     The option.\n     * @param[in]  arguments  The argument names list.\n     * @return                The arguments limit value for the option.\n     */\n    unsigned arguments_limit(int position,\n                             const boost::program_options::option_description &option,\n                             const argument_list &arguments) const;\n\n    /**\n     * Get the option's short name character or zero.\n     * @param[in]  option  The metadata of the option to test.\n     * @return             The short name character or null character.\n     */\n    virtual char short_name(\n        const boost::program_options::option_description &option) const;\n\n    /**\n     * Virtual property declarations.\n     */\n    BC_PROPERTY(int, position);\n    BC_PROPERTY(bool, required);\n    BC_PROPERTY(char, short_name);\n    BC_PROPERTY(unsigned, args_limit);\n    BC_PROPERTY(std::string, long_name);\n    BC_PROPERTY(std::string, description);\n    BC_PROPERTY(std::string, format_name);\n    BC_PROPERTY(std::string, format_parameter);\n};\n\n#undef BC_PROPERTY\n\n} // namespace config\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/config/parser.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CONFIG_PARSER_HPP\n#define UC_CONFIG_PARSER_HPP\n\n#include <string>\n#include <boost/filesystem.hpp>\n#include <boost/program_options.hpp>\n#include <UChain/coin/define.hpp>\n\nnamespace libbitcoin\n{\n\n// These are just annoyingly long.\ntypedef boost::program_options::variables_map variables_map;\ntypedef boost::program_options::option_description option_metadata;\ntypedef boost::program_options::options_description options_metadata;\ntypedef boost::program_options::positional_options_description\n    arguments_metadata;\n\nnamespace config\n{\n\n/// Parse configurable values from environment variables, settings file, and\n/// command line positional and non-positional options.\nclass BC_API parser\n{\n  public:\n    static std::string format_invalid_parameter(const std::string &message);\n    static bool get_option(variables_map &variables, const std::string &name);\n    static boost::filesystem::path get_config_option(variables_map &variables,\n                                                     const std::string &name);\n\n    /// Load command line options (named).\n    virtual options_metadata load_options() = 0;\n\n    /// Load command line arguments (positional).\n    virtual arguments_metadata load_arguments() = 0;\n\n    /// Load environment variable settings.\n    virtual options_metadata load_environment() = 0;\n\n    /// Load configuration file settings.\n    virtual options_metadata load_settings() = 0;\n\n  protected:\n    virtual void load_command_variables(variables_map &variables,\n                                        int argc, const char *argv[]);\n\n    virtual bool load_configuration_variables(variables_map &variables,\n                                              const std::string &option_name);\n\n    virtual void load_environment_variables(variables_map &variables,\n                                            const std::string &prefix);\n};\n\n} // namespace config\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/config/printer.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CONFIG_PRINTER_HPP\n#define UC_CONFIG_PRINTER_HPP\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <boost/format.hpp>\n#include <boost/program_options.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/config/parameter.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace config\n{\n\n/**\n * Shorthand for property declarations in printer class.\n */\n#define BC_PROPERTY_GET_REF(type, name)            \\\n  public:                                          \\\n    virtual type &get_##name() { return name##_; } \\\n                                                   \\\n  private:                                         \\\n    type name##_\n\n/**\n * Class for managing the serialization of command line options and arguments.\n */\nclass BC_API printer\n{\n  public:\n    /**\n     * Number of arguments above which the argument is considered unlimited.\n     */\n    BC_API static const int max_arguments;\n\n    /**\n     * Construct an instance of the printer class.\n     * @param[in]  settings     Populated config file settings metadata.\n     * @param[in]  application  This application (e.g. 'bitcoin_server').\n     * @param[in]  description  This application description (e.g. 'Server').\n     */\n    printer(const boost::program_options::options_description &settings,\n            const std::string &application, const std::string &description = \"\");\n\n    /**\n     * Construct an instance of the printer class.\n     * @param[in]  options      Populated command line options metadata.\n     * @param[in]  arguments    Populated command line arguments metadata.\n     * @param[in]  application  This application (e.g. 'bx').\n     * @param[in]  description  This command description (e.g. 'Convert BTC').\n     * @param[in]  command      This command (e.g. 'btc').\n     */\n    printer(const boost::program_options::options_description &options,\n            const boost::program_options::positional_options_description &arguments,\n            const std::string &application, const std::string &description = \"\",\n            const std::string &command = \"\");\n\n    /**\n     * Convert a paragraph of text into a column.\n     * This formats to 80 char width as: [ 23 | ' ' | 55 | '\\n' ].\n     * If one word exceeds width it will cause a column overflow.\n     * This always sets at least one line and always collapses whitespace.\n     * @param[in]  paragraph  The paragraph to columnize.\n     * @return                The column, as a list of fragments.\n     */\n    virtual std::vector<std::string> columnize(const std::string &paragraph,\n                                               size_t width);\n\n    /**\n     * Format the command description.\n     * @return  The command description.\n     */\n    virtual std::string format_description();\n\n    /**\n     * Format the parameters table.\n     * @param[in]  positional  True for positional otherwize named.\n     * @return                 The formatted help arguments table.\n     */\n    virtual std::string format_parameters_table(bool positional);\n\n    /**\n     * Format the settings table.\n     * @return  The formatted settings table.\n     */\n    virtual std::string format_settings_table();\n\n    /**\n     * Format a paragraph.\n     * @param[in]  paragraph  The text to format.\n     * @return                The formatted paragraph.\n     */\n    virtual std::string format_paragraph(const std::string &paragraph);\n\n    /**\n     * Format the command line usage.\n     * @return  The formatted usage.\n     */\n    virtual std::string format_usage();\n\n    /**\n     * Format the command line parameters.\n     * @return  The formatted command line parameters.\n     */\n    virtual std::string format_usage_parameters();\n\n    /**\n     * Build the list of argument name/count tuples.\n     */\n    virtual void generate_argument_names();\n\n    /**\n     * Build the list of parameters.\n     */\n    virtual void generate_parameters();\n\n    /**\n     * Parse the arguments and options into the normalized parameter list.\n     */\n    virtual void initialize();\n\n    /**\n     * Serialize command line help (full details).\n     * @param[out] output  Stream that is sink for output.\n     */\n    virtual void commandline(std::ostream &output);\n\n    /**\n     * Serialize as config settings (full details).\n     * @param[out] output  Stream that is sink for output.\n     */\n    virtual void settings(std::ostream &output);\n\n    /**\n     * Virtual property declarations, passed on construct.\n     */\n    BC_PROPERTY_GET_REF(boost::program_options::options_description, options);\n    BC_PROPERTY_GET_REF(boost::program_options::positional_options_description, arguments);\n    BC_PROPERTY_GET_REF(std::string, application);\n    BC_PROPERTY_GET_REF(std::string, description);\n    BC_PROPERTY_GET_REF(std::string, command);\n\n    /**\n     * Virtual property declarations, generated from metadata.\n     */\n    BC_PROPERTY_GET_REF(argument_list, argument_names);\n    BC_PROPERTY_GET_REF(parameter_list, parameters);\n};\n\n#undef PROPERTY_GET_REF\n\n} // namespace config\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/config/sodium.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CONFIG_SODIUM_HPP\n#define UC_CONFIG_SODIUM_HPP\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/math/hash.hpp>\n\nnamespace libbitcoin\n{\nnamespace config\n{\n\n/**\n * Serialization helper for base58 sodium keys.\n */\nclass BC_API sodium\n{\n  public:\n    /**\n     * A list of base85 values.\n     * This must provide operator<< for ostream in order to be used as a\n     * boost::program_options default_value.\n     */\n    typedef std::vector<sodium> list;\n\n    /**\n     * Default constructor.\n     */\n    sodium();\n\n    /**\n     * Initialization constructor.\n     * @param[in]  base85  The value to initialize with.\n     */\n    sodium(const std::string &base85);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  value  The value to initialize with.\n     */\n    sodium(const hash_digest &value);\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    sodium(const sodium &other);\n\n    /**\n     * Getter.\n     * @return True if the key is initialized.\n     */\n    operator bool() const;\n\n    /**\n     * Overload cast to internal type.\n     * @return  This object's value cast to internal type.\n     * -\n     */\n    operator hash_digest() const;\n\n    /**\n     * Overload cast to generic data reference.\n     * @return  This object's value cast to generic data.\n     */\n    operator data_slice() const;\n\n    /**\n     * Get the key as a base85 encoded (z85) string.\n     * @return The encoded key.\n     */\n    std::string to_string() const;\n\n    /**\n     * Overload stream in. Throws if input is invalid.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    sodium &argument);\n\n    /**\n     * Overload stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const sodium &argument);\n\n  private:\n    /**\n     * The state of this object.\n     */\n    hash_digest value_;\n};\n\n} // namespace config\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/constants.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CONSTANTS_HPP\n#define UC_CONSTANTS_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <UChain/coin/compat.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/message/network_address.hpp>\n#include <UChain/coin/math/hash_number.hpp>\n\nnamespace libbitcoin\n{\n\n#define BC_USER_AGENT \"/UChain:\" UC_VERSION \"/\"\n\n#define UC_BLOCK_TOKEN_SYMBOL \"BLOCK\"\n#define UC_VOTE_TOKEN_SYMBOL \"VOTE\"\n\n#define UC_REWARD_POOL_UID_SYMBOL \"reward_pool\"\n#define UC_BLACKHOLE_UID_SYMBOL \"BLACKHOLE\"\n#define UC_REWARD_POOL_CANDIDATE_SYMBOL \"reward_pool_miner\"\n\n#define VOTE_LOCKED_TIME 345600\n#define TIMES_QUANTITY_TO_VALUE 5E6\n// Generic constants.\n\nBC_CONSTEXPR size_t command_size = 12;\n\nBC_CONSTEXPR int64_t min_int64 = MIN_INT64;\nBC_CONSTEXPR int64_t max_int64 = MAX_INT64;\nBC_CONSTEXPR int32_t min_int32 = MIN_INT32;\nBC_CONSTEXPR int32_t max_int32 = MAX_INT32;\nBC_CONSTEXPR uint64_t max_uint64 = MAX_UINT64;\nBC_CONSTEXPR uint32_t max_uint32 = MAX_UINT32;\nBC_CONSTEXPR uint16_t max_uint16 = MAX_UINT16;\nBC_CONSTEXPR uint8_t max_uint8 = MAX_UINT8;\nBC_CONSTEXPR uint64_t max_size_t = BC_MAX_SIZE;\nBC_CONSTEXPR uint8_t byte_bits = 8;\n\n// Consensus constants.\nBC_CONSTEXPR uint32_t reward_interval = 210000;\nextern uint32_t coinbase_maturity;\nBC_CONSTEXPR uint32_t initial_block_reward = 50;\nBC_CONSTEXPR uint32_t max_work_bits = 0x1d00ffff;\nBC_CONSTEXPR uint32_t max_input_sequence = max_uint32;\n\nBC_CONSTEXPR uint32_t total_reward = 820000000;\n\nBC_CONSTEXPR uint64_t min_fee_to_issue_token = 10000 * 100000000LL;\nBC_CONSTEXPR uint64_t min_lock_to_issue_candidate = 500000 * 100000000LL;\nBC_CONSTEXPR uint64_t min_fee_to_register_uid = 100 * 100000000LL;\nBC_CONSTEXPR uint32_t min_fee_percentage_to_miner = 20;\nBC_CONSTEXPR uint64_t min_tx_fee = 200000;\n\nBC_CONSTEXPR uint64_t mine_block_produce_minsecons = 500;\nBC_CONSTEXPR uint64_t mine_fetch_utxo_height_windows = 10000;\n// The window by which a time stamp may exceed our current time (2 hours).\nBC_CONSTEXPR uint64_t time_stamp_window_senconds = 2;\n\n// Threshold for nLockTime: below this value it is interpreted as block number,\n// otherwise as UNIX timestamp. [Tue Nov 5 00:53:20 1985 UTC]\nBC_CONSTEXPR uint32_t locktime_threshold = 500000000;\n\nBC_CONSTFUNC uint64_t max_money_recursive(uint64_t current)\n{\n    return (current > 0) ? current + max_money_recursive(current >> 1) : 0;\n}\n\nBC_CONSTFUNC uint64_t coin_price(uint64_t value = 1)\n{\n    return value * 100000000;\n}\n\nBC_CONSTFUNC uint64_t max_money()\n{\n    return coin_price(total_reward);\n}\n\n// For configuration settings initialization.\nenum class settings\n{\n    none,\n    mainnet,\n    testnet\n};\n\nenum services : uint64_t\n{\n    // The node is capable of serving the block chain.\n    node_network = (1 << 0),\n\n    // Requires version >= 70004 (bip64)\n    // The node is capable of responding to the getutxo protocol request.\n    node_utxo = (1 << 1),\n\n    // Requires version >= 70011 (proposed)\n    // The node is capable and willing to handle bloom-filtered connections.\n    bloom_filters = (1 << 2)\n};\n\nBC_CONSTEXPR uint32_t no_timestamp = 0;\nBC_CONSTEXPR uint16_t unspecified_ip_port = 0;\nBC_CONSTEXPR message::ip_address unspecified_ip_address{\n    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n     0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}};\nBC_CONSTEXPR message::network_address unspecified_network_address{\n    no_timestamp,\n    services::node_network,\n    unspecified_ip_address,\n    unspecified_ip_port};\n\n// TODO: make static.\nBC_API hash_number max_target();\n\nBC_API std::string get_developer_community_address(bool is_testnet);\n\nBC_API std::string get_foundation_address(bool is_testnet);\n\nBC_API std::string get_reward_pool_address(bool is_testnet);\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/define.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DEFINE_HPP\n#define UC_DEFINE_HPP\n\n// Create bc namespace alias.\nnamespace libbitcoin\n{\n} // namespace libbitcoin\n\nnamespace bc = libbitcoin;\nnamespace uc = libbitcoin; // for uc\n\n// See http://gcc.gnu.org/wiki/Visibility\n\n// Generic helper definitions for shared library support\n#if defined _MSC_VER || defined __CYGWIN__\n#define BC_HELPER_DLL_IMPORT __declspec(dllimport)\n#define BC_HELPER_DLL_EXPORT __declspec(dllexport)\n#define BC_HELPER_DLL_LOCAL\n#else\n#if __GNUC__ >= 4\n#define BC_HELPER_DLL_IMPORT __attribute__((visibility(\"default\")))\n#define BC_HELPER_DLL_EXPORT __attribute__((visibility(\"default\")))\n#define BC_HELPER_DLL_LOCAL __attribute__((visibility(\"internal\")))\n#else\n#define BC_HELPER_DLL_IMPORT\n#define BC_HELPER_DLL_EXPORT\n#define BC_HELPER_DLL_LOCAL\n#endif\n#endif\n\n// Now we use the generic helper definitions above to define BC_API\n// and BC_INTERNAL. BC_API is used for the public API symbols. It either DLL\n// imports or DLL exports (or does nothing for static build) BC_INTERNAL is\n// used for non-api symbols.\n\n#if defined BC_STATIC\n#define BC_API\n#define BC_INTERNAL\n#elif defined BC_DLL\n#define BC_API BC_HELPER_DLL_EXPORT\n#define BC_INTERNAL BC_HELPER_DLL_LOCAL\n#else\n#define BC_API BC_HELPER_DLL_IMPORT\n#define BC_INTERNAL BC_HELPER_DLL_LOCAL\n#endif\n\n// Tag to deprecate functions and methods.\n// Gives a compiler warning when they are used.\n#if defined _MSC_VER || defined __CYGWIN__\n#define BC_DEPRECATED __declspec(deprecated)\n#else\n#if __GNUC__ >= 4\n#define BC_DEPRECATED __attribute__((deprecated))\n#else\n#define BC_DEPRECATED\n#endif\n#endif\n\n// Log name.\n#define LOG_SYSTEM \"system\"\n\n// Avoid namespace conflict between boost::placeholders and std::placeholders.\n#define BOOST_BIND_NO_PLACEHOLDERS\n\n// Define so we can have better visibility of lcov exclusion ranges.\n#define LCOV_EXCL_START(text)\n#define LCOV_EXCL_STOP()\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/error.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_ERROR_HPP\n#define UC_ERROR_HPP\n\n#include <string>\n#include <system_error>\n#include <boost/system/error_code.hpp>\n#include <UChain/coin/define.hpp>\n\nnamespace libbitcoin\n{\n\n/// Console result codes, positive values are domain-specific.\nenum console_result : int\n{\n    failure = -1,\n    okay = 0,\n    invalid = 1,\n    cmd_output = 2\n};\n\n/// Alias for error code declarations.\ntypedef std::error_code code;\n\n/// Alias for boost error code declarations.\ntypedef boost::system::error_code boost_code;\n\nnamespace error\n{\n\n// The numeric values of these codes may change without notice.\nenum error_code_t\n{\n    success = 0,\n\n    // network errors\n    service_stopped, // 1\n    operation_failed,\n\n    // blockchain errors\n    not_found,\n    duplicate,\n    unspent_output, // 5\n    unsupported_script_pattern,\n\n    // network errors (more)\n    resolve_failed,\n    network_unreachable,\n    address_in_use,\n    listen_failed, // 10\n    accept_failed,\n    bad_stream,\n    channel_timeout,\n\n    // transaction pool\n    blockchain_reorganized,\n    pool_filled, // 15\n\n    // validate tx\n    coinbase_transaction,\n    is_not_standard,\n    double_spend,\n    input_not_found,\n    invalid_input_script_lock_height, // 20\n    invalid_output_script_lock_height,\n\n    // check_transaction()\n    empty_transaction,\n    output_value_overflow,\n    invalid_coinbase_script_size,\n    previous_output_null, // 25\n    script_not_standard,\n    transaction_version_error,\n\n    // validate block\n    previous_block_invalid,\n\n    // check_block()\n    size_limits,\n    proof_of_work, // 30\n    futuristic_timestamp,\n    first_not_coinbase,\n    extra_coinbases,\n    too_many_sigs,\n    merkle_mismatch, // 35\n\n    // accept_block()\n    incorrect_proof_of_work,\n    timestamp_too_early,\n    non_final_transaction,\n    checkpoints_failed,\n    old_version_block, // 40\n    coinbase_height_mismatch,\n\n    // connect_block()\n    duplicate_or_spent,\n    validate_inputs_failed,\n    fees_out_of_range,\n    coinbase_too_large, // 45\n    invalid_coinage_reward_coinbase,\n    invalid_quantity_or_value,\n\n    // file system errors\n    file_system,\n\n    // unknown errors\n    unknown,\n\n    // network errors (more)\n    address_blocked,\n    channel_stopped, // 50\n    not_satisfied,\n    mock,\n\n    // token check\n    token_amount_overflow,\n    token_amount_not_equal,\n    token_symbol_not_match, // 55\n    token_symbol_invalid,\n    token_address_not_match,\n    token_exist,\n    token_not_exist,\n    token_issue_error, // 60\n    token_secondaryissue_error,\n    token_secondaryissue_share_not_enough,\n    token_secondaryissue_threshold_invalid,\n\n    //syn block\n    fetch_more_block,\n    bad_magic, // 65\n\n    // uid check\n    uid_symbol_not_match,\n    uid_symbol_invalid,\n    uid_exist,\n    address_registered_uid, // 70\n    uid_func_not_actived,\n    uid_address_not_match,\n    uid_address_needed,\n    uid_not_exist,\n    uid_multi_type_exist,\n    uid_input_error, // 75\n    uid_in_candidate,\n    attenuation_model_param_error,\n\n    // cert check\n    token_cert_error,\n    token_cert_exist,\n    token_cert_not_exist,\n    token_cert_not_owned, // 80\n    token_cert_not_provided,\n    token_cert_issue_error,\n    token_uid_registerr_not_match,\n\n    asset_invalid,\n    uid_feature_not_activated, // 85\n\n    // identifier token\n    candidate_error,\n    candidate_exist,\n    candidate_register_error,\n    candidate_symbol_invalid,\n    candidate_not_exist,\n\n    //block ext\n    first_coinbase_index_error\n};\n\nenum error_condition_t\n{\n    //// validate\n    //validate_failed = 1,\n    //forced_removal\n};\n\nBC_API code make_error_code(error_code_t e);\nBC_API std::error_condition make_error_condition(error_condition_t e);\nBC_API error_code_t boost_to_error_code(const boost_code &ec);\n\n} // namespace error\n} // namespace libbitcoin\n\nnamespace std\n{\n\ntemplate <>\nstruct is_error_code_enum<bc::error::error_code_t>\n    : public true_type\n{\n};\n\ntemplate <>\nstruct is_error_condition_enum<bc::error::error_condition_t>\n    : public true_type\n{\n};\n\n} // namespace std\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/formats/base_10.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_BASE_10_HPP\n#define UC_BASE_10_HPP\n\n#include <cstdint>\n#include <string>\n#include <UChain/coin/compat.hpp>\n#include <UChain/coin/define.hpp>\n\nnamespace libbitcoin\n{\n\nBC_CONSTEXPR uint8_t btc_decimal_places = 8;\nBC_CONSTEXPR uint8_t mbtc_decimal_places = 5;\nBC_CONSTEXPR uint8_t ubtc_decimal_places = 2;\n\n/**\n * Validates and parses an amount string according to the BIP 21 grammar.\n * @param decmial_places the location of the decimal point.\n * The default is 0, which treats the input as a normal integer.\n * @param strict true to treat fractional results as an error,\n * or false to round them upwards.\n * @return false for failure.\n */\nBC_API bool decode_base10(uint64_t &out, const std::string &amount,\n                          uint8_t decimal_places = 0, bool strict = true);\n\n/**\n * Writes a Bitcoin amount to a string, following the BIP 21 grammar.\n * Avoids the rounding issues often seen with floating-point methods.\n * @param decmial_places the location of the decimal point.\n * The default is 0, which treats the input as a normal integer.\n */\nBC_API std::string encode_base10(uint64_t amount,\n                                 uint8_t decimal_places = 0);\n\n// Old names:\nBC_API bool btc_to_satoshi(uint64_t &satoshi, const std::string &btc);\nBC_API std::string satoshi_to_btc(uint64_t satoshi);\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/formats/base_16.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_BASE_16_HPP\n#define UC_BASE_16_HPP\n\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/hash.hpp>\n\nnamespace libbitcoin\n{\n\n/**\n * Returns true if a character is a hexadecimal digit.\n * The C standard library function `isxdigit` depends on the current locale,\n * and does not necessarily match the base16 encoding.\n */\nbool is_base16(const char c);\n\n/**\n * Convert data into a user-readable hex string.\n */\nBC_API std::string encode_base16(data_slice data);\n\n/**\n * Convert a hex string into bytes.\n * @return false if the input is malformed.\n */\nBC_API bool decode_base16(data_chunk &out, const std::string &in);\n\n/**\n * Converts a hex string to a number of bytes.\n * @return false if the input is malformed, or the wrong length.\n */\ntemplate <size_t Size>\nbool decode_base16(byte_array<Size> &out, const std::string &in);\n\n/**\n * Converts a hex string literal to a data array.\n * This would be better as a C++11 user-defined literal,\n * but MSVC doesn't support those.\n */\ntemplate <size_t Size>\nbyte_array<(Size - 1) / 2> base16_literal(const char (&string)[Size]);\n\n/**\n * Converts a bitcoin_hash to a string.\n * The bitcoin_hash format is like base16, but with the bytes reversed.\n */\nBC_API std::string encode_hash(hash_digest hash);\n\n/**\n * Convert a string into a bitcoin_hash.\n * The bitcoin_hash format is like base16, but with the bytes reversed.\n * @return false if the input is malformed.\n */\nBC_API bool decode_hash(hash_digest &out, const std::string &in);\n\n/**\n * Convert a hex string literal into a bitcoin_hash.\n * The bitcoin_hash format is like base16, but with the bytes reversed.\n */\nBC_API hash_digest hash_literal(const char (&string)[2 * hash_size + 1]);\n\n} // namespace libbitcoin\n\n#include <UChain/coin/impl/formats/base_16.ipp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/formats/base_58.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_BASE_58_HPP\n#define UC_BASE_58_HPP\n\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\n\nBC_API bool is_base58(const char ch);\nBC_API bool is_base58(const std::string &text);\n\n/**\n * Converts a base58 string to a number of bytes.\n * @return false if the input is malformed, or the wrong length.\n */\ntemplate <size_t Size>\nbool decode_base58(byte_array<Size> &out, const std::string &in);\n\n/**\n * Converts a base58 string literal to a data array.\n * This would be better as a C++11 user-defined literal,\n * but MSVC doesn't support those.\n * TODO: determine if the sizing function is always accurate.\n */\ntemplate <size_t Size>\nbyte_array<Size * 733 / 1000> base58_literal(const char (&string)[Size]);\n\n/**\n * Encode data as base58.\n * @return the base58 encoded string.\n */\nBC_API std::string encode_base58(data_slice unencoded);\n\n/**\n * Attempt to decode base58 data.\n * @return false if the input contains non-base58 characters.\n */\nBC_API bool decode_base58(data_chunk &out, const std::string &in);\n\n} // namespace libbitcoin\n\n#include <UChain/coin/impl/formats/base_58.ipp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/formats/base_64.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_BASE_64_HPP\n#define UC_BASE_64_HPP\n\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\n\n/**\n * Encode data as base64.\n * @return the base64 encoded string.\n */\nBC_API std::string encode_base64(data_slice unencoded);\n\n/**\n * Attempt to decode base64 data.\n * @return false if the input contains non-base64 characters.\n */\nBC_API bool decode_base64(data_chunk &out, const std::string &in);\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/formats/base_85.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_BASE_85_HPP\n#define UC_BASE_85_HPP\n\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\n\n/**\n * Encode data as base85 (Z85).\n * @return false if the input is not of base85 size (% 4).\n */\nBC_API bool encode_base85(std::string &out, data_slice in);\n\n/**\n * Attempt to decode base85 (Z85) data.\n * @return false if the input contains non-base85 characters or length (% 5).\n */\nBC_API bool decode_base85(data_chunk &out, const std::string &in);\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/handlers.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_HANDLERS_HPP\n#define UC_HANDLERS_HPP\n\n#include <functional>\n#include <UChain/coin/error.hpp>\n\nnamespace libbitcoin\n{\n\ntypedef std::function<void(const code &)> handle0;\n\ntemplate <typename Type>\nusing handle1 = std::function<void(const code &, const Type &)>;\n\ntemplate <typename Type1, typename Type2>\nusing handle2 = std::function<void(const code &, const Type1 &,\n                                   const Type2 &)>;\n\ntemplate <typename Type1, typename Type2, typename Type3>\nusing handle3 = std::function<void(const code &, const Type1 &,\n                                   const Type2 &, const Type3 &)>;\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/impl/formats/base_16.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_BASE_16_IPP\n#define UC_BASE_16_IPP\n\n#include <UChain/coin/utility/assert.hpp>\n\nnamespace libbitcoin\n{\n\n// For template implementation only, do not call directly.\nBC_API bool decode_base16_private(uint8_t *out, size_t out_size,\n                                  const char *in);\n\ntemplate <size_t Size>\nbool decode_base16(byte_array<Size> &out, const std::string &in)\n{\n    if (in.size() != 2 * Size)\n        return false;\n\n    byte_array<Size> result;\n    if (!decode_base16_private(result.data(), result.size(), in.data()))\n        return false;\n\n    out = result;\n    return true;\n}\n\ntemplate <size_t Size>\nbyte_array<(Size - 1) / 2> base16_literal(const char (&string)[Size])\n{\n    byte_array<(Size - 1) / 2> out;\n    DEBUG_ONLY(const auto success =)\n    decode_base16_private(out.data(),\n                          out.size(), string);\n    BITCOIN_ASSERT(success);\n    return out;\n}\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/impl/formats/base_58.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_BASE_58_IPP\n#define UC_BASE_58_IPP\n\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\n\n// For support of template implementation only, do not call directly.\nBC_API bool decode_base58_private(uint8_t *out, size_t out_size,\n                                  const char *in);\n\ntemplate <size_t Size>\nbool decode_base58(byte_array<Size> &out, const std::string &in)\n{\n    byte_array<Size> result;\n    if (!decode_base58_private(result.data(), result.size(), in.data()))\n        return false;\n\n    out = result;\n    return true;\n}\n\n// TODO: determine if the sizing function is always accurate.\ntemplate <size_t Size>\nbyte_array<Size * 733 / 1000> base58_literal(const char (&string)[Size])\n{\n    // log(58) / log(256), rounded up.\n    byte_array<Size * 733 / 1000> out;\n    DEBUG_ONLY(const auto success =)\n    decode_base58_private(out.data(),\n                          out.size(), string);\n    BITCOIN_ASSERT(success);\n    return out;\n}\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/impl/math/checksum.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHECKSUM_IPP\n#define UC_CHECKSUM_IPP\n\n#include <algorithm>\n#include <cstddef>\n#include <initializer_list>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/endian.hpp>\n\nnamespace libbitcoin\n{\n\ntemplate <size_t Size>\nbool build_checked_array(byte_array<Size> &out,\n                         const std::initializer_list<data_slice> &slices)\n{\n    return build_array(out, slices) && insert_checksum(out);\n}\n\ntemplate <size_t Size>\nbool insert_checksum(byte_array<Size> &out)\n{\n    if (out.size() < checksum_size)\n        return false;\n\n    data_chunk body(out.begin(), out.end() - checksum_size);\n    const auto checksum = to_little_endian(bitcoin_checksum(body));\n    std::copy(checksum.begin(), checksum.end(), out.end() - checksum_size);\n    return true;\n}\n\n// std::array<> is used in place of byte_array<> to enable Size deduction.\ntemplate <size_t Size>\nbool unwrap(uint8_t &out_version,\n            std::array<uint8_t, UNWRAP_SIZE(Size)> &out_payload,\n            const std::array<uint8_t, Size> &wrapped)\n{\n    uint32_t unused;\n    return unwrap(out_version, out_payload, unused, wrapped);\n}\n\n// std::array<> is used in place of byte_array<> to enable Size deduction.\ntemplate <size_t Size>\nbool unwrap(uint8_t &out_version,\n            std::array<uint8_t, UNWRAP_SIZE(Size)> &out_payload,\n            uint32_t &out_checksum, const std::array<uint8_t, Size> &wrapped)\n{\n    if (!verify_checksum(wrapped))\n        return false;\n\n    out_version = slice<0, 1>(wrapped)[0];\n    out_payload = slice<1, Size - checksum_size>(wrapped);\n    const auto bytes = slice<Size - checksum_size, Size>(wrapped);\n    out_checksum = from_little_endian_unsafe<uint32_t>(bytes.begin());\n    return true;\n}\n\n// std::array<> is used in place of byte_array<> to enable Size deduction.\ntemplate <size_t Size>\nstd::array<uint8_t, WRAP_SIZE(Size)> wrap(uint8_t version,\n                                          const std::array<uint8_t, Size> &payload)\n{\n    byte_array<WRAP_SIZE(Size)> out;\n    build_array(out, {to_array(version), payload});\n    insert_checksum(out);\n    return out;\n}\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/impl/math/hash.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_HASH_IPP\n#define UC_HASH_IPP\n\n#include <algorithm>\n#include <cstddef>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\n\ntemplate <size_t Size>\nbyte_array<Size> scrypt(data_slice data, data_slice salt, uint64_t N,\n                        uint32_t p, uint32_t r)\n{\n    const auto out = scrypt(data, salt, N, r, p, Size);\n    return to_array<Size>({out});\n}\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/impl/utility/array_slice.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_ARRAY_SLICE_IPP\n#define UC_ARRAY_SLICE_IPP\n\nnamespace libbitcoin\n{\n\ntemplate <typename T>\ntemplate <typename Container>\narray_slice<T>::array_slice(const Container &container)\n    : begin_(container.data()), end_(container.data() + container.size())\n{\n}\n\ntemplate <typename T>\narray_slice<T>::array_slice(const T *begin, const T *end)\n    : begin_(begin), end_(end)\n{\n}\n\ntemplate <typename T>\nconst T *array_slice<T>::begin() const\n{\n    return begin_;\n}\n\ntemplate <typename T>\nconst T *array_slice<T>::end() const\n{\n    return end_;\n}\n\ntemplate <typename T>\nconst T *array_slice<T>::data() const\n{\n    return begin_;\n}\n\ntemplate <typename T>\nstd::size_t array_slice<T>::size() const\n{\n    return end_ - begin_;\n}\n\ntemplate <typename T>\nbool array_slice<T>::empty() const\n{\n    return end_ == begin_;\n}\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/impl/utility/collection.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_COLLECTION_IPP\n#define UC_COLLECTION_IPP\n\n#include <algorithm>\n#include <iterator>\n#include <cstddef>\n#include <iterator>\n#include <iostream>\n#include <vector>\n\nnamespace libbitcoin\n{\n\ntemplate <typename Source, typename Target>\nstd::vector<Target> cast(const std::vector<Source> &source)\n{\n    std::vector<Target> target(source.size());\n    target.assign(source.begin(), source.end());\n    return target;\n}\n\ntemplate <typename Pair, typename Key>\nint find_pair_position(const std::vector<Pair> &list, const Key &key)\n{\n    const auto predicate = [&](const Pair &pair) {\n        return pair.first == key;\n    };\n\n    auto it = std::find_if(list.begin(), list.end(), predicate);\n\n    if (it == list.end())\n        return -1;\n\n    return static_cast<int>(distance(list.begin(), it));\n}\n\ntemplate <typename Element, typename Container>\nint find_position(const Container &list, const Element &value)\n{\n    const auto it = std::find(std::begin(list), std::end(list), value);\n\n    if (it == std::end(list))\n        return -1;\n\n    return static_cast<int>(std::distance(list.begin(), it));\n}\n\ntemplate <typename Type, typename Predicate>\ntypename std::vector<Type>::iterator insert_sorted(std::vector<Type> &list,\n                                                   Type &element, Predicate predicate)\n{\n    return list.insert(std::upper_bound(list.begin(), list.end(), element,\n                                        predicate),\n                       element);\n}\n\ntemplate <typename Type>\nvoid move_append(std::vector<Type> &target, std::vector<Type> &source)\n{\n    target.reserve(target.size() + source.size());\n    std::move(source.begin(), source.end(), std::back_inserter(target));\n    source.clear();\n}\n\n////template <typename Collection>\n////Collection reverse(const Collection& list)\n////{\n////    Collection out(list.size());\n////    std::reverse_copy(list.begin(), list.end(), out.begin());\n////    return out;\n////}\n\n} // namespace libbitcoin\n\nnamespace std\n{\n\ntemplate <class Type>\nstd::ostream &operator<<(std::ostream &output, const std::vector<Type> &list)\n{\n    size_t current = 0;\n    const auto end = list.size();\n\n    for (const auto &element : list)\n    {\n        output << element;\n\n        if (++current < end)\n            output << std::endl;\n    }\n\n    return output;\n}\n\n} // namespace std\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/impl/utility/data.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATA_IPP\n#define UC_DATA_IPP\n\n#include <algorithm>\n#include <cstddef>\n#include <initializer_list>\n#include <UChain/coin/utility/assert.hpp>\n\nnamespace libbitcoin\n{\n\ninline one_byte to_array(uint8_t byte)\n{\n    return byte_array<1>{{byte}};\n}\n\ninline data_chunk to_chunk(uint8_t byte)\n{\n    return data_chunk{byte};\n}\n\ninline data_chunk build_chunk(loaf slices, size_t extra_reserve)\n{\n    size_t size = 0;\n    for (const auto slice : slices)\n        size += slice.size();\n\n    data_chunk out;\n    out.reserve(size + extra_reserve);\n    for (const auto slice : slices)\n        out.insert(out.end(), slice.begin(), slice.end());\n\n    return out;\n}\n\ntemplate <size_t Size>\nbool build_array(byte_array<Size> &out, loaf slices)\n{\n    size_t size = 0;\n    for (const auto slice : slices)\n        size += slice.size();\n\n    if (size > Size)\n        return false;\n\n    auto position = out.begin();\n    for (const auto slice : slices)\n    {\n        std::copy(slice.begin(), slice.end(), position);\n        position += slice.size();\n    }\n\n    return true;\n}\n\ntemplate <class Target, class Extension>\nvoid extend_data(Target &bytes, const Extension &other)\n{\n    bytes.insert(std::end(bytes), std::begin(other), std::end(other));\n}\n\ntemplate <typename Value>\nValue range_constrain(Value value, Value minimum, Value maximum)\n{\n    if (value < minimum)\n        return minimum;\n\n    if (value > maximum)\n        return maximum;\n\n    return value;\n}\n\n// std::array<> is used in place of byte_array<> to enable Size deduction.\ntemplate <size_t Start, size_t End, size_t Size>\nbyte_array<End - Start> slice(const std::array<uint8_t, Size> &bytes)\n{\n    static_assert(End <= Size, \"Slice end must not exceed array size.\");\n    byte_array<End - Start> out;\n    std::copy(std::begin(bytes) + Start, std::begin(bytes) + End, out.begin());\n    return out;\n}\n\ntemplate <size_t Left, size_t Right>\nbyte_array<Left + Right> splice(const std::array<uint8_t, Left> &left,\n                                const std::array<uint8_t, Right> &right)\n{\n    byte_array<Left + Right> out;\n    /* safe to ignore */ build_array<Left + Right>(out, {left, right});\n    return out;\n}\n\ntemplate <size_t Left, size_t Middle, size_t Right>\nbyte_array<Left + Middle + Right> splice(const std::array<uint8_t, Left> &left,\n                                         const std::array<uint8_t, Middle> &middle,\n                                         const std::array<uint8_t, Right> &right)\n{\n    byte_array<Left + Middle + Right> out;\n    /* safe to ignore */ build_array(out, {left, middle, right});\n    return out;\n}\n\ntemplate <size_t Size>\nbyte_array_parts<Size / 2> split(const byte_array<Size> &bytes)\n{\n    static_assert(Size % 2 == 0, \"Split requires an even length parameter.\");\n    static const size_t half = Size / 2;\n    byte_array_parts<half> out;\n    std::copy(std::begin(bytes), std::begin(bytes) + half, out.left.begin());\n    std::copy(std::begin(bytes) + half, std::end(bytes), out.right.begin());\n    return out;\n}\n\n// unsafe\ntemplate <size_t Size>\nbyte_array<Size> to_array(data_slice bytes)\n{\n    byte_array<Size> out;\n    DEBUG_ONLY(const auto result =)\n    build_array(out, {bytes});\n    BITCOIN_ASSERT(result);\n    return out;\n}\n\ntemplate <typename Source>\ndata_chunk to_chunk(const Source &bytes)\n{\n    return data_chunk(std::begin(bytes), std::end(bytes));\n}\n\n// unsafe\ntemplate <size_t Size>\nbyte_array<Size> xor_data(data_slice bytes1, data_slice bytes2)\n{\n    return xor_data<Size>(bytes1, bytes2, 0);\n}\n\n// unsafe\ntemplate <size_t Size>\nbyte_array<Size> xor_data(data_slice bytes1, data_slice bytes2, size_t offset)\n{\n    return xor_data<Size>(bytes1, bytes2, offset, offset);\n}\n\n// unsafe\ntemplate <size_t Size>\nbyte_array<Size> xor_data(data_slice bytes1, data_slice bytes2, size_t offset1,\n                          size_t offset2)\n{\n    BITCOIN_ASSERT(offset1 + Size <= bytes1.size());\n    BITCOIN_ASSERT(offset2 + Size <= bytes2.size());\n    const auto &data1 = bytes1.data();\n    const auto &data2 = bytes2.data();\n    byte_array<Size> out;\n    for (size_t i = 0; i < Size; i++)\n        out[i] = data1[i + offset1] ^ data2[i + offset2];\n\n    return out;\n}\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/impl/utility/deserializer.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DESERIALIZER_IPP\n#define UC_DESERIALIZER_IPP\n\n#include <algorithm>\n#include <cstddef>\n#include <cstdint>\n#include <boost/asio/streambuf.hpp>\n#include <UChain/coin/error.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/endian.hpp>\n#include <UChain/coin/utility/exceptions.hpp>\n\nnamespace libbitcoin\n{\n\n// Macro used so that compiler will optimise out function calls to\n// check_distance() if SafeCheckLast is false.\n#define SAFE_CHECK_DISTANCE(N) \\\n    if (SafeCheckLast)         \\\n        check_distance(iterator_, end_, N);\n\ntemplate <typename Iterator, bool SafeCheckLast>\ndeserializer<Iterator, SafeCheckLast>::deserializer(const Iterator begin,\n                                                    const Iterator end)\n    : iterator_(begin), end_(end)\n{\n}\n\ntemplate <typename Iterator, bool SafeCheckLast>\ndeserializer<Iterator, SafeCheckLast>::operator bool() const\n{\n    return true;\n}\n\ntemplate <typename Iterator, bool SafeCheckLast>\nbool deserializer<Iterator, SafeCheckLast>::operator!() const\n{\n    return false;\n}\n\ntemplate <typename Iterator, bool SafeCheckLast>\nbool deserializer<Iterator, SafeCheckLast>::is_exhausted() const\n{\n    return (iterator_ == end_);\n}\n\ntemplate <typename Iterator, bool SafeCheckLast>\nuint8_t deserializer<Iterator, SafeCheckLast>::read_byte()\n{\n    SAFE_CHECK_DISTANCE(1);\n    return *(iterator_++);\n}\n\ntemplate <typename Iterator, bool SafeCheckLast>\nuint16_t deserializer<Iterator, SafeCheckLast>::read_2_bytes_little_endian()\n{\n    return read_little_endian<uint16_t>();\n}\n\ntemplate <typename Iterator, bool SafeCheckLast>\nuint32_t deserializer<Iterator, SafeCheckLast>::read_4_bytes_little_endian()\n{\n    return read_little_endian<uint32_t>();\n}\n\ntemplate <typename Iterator, bool SafeCheckLast>\nuint64_t deserializer<Iterator, SafeCheckLast>::read_8_bytes_little_endian()\n{\n    return read_little_endian<uint64_t>();\n}\n\ntemplate <typename Iterator, bool SafeCheckLast>\nuint16_t deserializer<Iterator, SafeCheckLast>::read_2_bytes_big_endian()\n{\n    return read_big_endian<uint16_t>();\n}\n\ntemplate <typename Iterator, bool SafeCheckLast>\nuint32_t deserializer<Iterator, SafeCheckLast>::read_4_bytes_big_endian()\n{\n    return read_big_endian<uint32_t>();\n}\n\ntemplate <typename Iterator, bool SafeCheckLast>\nuint64_t deserializer<Iterator, SafeCheckLast>::read_8_bytes_big_endian()\n{\n    return read_big_endian<uint64_t>();\n}\n\ntemplate <typename Iterator, bool SafeCheckLast>\ntemplate <typename T>\nT deserializer<Iterator, SafeCheckLast>::read_big_endian()\n{\n    const auto begin = iterator_;\n    SAFE_CHECK_DISTANCE(sizeof(T));\n    iterator_ += sizeof(T);\n    return from_big_endian_unsafe<T>(begin);\n}\ntemplate <typename Iterator, bool SafeCheckLast>\ntemplate <typename T>\nT deserializer<Iterator, SafeCheckLast>::read_little_endian()\n{\n    const auto begin = iterator_;\n    SAFE_CHECK_DISTANCE(sizeof(T));\n    iterator_ += sizeof(T);\n    return from_little_endian_unsafe<T>(begin);\n}\n\ntemplate <typename Iterator, bool SafeCheckLast>\nuint64_t deserializer<Iterator,\n                      SafeCheckLast>::read_variable_uint_little_endian()\n{\n    const auto length = read_byte();\n    if (length < 0xfd)\n        return length;\n    else if (length == 0xfd)\n        return read_2_bytes_little_endian();\n    else if (length == 0xfe)\n        return read_4_bytes_little_endian();\n\n    // length should be 0xff\n    return read_8_bytes_little_endian();\n}\n\ntemplate <typename Iterator, bool SafeCheckLast>\nuint64_t deserializer<Iterator, SafeCheckLast>::read_variable_uint_big_endian()\n{\n    const auto length = read_byte();\n    if (length < 0xfd)\n        return length;\n    else if (length == 0xfd)\n        return read_2_bytes_big_endian();\n    else if (length == 0xfe)\n        return read_4_bytes_big_endian();\n\n    // length should be 0xff\n    return read_8_bytes_big_endian();\n}\n\ntemplate <typename Iterator, bool SafeCheckLast>\ndata_chunk deserializer<Iterator, SafeCheckLast>::read_data(size_t size)\n{\n    SAFE_CHECK_DISTANCE(size);\n    data_chunk raw_bytes(size);\n    for (size_t i = 0; i < size; ++i)\n        raw_bytes[i] = read_byte();\n\n    return raw_bytes;\n}\n\ntemplate <typename Iterator, bool SafeCheckLast>\nsize_t deserializer<Iterator, SafeCheckLast>::read_data(uint8_t *data,\n                                                        size_t size)\n{\n    SAFE_CHECK_DISTANCE(size);\n    for (size_t i = 0; i < size; ++i)\n        data[i] = read_byte();\n    return size;\n}\n\ntemplate <typename Iterator, bool SafeCheckLast>\ncode deserializer<Iterator, SafeCheckLast>::read_error_code()\n{\n    const auto value = read_little_endian<uint32_t>();\n    return code(static_cast<error::error_code_t>(value));\n}\n\ntemplate <typename Iterator, bool SafeCheckLast>\ndata_chunk deserializer<Iterator, SafeCheckLast>::read_data_to_eof()\n{\n    data_chunk raw_bytes;\n    while (iterator_ != end_)\n        raw_bytes.push_back(read_byte());\n\n    return raw_bytes;\n}\n\ntemplate <typename Iterator, bool SafeCheckLast>\nhash_digest deserializer<Iterator, SafeCheckLast>::read_hash()\n{\n    return read_bytes<hash_size>();\n}\n\ntemplate <typename Iterator, bool SafeCheckLast>\nshort_hash deserializer<Iterator, SafeCheckLast>::read_short_hash()\n{\n    return read_bytes<short_hash_size>();\n}\n\ntemplate <typename Iterator, bool SafeCheckLast>\nmini_hash deserializer<Iterator, SafeCheckLast>::read_mini_hash()\n{\n    return read_bytes<mini_hash_size>();\n}\n\ntemplate <typename Iterator, bool SafeCheckLast>\nstd::string deserializer<Iterator, SafeCheckLast>::read_fixed_string(\n    size_t length)\n{\n    data_chunk string_bytes = read_data(length);\n    std::string result(string_bytes.begin(), string_bytes.end());\n\n    // Removes trailing 0s... Needed for string comparisons\n    return result.c_str();\n}\n\ntemplate <typename Iterator, bool SafeCheckLast>\nstd::string deserializer<Iterator, SafeCheckLast>::read_string()\n{\n    const auto size = read_variable_uint_little_endian();\n\n    // Warning: conversion from uint64_t to size_t, possible loss of data.\n    return read_fixed_string(static_cast<size_t>(size));\n}\n\ntemplate <typename Iterator, bool SafeCheckLast>\ntemplate <unsigned N>\nbyte_array<N> deserializer<Iterator, SafeCheckLast>::read_bytes()\n{\n    SAFE_CHECK_DISTANCE(N);\n    byte_array<N> out;\n    std::copy(iterator_, iterator_ + N, out.begin());\n    iterator_ += N;\n    return out;\n}\n\ntemplate <typename Iterator, bool SafeCheckLast>\ntemplate <unsigned N>\nbyte_array<N> deserializer<Iterator, SafeCheckLast>::read_bytes_reverse()\n{\n    SAFE_CHECK_DISTANCE(N);\n    byte_array<N> out;\n    std::reverse_copy(iterator_, iterator_ + N, out.begin());\n    iterator_ += N;\n    return out;\n}\n\n/**\n * Returns underlying iterator.\n */\ntemplate <typename Iterator, bool SafeCheckLast>\nIterator deserializer<Iterator, SafeCheckLast>::iterator() const\n{\n    return iterator_;\n}\n\n/**\n * Useful if you advance the iterator using other serialization\n * methods or objects.\n */\ntemplate <typename Iterator, bool SafeCheckLast>\nvoid deserializer<Iterator, SafeCheckLast>::set_iterator(\n    const Iterator iterator)\n{\n    iterator_ = iterator;\n}\n\n// Try to advance iterator 'distance' increments forwards.\n// Throw if we prematurely reach the end.\ntemplate <typename Iterator, bool SafeCheckLast>\nvoid deserializer<Iterator, SafeCheckLast>::check_distance(\n    Iterator it, const Iterator end, size_t distance)\n{\n    BITCOIN_ASSERT(SafeCheckLast);\n    for (size_t i = 0; i < distance; ++i)\n    {\n        // Is this a valid byte?\n        if (it == end)\n            throw end_of_stream();\n\n        // If so move to next value.\n        ++it;\n    }\n}\n\n#undef SAFE_CHECK_DISTANCE\n\ntemplate <typename Iterator>\ndeserializer<Iterator, true> make_deserializer(\n    const Iterator begin, const Iterator end)\n{\n    return deserializer<Iterator, true>(begin, end);\n}\n\ntemplate <typename Iterator>\ndeserializer<Iterator, false> make_deserializer_unsafe(\n    const Iterator begin)\n{\n    // end argument isn't used so just reuse begin here.\n    return deserializer<Iterator, false>(begin, begin);\n}\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/impl/utility/endian.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_ENDIAN_IPP\n#define UC_ENDIAN_IPP\n\n#include <type_traits>\n\nnamespace libbitcoin\n{\n\n#define VERIFY_UNSIGNED(T) static_assert(std::is_unsigned<T>::value, \\\n                                         \"The endian functions only work on unsigned types\")\n\ntemplate <typename T, typename Iterator>\nT from_big_endian(Iterator start, const Iterator end)\n{\n    VERIFY_UNSIGNED(T);\n    T out = 0;\n    size_t i = sizeof(T);\n    while (0 < i && start != end)\n        out |= static_cast<T>(*start++) << (8 * --i);\n\n    return out;\n}\n\ntemplate <typename T, typename Iterator>\nT from_little_endian(Iterator start, const Iterator end)\n{\n    VERIFY_UNSIGNED(T);\n    T out = 0;\n    size_t i = 0;\n    while (i < sizeof(T) && start != end)\n        out |= static_cast<T>(*start++) << (8 * i++);\n\n    return out;\n}\n\ntemplate <typename T, typename Iterator>\nT from_big_endian_unsafe(Iterator in)\n{\n    VERIFY_UNSIGNED(T);\n    T out = 0;\n    size_t i = sizeof(T);\n    while (0 < i)\n        out |= static_cast<T>(*in++) << (8 * --i);\n    return out;\n}\n\ntemplate <typename T, typename Iterator>\nT from_little_endian_unsafe(Iterator in)\n{\n    VERIFY_UNSIGNED(T);\n    T out = 0;\n    size_t i = 0;\n    while (i < sizeof(T))\n        out |= static_cast<T>(*in++) << (8 * i++);\n\n    return out;\n}\n\ntemplate <typename T>\nT from_big_endian_stream_unsafe(std::istream &stream)\n{\n    VERIFY_UNSIGNED(T);\n    T out = 0;\n    for (size_t i = sizeof(T); (i > 0) && stream; i--)\n    {\n        uint8_t value = 0;\n        stream.read(reinterpret_cast<char *>(&value), sizeof value);\n        out |= static_cast<T>(value) << (8 * (i - 1));\n    }\n\n    return out;\n}\n\ntemplate <typename T>\nT from_little_endian_stream_unsafe(std::istream &stream)\n{\n    VERIFY_UNSIGNED(T);\n    T out = 0;\n    for (size_t i = 0; (i < sizeof(T)) && stream; i++)\n    {\n        uint8_t value = 0;\n        stream.read(reinterpret_cast<char *>(&value), sizeof value);\n        out |= static_cast<T>(value) << (8 * i);\n    }\n\n    return out;\n}\n\ntemplate <typename T>\nbyte_array<sizeof(T)> to_big_endian(T n)\n{\n    VERIFY_UNSIGNED(T);\n    byte_array<sizeof(T)> out;\n    for (auto i = out.rbegin(); i != out.rend(); ++i)\n    {\n        *i = static_cast<uint8_t>(n);\n        n >>= 8;\n    }\n\n    return out;\n}\n\ntemplate <typename T>\nbyte_array<sizeof(T)> to_little_endian(T n)\n{\n    VERIFY_UNSIGNED(T);\n    byte_array<sizeof(T)> out;\n    for (auto i = out.begin(); i != out.end(); ++i)\n    {\n        *i = static_cast<uint8_t>(n);\n        n >>= 8;\n    }\n\n    return out;\n}\n\n#undef VERIFY_UNSIGNED\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/impl/utility/istream_reader.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_ISTREAM_READER_IPP\n#define UC_ISTREAM_READER_IPP\n\n#include <algorithm>\n#include <boost/asio/streambuf.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/endian.hpp>\n#include <UChain/coin/utility/exceptions.hpp>\n\nnamespace libbitcoin\n{\n\ntemplate <typename T>\nT istream_reader::read_big_endian()\n{\n    return from_big_endian_stream_unsafe<T>(stream_);\n}\n\ntemplate <typename T>\nT istream_reader::read_little_endian()\n{\n    return from_little_endian_stream_unsafe<T>(stream_);\n}\n\ntemplate <unsigned Size>\nbyte_array<Size> istream_reader::read_bytes()\n{\n    byte_array<Size> out;\n\n    for (unsigned i = 0; i < Size; i++)\n        out[i] = read_byte();\n\n    return out;\n}\n\ntemplate <unsigned Size>\nbyte_array<Size> istream_reader::read_bytes_reverse()\n{\n    byte_array<Size> out;\n\n    for (unsigned i = 0; i < Size; i++)\n        out[Size - (i + 1)] = read_byte();\n\n    return out;\n}\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/impl/utility/notifier.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NOTIFIER_IPP\n#define UC_NOTIFIER_IPP\n\n#include <cstddef>\n#include <functional>\n#include <memory>\n#include <string>\n#include <utility>\n#include <UChain/coin/compat.hpp>\n#include <UChain/coin/utility/asio.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/dispatcher.hpp>\n#include <UChain/coin/utility/thread.hpp>\n#include <UChain/coin/utility/threadpool.hpp>\n////#include <UChain/coin/utility/track.hpp>\n\nnamespace libbitcoin\n{\n\ntemplate <typename Key, typename... Args>\nnotifier<Key, Args...>::notifier(threadpool &pool,\n                                 const std::string &class_name)\n    : limit_(0), stopped_(true), dispatch_(pool, class_name)\n/*, track<notifier<Key, Args...>>(class_name)*/\n{\n}\n\ntemplate <typename Key, typename... Args>\nnotifier<Key, Args...>::notifier(threadpool &pool, size_t limit,\n                                 const std::string &class_name)\n    : limit_(limit), stopped_(true), dispatch_(pool, class_name)\n/*, track<notifier<Key, Args...>>(class_name)*/\n{\n}\n\ntemplate <typename Key, typename... Args>\nnotifier<Key, Args...>::~notifier()\n{\n    BITCOIN_ASSERT_MSG(subscriptions_.empty(), \"notifier not cleared\");\n}\n\ntemplate <typename Key, typename... Args>\nvoid notifier<Key, Args...>::start()\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    subscribe_mutex_.lock_upgrade();\n\n    if (stopped_)\n    {\n        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n        subscribe_mutex_.unlock_upgrade_and_lock();\n        stopped_ = false;\n        subscribe_mutex_.unlock();\n        //---------------------------------------------------------------------\n        return;\n    }\n\n    subscribe_mutex_.unlock_upgrade();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\ntemplate <typename Key, typename... Args>\nvoid notifier<Key, Args...>::stop()\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    subscribe_mutex_.lock_upgrade();\n\n    if (!stopped_)\n    {\n        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n        subscribe_mutex_.unlock_upgrade_and_lock();\n        stopped_ = true;\n        subscribe_mutex_.unlock();\n        //---------------------------------------------------------------------\n        return;\n    }\n\n    subscribe_mutex_.unlock_upgrade();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\ntemplate <typename Key, typename... Args>\nvoid notifier<Key, Args...>::subscribe(handler handler, const Key &key,\n                                       const asio::duration &duration, Args... stopped_args)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    subscribe_mutex_.lock_upgrade();\n\n    if (!stopped_)\n    {\n        const auto it = subscriptions_.find(key);\n\n        if (it != subscriptions_.end())\n        {\n            const auto expires = asio::steady_clock::now() + duration;\n            //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n            subscribe_mutex_.unlock_upgrade_and_lock();\n            it->second.expires = expires;\n            subscribe_mutex_.unlock();\n            //---------------------------------------------------------------------\n            return;\n        }\n        else if (limit_ == 0 || subscriptions_.size() < limit_)\n        {\n            const auto expires = asio::steady_clock::now() + duration;\n            //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n            subscribe_mutex_.unlock_upgrade_and_lock();\n            subscriptions_.emplace(\n                std::make_pair(key, value{handler, expires}));\n            subscribe_mutex_.unlock();\n            //---------------------------------------------------------------------\n            return;\n        }\n    }\n\n    subscribe_mutex_.unlock_upgrade();\n    ///////////////////////////////////////////////////////////////////////////\n\n    // Limit exceeded and stopped share the same return arguments.\n    handler(stopped_args...);\n}\n\ntemplate <typename Key, typename... Args>\nvoid notifier<Key, Args...>::unsubscribe(const Key &key,\n                                         Args... unsubscribed_args)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    subscribe_mutex_.lock_upgrade();\n\n    if (!stopped_)\n    {\n        const auto it = subscriptions_.find(key);\n\n        if (it != subscriptions_.end())\n        {\n            const auto handler = it->second.notify;\n\n            //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n            subscribe_mutex_.unlock_upgrade_and_lock();\n            subscriptions_.erase(it);\n            subscribe_mutex_.unlock();\n            //-----------------------------------------------------------------\n            handler(unsubscribed_args...);\n            return;\n        }\n    }\n\n    subscribe_mutex_.unlock_upgrade();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\ntemplate <typename Key, typename... Args>\nvoid notifier<Key, Args...>::purge(Args... expired_args)\n{\n    const auto now = asio::steady_clock::now();\n\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    subscribe_mutex_.lock();\n\n    // Move subscribers from the member map to a temporary map.\n    map subscriptions;\n    std::swap(subscriptions, subscriptions_);\n\n    subscribe_mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n\n    // Subscriptions may be created while this loop is executing.\n    // Invoke and discard expired subscribers from temporary map.\n    for (const auto &entry : subscriptions)\n    {\n        if (now > entry.second.expires)\n        {\n            entry.second.notify(expired_args...);\n            continue;\n        }\n\n        // Critical Section\n        ///////////////////////////////////////////////////////////////////\n        unique_lock lock(subscribe_mutex_);\n        subscriptions_.emplace(entry);\n        ///////////////////////////////////////////////////////////////////\n    }\n}\n\ntemplate <typename Key, typename... Args>\nvoid notifier<Key, Args...>::invoke(Args... args)\n{\n    do_invoke(args...);\n}\n\ntemplate <typename Key, typename... Args>\nvoid notifier<Key, Args...>::relay(Args... args)\n{\n    // This enqueues work while maintaining order.\n    dispatch_.ordered(&notifier<Key, Args...>::do_invoke,\n                      this->shared_from_this(), args...);\n}\n\n// private\ntemplate <typename Key, typename... Args>\nvoid notifier<Key, Args...>::do_invoke(Args... args)\n{\n    // Critical Section (prevent concurrent handler execution)\n    ///////////////////////////////////////////////////////////////////////////\n    unique_lock lock(invoke_mutex_);\n\n    // Critical Section (protect stop)\n    ///////////////////////////////////////////////////////////////////////////\n    subscribe_mutex_.lock();\n\n    // Move subscribers from the member map to a temporary map.\n    map subscriptions;\n    std::swap(subscriptions, subscriptions_);\n\n    subscribe_mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n\n    // Subscriptions may be created while this loop is executing.\n    // Invoke subscribers from temporary map and resubscribe as indicated.\n    for (const auto &entry : subscriptions)\n    {\n        if (entry.second.notify(args...))\n        {\n            // Critical Section\n            ///////////////////////////////////////////////////////////////////\n            subscribe_mutex_.lock_upgrade();\n\n            if (stopped_)\n            {\n                subscribe_mutex_.unlock_upgrade();\n                //-------------------------------------------------------------\n                continue;\n            }\n\n            subscribe_mutex_.unlock_upgrade_and_lock();\n            //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n            subscriptions_.emplace(entry);\n\n            subscribe_mutex_.unlock();\n            ///////////////////////////////////////////////////////////////////\n        }\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/impl/utility/ostream_writer.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_OSTREAM_WRITER_IPP\n#define UC_OSTREAM_WRITER_IPP\n\n#include <algorithm>\n#include <boost/asio/streambuf.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/endian.hpp>\n#include <UChain/coin/utility/exceptions.hpp>\n\nnamespace libbitcoin\n{\n\ntemplate <typename T>\nvoid ostream_writer::write_big_endian(T value)\n{\n    byte_array<sizeof(T)> bytes = to_big_endian(value);\n    write_bytes<sizeof(T)>(bytes);\n}\n\ntemplate <typename T>\nvoid ostream_writer::write_little_endian(T value)\n{\n    stream_.write(reinterpret_cast<const char *>(&value), sizeof(T));\n}\n\ntemplate <typename T>\nvoid ostream_writer::write_data(T &value)\n{\n    const auto size = value.size();\n    if (size > 0)\n        stream_.write(reinterpret_cast<const char *>(value.data()), size);\n}\n\ntemplate <unsigned Size>\nvoid ostream_writer::write_bytes(const byte_array<Size> &value)\n{\n    //for (unsigned i = 0; i < Size; i++)\n    //    write_byte(value[i]);\n\n    const auto size = value.size();\n    if (size > 0)\n        stream_.write(reinterpret_cast<const char *>(value.data()), size);\n}\n\ntemplate <unsigned Size>\nvoid ostream_writer::write_bytes_reverse(const byte_array<Size> &value)\n{\n    for (unsigned i = 0; i < Size; i++)\n        write_byte(value[Size - (i + 1)]);\n}\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/impl/utility/resubscriber.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_RESUBSCRIBER_IPP\n#define UC_RESUBSCRIBER_IPP\n\n#include <functional>\n#include <memory>\n#include <string>\n#include <utility>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/dispatcher.hpp>\n#include <UChain/coin/utility/thread.hpp>\n#include <UChain/coin/utility/threadpool.hpp>\n////#include <UChain/coin/utility/track.hpp>\n\nnamespace libbitcoin\n{\n\ntemplate <typename... Args>\nresubscriber<Args...>::resubscriber(threadpool &pool,\n                                    const std::string &class_name)\n    : stopped_(true), dispatch_(pool, class_name)\n/*, track<resubscriber<Args...>>(class_name)*/\n{\n}\n\ntemplate <typename... Args>\nresubscriber<Args...>::~resubscriber()\n{\n    BITCOIN_ASSERT_MSG(subscriptions_.empty(), \"resubscriber not cleared\");\n}\n\ntemplate <typename... Args>\nvoid resubscriber<Args...>::start()\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    subscribe_mutex_.lock_upgrade();\n\n    if (stopped_)\n    {\n        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n        subscribe_mutex_.unlock_upgrade_and_lock();\n        stopped_ = false;\n        subscribe_mutex_.unlock();\n        //---------------------------------------------------------------------\n        return;\n    }\n\n    subscribe_mutex_.unlock_upgrade();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\ntemplate <typename... Args>\nvoid resubscriber<Args...>::stop()\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    subscribe_mutex_.lock_upgrade();\n\n    if (!stopped_)\n    {\n        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n        subscribe_mutex_.unlock_upgrade_and_lock();\n        stopped_ = true;\n        subscribe_mutex_.unlock();\n        //---------------------------------------------------------------------\n        return;\n    }\n\n    subscribe_mutex_.unlock_upgrade();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\ntemplate <typename... Args>\nvoid resubscriber<Args...>::subscribe(handler handler, Args... stopped_args)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    subscribe_mutex_.lock_upgrade();\n\n    if (!stopped_)\n    {\n        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n        subscribe_mutex_.unlock_upgrade_and_lock();\n        subscriptions_.emplace_back(handler);\n        subscribe_mutex_.unlock();\n        //---------------------------------------------------------------------\n        return;\n    }\n\n    subscribe_mutex_.unlock_upgrade();\n    ///////////////////////////////////////////////////////////////////////////\n\n    handler(stopped_args...);\n}\n\ntemplate <typename... Args>\nvoid resubscriber<Args...>::invoke(Args... args)\n{\n    do_invoke(args...);\n}\n\ntemplate <typename... Args>\nvoid resubscriber<Args...>::relay(Args... args)\n{\n    // This enqueues work while maintaining order.\n    dispatch_.ordered(&resubscriber<Args...>::do_invoke,\n                      this->shared_from_this(), args...);\n}\n\n// private\ntemplate <typename... Args>\nvoid resubscriber<Args...>::do_invoke(Args... args)\n{\n    // Critical Section (prevent concurrent handler execution)\n    ///////////////////////////////////////////////////////////////////////////\n    unique_lock lock(invoke_mutex_);\n\n    // Critical Section (protect stop)\n    ///////////////////////////////////////////////////////////////////////////\n    subscribe_mutex_.lock();\n\n    // Move subscribers from the member list to a temporary list.\n    list subscriptions;\n    std::swap(subscriptions, subscriptions_);\n\n    subscribe_mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n\n    // Subscriptions may be created while this loop is executing.\n    // Invoke subscribers from temporary list and resubscribe as indicated.\n    for (const auto &handler : subscriptions)\n    {\n        if (handler(args...))\n        {\n            // Critical Section\n            ///////////////////////////////////////////////////////////////////\n            subscribe_mutex_.lock_upgrade();\n\n            if (stopped_)\n            {\n                subscribe_mutex_.unlock_upgrade();\n                //-------------------------------------------------------------\n                continue;\n            }\n\n            subscribe_mutex_.unlock_upgrade_and_lock();\n            //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n            subscriptions_.emplace_back(handler);\n\n            subscribe_mutex_.unlock();\n            ///////////////////////////////////////////////////////////////////\n        }\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/impl/utility/serializer.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SERIALIZER_IPP\n#define UC_SERIALIZER_IPP\n\n#include <algorithm>\n#include <cstddef>\n#include <cstdint>\n#include <boost/asio/streambuf.hpp>\n#include <UChain/coin/error.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/endian.hpp>\n\nnamespace libbitcoin\n{\n\ntemplate <typename Iterator>\nserializer<Iterator>::serializer(const Iterator begin)\n    : iterator_(begin)\n{\n}\n\ntemplate <typename Iterator>\nserializer<Iterator>::operator bool() const\n{\n    return true;\n}\n\ntemplate <typename Iterator>\nbool serializer<Iterator>::operator!() const\n{\n    return false;\n}\n\ntemplate <typename Iterator>\nvoid serializer<Iterator>::write_byte(uint8_t value)\n{\n    *iterator_ = value;\n    ++iterator_;\n}\n\ntemplate <typename Iterator>\nvoid serializer<Iterator>::write_data(const data_chunk &data)\n{\n    write_data<const data_chunk>(data);\n}\n\ntemplate <typename Iterator>\nvoid serializer<Iterator>::write_data(const uint8_t *data, size_t size)\n{\n    iterator_ = std::copy(data, (data + size), iterator_);\n}\n\ntemplate <typename Iterator>\nvoid serializer<Iterator>::write_error_code(const code &ec)\n{\n    const auto value = ec.value();\n    BITCOIN_ASSERT(value >= 0 && static_cast<uint32_t>(value) <= max_uint32);\n    write_4_bytes_little_endian(static_cast<uint32_t>(value));\n}\n\ntemplate <typename Iterator>\nvoid serializer<Iterator>::write_2_bytes_little_endian(uint16_t value)\n{\n    write_little_endian(value);\n}\n\ntemplate <typename Iterator>\nvoid serializer<Iterator>::write_4_bytes_little_endian(uint32_t value)\n{\n    write_little_endian(value);\n}\n\ntemplate <typename Iterator>\nvoid serializer<Iterator>::write_8_bytes_little_endian(uint64_t value)\n{\n    write_little_endian(value);\n}\n\ntemplate <typename Iterator>\nvoid serializer<Iterator>::write_2_bytes_big_endian(uint16_t value)\n{\n    write_big_endian(value);\n}\n\ntemplate <typename Iterator>\nvoid serializer<Iterator>::write_4_bytes_big_endian(uint32_t value)\n{\n    write_big_endian(value);\n}\n\ntemplate <typename Iterator>\nvoid serializer<Iterator>::write_8_bytes_big_endian(uint64_t value)\n{\n    write_big_endian(value);\n}\n\ntemplate <typename Iterator>\ntemplate <typename T>\nvoid serializer<Iterator>::write_big_endian(T n)\n{\n    return write_data(to_big_endian(n));\n}\n\ntemplate <typename Iterator>\ntemplate <typename T>\nvoid serializer<Iterator>::write_little_endian(T n)\n{\n    return write_data(to_little_endian(n));\n}\n\ntemplate <typename Iterator>\nvoid serializer<Iterator>::write_variable_uint_little_endian(uint64_t value)\n{\n    if (value < 0xfd)\n    {\n        write_byte((uint8_t)value);\n    }\n    else if (value <= 0xffff)\n    {\n        write_byte(0xfd);\n        write_2_bytes_little_endian((uint16_t)value);\n    }\n    else if (value <= 0xffffffff)\n    {\n        write_byte(0xfe);\n        write_4_bytes_little_endian((uint32_t)value);\n    }\n    else\n    {\n        write_byte(0xff);\n        write_8_bytes_little_endian(value);\n    }\n}\n\ntemplate <typename Iterator>\nvoid serializer<Iterator>::write_variable_uint_big_endian(uint64_t value)\n{\n    if (value < 0xfd)\n    {\n        write_byte((uint8_t)value);\n    }\n    else if (value <= 0xffff)\n    {\n        write_byte(0xfd);\n        write_2_bytes_big_endian((uint16_t)value);\n    }\n    else if (value <= 0xffffffff)\n    {\n        write_byte(0xfe);\n        write_4_bytes_big_endian((uint32_t)value);\n    }\n    else\n    {\n        write_byte(0xff);\n        write_8_bytes_big_endian(value);\n    }\n}\n\ntemplate <typename Iterator>\ntemplate <typename T>\nvoid serializer<Iterator>::write_data(const T &data)\n{\n    iterator_ = std::copy(data.begin(), data.end(), iterator_);\n}\n\ntemplate <typename Iterator>\nvoid serializer<Iterator>::write_hash(const hash_digest &hash)\n{\n    write_data(hash);\n}\n\ntemplate <typename Iterator>\nvoid serializer<Iterator>::write_short_hash(const short_hash &hash)\n{\n    write_data(hash);\n}\n\ntemplate <typename Iterator>\nvoid serializer<Iterator>::write_mini_hash(\n    const mini_hash &hash)\n{\n    write_data(hash);\n}\n\ntemplate <typename Iterator>\nvoid serializer<Iterator>::write_fixed_string(const std::string &value,\n                                              size_t size)\n{\n    const auto min_size = std::min(size, value.size());\n    data_chunk raw_string(size, 0);\n\n    std::copy_n(value.begin(), min_size, raw_string.begin());\n    write_data(raw_string);\n}\n\ntemplate <typename Iterator>\nvoid serializer<Iterator>::write_string(const std::string &value)\n{\n    write_variable_uint_little_endian(value.size());\n    write_data(value);\n}\n\n/**\n * Returns underlying iterator.\n */\ntemplate <typename Iterator>\nIterator serializer<Iterator>::iterator()\n{\n    return iterator_;\n}\n\n/**\n * Useful if you want to serialize some data using another\n * routine and then continue with this serializer.\n */\ntemplate <typename Iterator>\nvoid serializer<Iterator>::set_iterator(Iterator iterator)\n{\n    iterator_ = iterator;\n}\n\ntemplate <typename Iterator>\ntemplate <typename T>\nvoid serializer<Iterator>::write_data_reverse(const T &data)\n{\n    iterator_ = std::reverse_copy(data.begin(), data.end(), iterator_);\n}\n\ntemplate <typename Iterator>\nserializer<Iterator> make_serializer(Iterator begin)\n{\n    return serializer<Iterator>(begin);\n}\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/impl/utility/subscriber.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SUBSCRIBER_IPP\n#define UC_SUBSCRIBER_IPP\n\n#include <functional>\n#include <memory>\n#include <string>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/dispatcher.hpp>\n#include <UChain/coin/utility/thread.hpp>\n#include <UChain/coin/utility/threadpool.hpp>\n////#include <UChain/coin/utility/track.hpp>\n\nnamespace libbitcoin\n{\n\ntemplate <typename... Args>\nsubscriber<Args...>::subscriber(threadpool &pool,\n                                const std::string &class_name)\n    : stopped_(true), dispatch_(pool, class_name)\n/*, track<subscriber<Args...>>(class_name)*/\n{\n}\n\ntemplate <typename... Args>\nsubscriber<Args...>::~subscriber()\n{\n    BITCOIN_ASSERT_MSG(subscriptions_.empty(), \"subscriber not cleared\");\n}\n\ntemplate <typename... Args>\nvoid subscriber<Args...>::start()\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    subscribe_mutex_.lock_upgrade();\n\n    if (stopped_)\n    {\n        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n        subscribe_mutex_.unlock_upgrade_and_lock();\n        stopped_ = false;\n        subscribe_mutex_.unlock();\n        //---------------------------------------------------------------------\n        return;\n    }\n\n    subscribe_mutex_.unlock_upgrade();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\ntemplate <typename... Args>\nvoid subscriber<Args...>::stop()\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    subscribe_mutex_.lock_upgrade();\n\n    if (!stopped_)\n    {\n        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n        subscribe_mutex_.unlock_upgrade_and_lock();\n        stopped_ = true;\n        subscribe_mutex_.unlock();\n        //---------------------------------------------------------------------\n        return;\n    }\n\n    subscribe_mutex_.unlock_upgrade();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\ntemplate <typename... Args>\nvoid subscriber<Args...>::subscribe(handler handler, Args... stopped_args)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    subscribe_mutex_.lock_upgrade();\n\n    if (!stopped_)\n    {\n        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n        subscribe_mutex_.unlock_upgrade_and_lock();\n        subscriptions_.emplace_back(handler);\n        subscribe_mutex_.unlock();\n        //---------------------------------------------------------------------\n        return;\n    }\n\n    subscribe_mutex_.unlock_upgrade();\n    ///////////////////////////////////////////////////////////////////////////\n\n    handler(stopped_args...);\n}\n\ntemplate <typename... Args>\nvoid subscriber<Args...>::invoke(Args... args)\n{\n    do_invoke(args...);\n}\n\ntemplate <typename... Args>\nvoid subscriber<Args...>::relay(Args... args)\n{\n    // This enqueues work while maintaining order.\n    dispatch_.ordered(&subscriber<Args...>::do_invoke,\n                      this->shared_from_this(), args...);\n}\n\n// private\ntemplate <typename... Args>\nvoid subscriber<Args...>::do_invoke(Args... args)\n{\n    // Critical Section (prevent concurrent handler execution)\n    ///////////////////////////////////////////////////////////////////////////\n    unique_lock lock(invoke_mutex_);\n\n    // Critical Section (protect stop)\n    ///////////////////////////////////////////////////////////////////////////\n    subscribe_mutex_.lock();\n\n    // Move subscribers from the member list to a temporary list.\n    list subscriptions;\n    std::swap(subscriptions, subscriptions_);\n\n    subscribe_mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n\n    // Subscriptions may be created while this loop is executing.\n    // Invoke subscribers from temporary list, without subscription renewal.\n    for (const auto &handler : subscriptions)\n        handler(args...);\n\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/impl/utility/track.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_TRACK_IPP\n#define UC_TRACK_IPP\n\n#include <atomic>\n#include <cstddef>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/log.hpp>\n#define RESOURCE_INSCREASE\ntemplate <class Shared>\nstd::atomic<size_t> track<Shared>::instances(0);\n\ntemplate <class Shared>\ntrack<Shared>::track(const std::string &DEBUG_ONLY(class_name))\n#ifndef NDEBUG\n    : class_(class_name)\n#endif\n{\n#ifndef NDEBUG\n#ifndef RESOURCE_INSCREASE\n    count_ = ++instances;\n    bc::log::trace(LOG_SYSTEM)\n        << class_ << \"(\" << count_ << \")\";\n#else\n    bc::log::trace(LOG_SYSTEM)\n        << class_ << \"(\" << ++instances << \")\";\n#endif\n#endif\n}\n\ntemplate <class Shared>\ntrack<Shared>::~track()\n{\n#ifndef NDEBUG\n    bc::log::trace(LOG_SYSTEM)\n#ifndef RESOURCE_INSCREASE\n        << \"~\" << class_ << \"(\" << count_ << \")\";\n#else\n        << \"~\" << class_ << \"(\" << --instances << \")\";\n#endif\n#endif\n}\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/math/checksum.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHECKSUM_HPP\n#define UC_CHECKSUM_HPP\n\n#include <algorithm>\n#include <cstddef>\n#include <cstdint>\n#include <initializer_list>\n#include <UChain/coin/compat.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\n\nstatic BC_CONSTEXPR size_t checksum_size = sizeof(uint32_t);\n\n#define WRAP_SIZE(payload_size) (payload_size + checksum_size + 1)\n#define UNWRAP_SIZE(payload_size) (payload_size - checksum_size - 1)\n\n/**\n * Concatenate several data slices into a single fixed size array and append a\n * checksum.\n */\ntemplate <size_t Size>\nbool build_checked_array(byte_array<Size> &out,\n                         const std::initializer_list<data_slice> &slices);\n\n/**\n * Appends a four-byte checksum into the end of an array.\n * Returns false if the array is too small to contain the checksum.\n */\ntemplate <size_t Size>\nbool insert_checksum(byte_array<Size> &out);\n\n/**\n * Unwrap a wrapped payload.\n * @param[out] out_version   The version byte of the wrapped data.\n * @param[out] out_payload   The payload of the wrapped data.\n * @param[in]  wrapped       The wrapped data to unwrap.\n * @return                   True if input checksum validates.\n */\ntemplate <size_t Size>\nbool unwrap(uint8_t &out_version, byte_array<UNWRAP_SIZE(Size)> &out_payload,\n            const std::array<uint8_t, Size> &wrapped);\n\n/**\n * Unwrap a wrapped payload and return the checksum.\n * @param[out] out_version   The version byte of the wrapped data.\n * @param[out] out_payload   The payload of the wrapped data.\n * @param[out] out_checksum  The validated checksum of the wrapped data.\n * @param[in]  wrapped       The wrapped data to unwrap.\n * @return                   True if input checksum validates.\n */\ntemplate <size_t Size>\nbool unwrap(uint8_t &out_version,\n            byte_array<UNWRAP_SIZE(Size)> &out_payload, uint32_t &out_checksum,\n            const std::array<uint8_t, Size> &wrapped);\n\n/**\n * Wrap arbitrary data.\n * @param[in]  version  The version byte for the wrapped data.\n * @param[out] payload  The payload to wrap.\n * @return              The wrapped data.\n */\ntemplate <size_t Size>\nstd::array<uint8_t, WRAP_SIZE(Size)> wrap(uint8_t version,\n                                          const std::array<uint8_t, Size> &payload);\n\n/**\n * Appends a four-byte checksum of a data chunk to itself.\n */\nBC_API void append_checksum(data_chunk &data);\n\n/**\n * Generate a bitcoin hash checksum. Last 4 bytes of sha256(sha256(data))\n *\n * int(sha256(sha256(data))[-4:])\n */\nBC_API uint32_t bitcoin_checksum(data_slice data);\n\n/**\n * Verifies the last four bytes of a data chunk are a valid checksum of the\n * earlier bytes. This is typically used to verify base58 data.\n */\nBC_API bool verify_checksum(data_slice data);\n\n} // namespace libbitcoin\n\n#include <UChain/coin/impl/math/checksum.ipp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/math/crypto.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_AES256_HPP\n#define UC_AES256_HPP\n\n#include <cstdint>\n#include <UChain/coin/compat.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\n\n/**\n * The secret for aes256 block cypher.\n */\nBC_CONSTEXPR uint8_t aes256_key_size = 32;\ntypedef byte_array<aes256_key_size> aes_secret;\n\n/**\n * The data block for use with aes256 block cypher.\n */\nBC_CONSTEXPR uint8_t aes256_block_size = 16;\ntypedef byte_array<aes256_block_size> aes_block;\n\n/**\n * Perform aes256 encryption on the specified data block.\n */\nBC_API void aes256_encrypt(const aes_secret &key, aes_block &block);\n\n/**\n * Perform aes256 decryption on the specified data block.\n */\nBC_API void aes256_decrypt(const aes_secret &key, aes_block &block);\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/math/elliptic_curve.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_ELLIPTIC_CURVE_HPP\n#define UC_ELLIPTIC_CURVE_HPP\n\n#include <cstddef>\n#include <UChain/coin/compat.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\n\n/// Private key:\nBC_CONSTEXPR size_t ec_secret_size = 32;\ntypedef byte_array<ec_secret_size> ec_secret;\n\n/// Compressed public key:\nBC_CONSTEXPR size_t ec_compressed_size = 33;\ntypedef byte_array<ec_compressed_size> ec_compressed;\n\ntypedef std::vector<ec_compressed> point_list;\n\n/// Uncompressed public key:\nBC_CONSTEXPR size_t ec_uncompressed_size = 65;\ntypedef byte_array<ec_uncompressed_size> ec_uncompressed;\n\n// Parsed ECDSA signature:\nBC_CONSTEXPR size_t ec_signature_size = 64;\ntypedef byte_array<ec_signature_size> ec_signature;\n\n// DER encoded signature:\nBC_CONSTEXPR size_t max_der_signature_size = 72;\ntypedef data_chunk der_signature;\n\n/// DER encoded signature with sighash byte for input endorsement:\nBC_CONSTEXPR size_t max_endorsement_size = 73;\ntypedef data_chunk endorsement;\n\n/// Recoverable ecdsa signature for message signing:\nstruct BC_API recoverable_signature\n{\n    ec_signature signature;\n    uint8_t recovery_id;\n};\n\nBC_CONSTEXPR ec_compressed null_compressed_point =\n    {\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};\n\nBC_CONSTEXPR ec_uncompressed null_uncompressed_point =\n    {\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};\n\n// Add and multiply EC values\n// ----------------------------------------------------------------------------\n\n/// Compute the sum a += G*b, where G is the curve's generator point.\n/// return false on failure (such as infinity or zero).\nBC_API bool ec_add(ec_compressed &point, const ec_secret &secret);\n\n/// Compute the sum a += G*b, where G is the curve's generator point.\n/// return false on failure (such as infinity or zero).\nBC_API bool ec_add(ec_uncompressed &point, const ec_secret &secret);\n\n/// Compute the sum a = (a + b) % n, where n is the curve order.\n/// return false on failure (such as a zero result).\nBC_API bool ec_add(ec_secret &left, const ec_secret &right);\n\n/// Compute the product point *= secret.\n/// return false on failure (such as infinity or zero).\nBC_API bool ec_multiply(ec_compressed &point, const ec_secret &secret);\n\n/// Compute the product point *= secret.\n/// return false on failure (such as infinity or zero).\nBC_API bool ec_multiply(ec_uncompressed &point, const ec_secret &secret);\n\n/// Compute the product a = (a * b) % n, where n is the curve order.\n/// return false on failure (such as a zero result).\nBC_API bool ec_multiply(ec_secret &left, const ec_secret &right);\n\n// Convert keys\n// ----------------------------------------------------------------------------\n\n/// Convert an uncompressed public point to compressed.\nBC_API bool compress(ec_compressed &out, const ec_uncompressed &point);\n\n/// Convert a compressed public point to decompressed.\nBC_API bool decompress(ec_uncompressed &out, const ec_compressed &point);\n\n/// Convert a secret to a compressed public point.\nBC_API bool secret_to_public(ec_compressed &out, const ec_secret &secret);\n\n/// Convert a secret parameter to an uncompressed public point.\nBC_API bool secret_to_public(ec_uncompressed &out, const ec_secret &secret);\n\n// Verify keys\n// ----------------------------------------------------------------------------\n\n/// Verify a secret.\nBC_API bool verify(const ec_secret &secret);\n\n/// Verify a point.\nBC_API bool verify(const ec_compressed &point);\n\n/// Verify a point.\nBC_API bool verify(const ec_uncompressed &point);\n\n// Detect public keys\n// ----------------------------------------------------------------------------\n\n/// Fast detection of compressed public key structure.\nbool is_compressed_key(data_slice point);\n\n/// Fast detection of uncompressed public key structure.\nbool is_uncompressed_key(data_slice point);\n\n/// Fast detection of compressed or uncompressed public key structure.\nbool is_public_key(data_slice point);\n\n// DER parse/encode\n// ----------------------------------------------------------------------------\n\n/// Parse a DER encoded signature with optional strict DER enforcement.\n/// Treat an empty DER signature as invalid, in accordance with BIP66.\nBC_API bool parse_signature(ec_signature &out,\n                            const der_signature &der_signature, bool strict);\n\n/// Encode an EC signature as DER (strict).\nBC_API bool encode_signature(der_signature &out, const ec_signature &signature);\n\n// EC sign/verify\n// ----------------------------------------------------------------------------\n\n/// Create a deterministic ECDSA signature using a private key.\nBC_API bool sign(ec_signature &out, const ec_secret &secret,\n                 const hash_digest &hash);\n\n/// Verify an EC signature using a compressed point.\nBC_API bool verify_signature(const ec_compressed &point,\n                             const hash_digest &hash, const ec_signature &signature);\n\n/// Verify an EC signature using an uncompressed point.\nBC_API bool verify_signature(const ec_uncompressed &point,\n                             const hash_digest &hash, const ec_signature &signature);\n\n/// Verify an EC signature using a potential point.\nBC_API bool verify_signature(data_slice point, const hash_digest &hash,\n                             const ec_signature &signature);\n\n// Recoverable sign/recover\n// ----------------------------------------------------------------------------\n\n/// Create a recoverable signature for use in message signing.\nBC_API bool sign_recoverable(recoverable_signature &out,\n                             const ec_secret &secret, const hash_digest &hash);\n\n/// Recover the compressed point from a recoverable message signature.\nBC_API bool recover_public(ec_compressed &out,\n                           const recoverable_signature &recoverable, const hash_digest &hash);\n\n/// Recover the uncompressed point from a recoverable message signature.\nBC_API bool recover_public(ec_uncompressed &out,\n                           const recoverable_signature &recoverable, const hash_digest &hash);\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/math/hash.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_HASH_HPP\n#define UC_HASH_HPP\n\n#include <cstddef>\n#include <string>\n#include <vector>\n#include <boost/functional/hash_fwd.hpp>\n#include <UChain/coin/compat.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\n\n// Common bitcoin hash container sizes.\nstatic BC_CONSTEXPR size_t hash_size = 32;\nstatic BC_CONSTEXPR size_t half_hash_size = hash_size / 2;\nstatic BC_CONSTEXPR size_t quarter_hash_size = half_hash_size / 2;\nstatic BC_CONSTEXPR size_t long_hash_size = 2 * hash_size;\nstatic BC_CONSTEXPR size_t short_hash_size = 20;\nstatic BC_CONSTEXPR size_t mini_hash_size = 6;\n\n// Common bitcoin hash containers.\ntypedef byte_array<hash_size> hash_digest;\ntypedef byte_array<half_hash_size> half_hash;\ntypedef byte_array<quarter_hash_size> quarter_hash;\ntypedef byte_array<long_hash_size> long_hash;\ntypedef byte_array<short_hash_size> short_hash;\ntypedef byte_array<mini_hash_size> mini_hash;\n\n// Lists of common bitcoin hashes.\ntypedef std::vector<hash_digest> hash_list;\ntypedef std::vector<half_hash> half_hash_list;\ntypedef std::vector<quarter_hash> quarter_hash_list;\ntypedef std::vector<long_hash> long_hash_list;\ntypedef std::vector<short_hash> short_hash_list;\ntypedef std::vector<mini_hash> mini_hash_list;\n\n// Null-valued common bitcoin hashes.\n\nBC_CONSTEXPR hash_digest null_hash{\n    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};\n\nBC_CONSTEXPR half_hash null_half_hash{\n    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};\n\nBC_CONSTEXPR quarter_hash null_quarter_hash{\n    {0, 0, 0, 0, 0, 0, 0, 0}};\n\nBC_CONSTEXPR long_hash null_long_hash{\n    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};\n\nBC_CONSTEXPR short_hash null_short_hash{\n    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n     0, 0, 0, 0}};\n\nBC_CONSTEXPR mini_hash null_mini_hash{\n    {0, 0, 0, 0, 0, 0}};\n\n/**\n * Generate a scrypt hash to fill a byte array.\n *\n * scrypt(data, salt, params)\n */\ntemplate <size_t Size>\nbyte_array<Size> scrypt(data_slice data, data_slice salt, uint64_t N,\n                        uint32_t p, uint32_t r);\n\n/**\n * Generate a ripemd160 hash. This hash function is used in script for\n * op_ripemd160.\n\n * ripemd160(data)\n */\nBC_API short_hash ripemd160_hash(data_slice data);\n\n/**\n * Generate a sha1 hash. This hash function is used in script for op_sha1.\n *\n * sha1(data)\n */\nBC_API short_hash sha1_hash(data_slice data);\n\n/**\n * Generate a sha256 hash. This hash function is used in mini keys.\n *\n * sha256(data)\n */\nBC_API hash_digest sha256_hash(data_slice data);\n\n/**\n * Generate a sha256 hash. This hash function is used in electrum seed\n * stretching (deprecated).\n *\n * sha256(data)\n */\nBC_API hash_digest sha256_hash(data_slice first, data_slice second);\n\n/**\n * Generate a hmac sha256 hash. This hash function is used in deterministic\n * signing.\n *\n * hmac-sha256(data, key)\n */\nBC_API hash_digest hmac_sha256_hash(data_slice data, data_slice key);\n\n/**\n * Generate a sha512 hash. This hash function is used in bip32 keys.\n *\n * sha512(data)\n */\nBC_API long_hash sha512_hash(data_slice data);\n\n/**\n * Generate a hmac sha512 hash. This hash function is used in bip32 keys.\n *\n * hmac-sha512(data, key)\n */\nBC_API long_hash hmac_sha512_hash(data_slice data, data_slice key);\n\n/**\n * Generate a pkcs5 pbkdf2 hmac sha512 hash. This hash function is used in\n * bip39 mnemonics.\n *\n * pkcs5_pbkdf2_hmac_sha512(passphrase, salt, iterations)\n */\nBC_API long_hash pkcs5_pbkdf2_hmac_sha512(data_slice passphrase,\n                                          data_slice salt, size_t iterations);\n\n/**\n * Generate a typical bitcoin hash. This is the most widely used\n * hash function in Bitcoin.\n *\n * sha256(sha256(data))\n */\nBC_API hash_digest bitcoin_hash(data_slice data);\n\n/**\n * Generate a bitcoin short hash. This hash function is used in a\n * few specific cases where short hashes are desired.\n *\n * ripemd160(sha256(data))\n */\nBC_API short_hash bitcoin_short_hash(data_slice data);\n\n/**\n * Generate a scrypt hash of specified length.\n *\n * scrypt(data, salt, params)\n */\nBC_API data_chunk scrypt(data_slice data, data_slice salt, uint64_t N,\n                         uint32_t p, uint32_t r, size_t length);\n\n} // namespace libbitcoin\n\n// Extend std and boost namespaces with our hash wrappers.\n\nnamespace libbitcoin\n{\n// by boost 1.58 on ubuntu\n//TODO hash_range cross platform\ntemplate <class It>\nstd::size_t hash_range(It first, It last)\n{\n#ifdef _WIN32\n    return boost::hash_range(first, last);\n#else\n    std::size_t seed = 0;\n    for (; first != last; ++first)\n    {\n        seed ^= *first + 0x9e3779b9 + (seed << 6) + (seed >> 2);\n    }\n    return seed;\n#endif\n}\n} // namespace libbitcoin\n\nnamespace std\n{\ntemplate <size_t Size>\nstruct hash<bc::byte_array<Size>>\n{\n    size_t operator()(const bc::byte_array<Size> &hash) const\n    {\n        return libbitcoin::hash_range(hash.begin(), hash.end());\n    }\n};\n} // namespace std\n\nnamespace boost\n{\ntemplate <size_t Size>\nstruct hash<bc::byte_array<Size>>\n{\n    size_t operator()(const bc::byte_array<Size> &hash) const\n    {\n        return libbitcoin::hash_range(hash.begin(), hash.end());\n    }\n};\n} // namespace boost\n\n#include <UChain/coin/impl/math/hash.ipp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/math/hash_number.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_HASH_NUMBER_HPP\n#define UC_HASH_NUMBER_HPP\n\n#include <cstddef>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/math/uint256.hpp>\n\nnamespace libbitcoin\n{\n\n/**\n * Represents a target hash or proof of work sum.\n * Used for block proof of works to calculate whether they reach\n * a certain target or which chain is longest.\n */\nclass hash_number\n{\n  public:\n    BC_API hash_number();\n    BC_API hash_number(uint64_t value);\n    // Returns false if negative or overflowed.\n    BC_API bool set_compact(uint32_t compact);\n    BC_API uint32_t compact() const;\n    BC_API void set_hash(const hash_digest &hash);\n    BC_API hash_digest hash() const;\n\n    BC_API const hash_number operator~() const;\n\n    // int64_t resolves to this in Satoshi's GetNextWorkRequired()\n    BC_API hash_number &operator*=(uint32_t value);\n    BC_API hash_number &operator/=(uint32_t value);\n    BC_API hash_number &operator<<=(uint32_t shift);\n\n    BC_API hash_number &operator/=(const hash_number &number_b);\n    BC_API hash_number &operator+=(const hash_number &number_b);\n\n  private:\n    friend bool operator>(\n        const hash_number &number_a, const hash_number &number_b);\n    friend bool operator<=(\n        const hash_number &number_a, const hash_number &number_b);\n    friend const hash_number operator<<(\n        const hash_number &number_a, int shift);\n    friend const hash_number operator/(\n        const hash_number &number_a, const hash_number &number_b);\n    friend const hash_number operator+(\n        const hash_number &number_a, const hash_number &number_b);\n    friend bool operator==(\n        const hash_number &number, uint64_t value);\n\n    uint256_t hash_;\n};\n\nBC_API bool operator>(\n    const hash_number &number_a, const hash_number &number_b);\nBC_API bool operator<=(\n    const hash_number &number_a, const hash_number &number_b);\nBC_API const hash_number operator<<(\n    const hash_number &number_a, int shift);\nBC_API const hash_number operator/(\n    const hash_number &number_a, const hash_number &number_b);\nBC_API const hash_number operator+(\n    const hash_number &number_a, const hash_number &number_b);\nBC_API bool operator==(\n    const hash_number &number, uint64_t value);\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/math/script_number.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SCRIPT_NUMBER_HPP\n#define UC_SCRIPT_NUMBER_HPP\n\n#include <cstddef>\n#include <UChain/coin/compat.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\n\nBC_CONSTEXPR size_t max_script_number_size = 4;\nBC_CONSTEXPR size_t cltv_max_script_number_size = 5;\n\n/**\n * Numeric opcodes (OP_1ADD, etc) are restricted to operating on\n * 4-byte integers. The semantics are subtle, though: operands must be\n * in the range [-2^31 +1...2^31 -1], but results may overflow (and are\n * valid as long as they are not used in a subsequent numeric operation).\n *\n * script_number enforces those semantics by storing results as\n * an int64 and allowing out-of-range values to be returned as a vector of\n * bytes but throwing an exception if arithmetic is done or the result is\n * interpreted as an integer.\n */\nclass script_number\n{\n  public:\n    BC_API explicit script_number(const int64_t value);\n\n    // Undefined state. set_data() must be called after.\n    BC_API script_number();\n    BC_API bool set_data(const data_chunk &data,\n                         uint8_t max_size = max_script_number_size);\n\n    BC_API data_chunk data() const;\n    BC_API int32_t int32() const;\n    BC_API int64_t int64() const;\n\n    // Arithmetic with a number.\n    BC_API script_number operator+(const int64_t value) const;\n    BC_API script_number operator-(const int64_t value) const;\n\n    // Arithmetic with another script_number.\n    BC_API script_number operator+(const script_number &other) const;\n    BC_API script_number operator-(const script_number &other) const;\n\n    // -script_number\n    BC_API script_number operator-() const;\n\n    // Comparison operators with a number.\n    BC_API bool operator==(const int64_t value) const;\n    BC_API bool operator!=(const int64_t value) const;\n    BC_API bool operator<=(const int64_t value) const;\n    BC_API bool operator<(const int64_t value) const;\n    BC_API bool operator>=(const int64_t value) const;\n    BC_API bool operator>(const int64_t value) const;\n\n    // Comparison operators with another script_number.\n    BC_API bool operator==(const script_number &other) const;\n    BC_API bool operator!=(const script_number &other) const;\n    BC_API bool operator<=(const script_number &other) const;\n    BC_API bool operator<(const script_number &other) const;\n    BC_API bool operator>=(const script_number &other) const;\n    BC_API bool operator>(const script_number &other) const;\n\n    BC_API script_number &operator+=(const int64_t value);\n    BC_API script_number &operator-=(const int64_t value);\n    BC_API script_number &operator+=(const script_number &other);\n    BC_API script_number &operator-=(const script_number &other);\n\n  private:\n    int64_t value_;\n};\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/math/stealth.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_STEALTH_HPP\n#define UC_STEALTH_HPP\n\n#include <cstdint>\n#include <UChain/coin/chain/script/script.hpp>\n#include <UChain/coin/compat.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/elliptic_curve.hpp>\n#include <UChain/coin/utility/binary.hpp>\n\nnamespace libbitcoin\n{\n\nstatic BC_CONSTEXPR uint8_t ephemeral_public_key_sign = 0x02;\n\n/// Determine if the script is a null-data script of at least 32 data bytes.\nBC_API bool is_stealth_script(const chain::script &script);\n\n/// Convert a stealth info script to a prefix usable for stealth.\nBC_API bool to_stealth_prefix(uint32_t &out_prefix,\n                              const chain::script &script);\n\n/// Create a valid stealth ephemeral private key from the provided seed.\nBC_API bool create_ephemeral_key(ec_secret &out_secret,\n                                 const data_chunk &seed);\n\n/// Create an ephemeral public key from the provided seed with the\n/// null-data script data value that produces the desired filter prefix.\nBC_API bool create_stealth_data(data_chunk &out_stealth_data,\n                                ec_secret &out_secret, const binary &filter, const data_chunk &seed);\n\n/// Extract the stealth ephemeral public key from an output script.\nBC_API bool extract_ephemeral_key(ec_compressed &out_ephemeral_public_key,\n                                  const chain::script &script);\n\n/// Extract the unsigned stealth ephemeral public key from an output script.\nBC_API bool extract_ephemeral_key(hash_digest &out_unsigned_ephemeral_key,\n                                  const chain::script &script);\n\n/// Calculate the shared secret.\nBC_API bool shared_secret(ec_secret &out_shared, const ec_secret &secret,\n                          const ec_compressed &point);\n\n/// Uncover the stealth public key.\nBC_API bool uncover_stealth(ec_compressed &out_stealth,\n                            const ec_compressed &ephemeral_or_scan, const ec_secret &scan_or_ephemeral,\n                            const ec_compressed &spend);\n\n/// Uncover the stealth secret.\nBC_API bool uncover_stealth(ec_secret &out_stealth,\n                            const ec_compressed &ephemeral_or_scan, const ec_secret &scan_or_ephemeral,\n                            const ec_secret &spend);\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/math/uint256.hpp",
    "content": "// Copyright (c) 2009-2010 Satoshi Nakamoto\n// Copyright (c) 2009-2014 The Bitcoin developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#ifndef LIBBBITCOIN_UINT256_HPP\n#define LIBBBITCOIN_UINT256_HPP\n\n#include <cassert>\n#include <cstdint>\n#include <iostream>\n#include <stdexcept>\n#include <string>\n#include <string.h>\n#include <vector>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/assert.hpp>\n\nnamespace libbitcoin\n{\n\nclass BC_API uint_error\n    : public std::runtime_error\n{\n  public:\n    explicit uint_error(const std::string &str) : std::runtime_error(str)\n    {\n    }\n};\n\n/** Template base class for unsigned big integers. */\ntemplate <unsigned int BITS>\nclass BC_API base_uint\n{\n  protected:\n    enum\n    {\n        WIDTH = BITS / 32\n    };\n\n    uint32_t pn[WIDTH];\n\n  public:\n    base_uint()\n    {\n        for (int i = 0; i < WIDTH; i++)\n            pn[i] = 0;\n    }\n\n    base_uint(const base_uint &b)\n    {\n        for (int i = 0; i < WIDTH; i++)\n            pn[i] = b.pn[i];\n    }\n\n    base_uint &operator=(const base_uint &b)\n    {\n        for (int i = 0; i < WIDTH; i++)\n            pn[i] = b.pn[i];\n\n        return *this;\n    }\n\n    base_uint(uint64_t b)\n    {\n        pn[0] = (unsigned int)b;\n        pn[1] = (unsigned int)(b >> 32);\n        for (int i = 2; i < WIDTH; i++)\n            pn[i] = 0;\n    }\n\n    explicit base_uint(const std::vector<unsigned char> &vch);\n\n    bool operator!() const\n    {\n        for (int i = 0; i < WIDTH; i++)\n            if (pn[i] != 0)\n                return false;\n\n        return true;\n    }\n\n    const base_uint operator~() const\n    {\n        base_uint ret;\n        for (int i = 0; i < WIDTH; i++)\n            ret.pn[i] = ~pn[i];\n\n        return ret;\n    }\n\n    const base_uint operator-() const\n    {\n        base_uint ret;\n        for (int i = 0; i < WIDTH; i++)\n            ret.pn[i] = ~pn[i];\n\n        ret++;\n        return ret;\n    }\n\n    base_uint &operator=(uint64_t b)\n    {\n        pn[0] = (unsigned int)b;\n        pn[1] = (unsigned int)(b >> 32);\n        for (int i = 2; i < WIDTH; i++)\n            pn[i] = 0;\n\n        return *this;\n    }\n\n    base_uint &operator^=(const base_uint &b)\n    {\n        for (int i = 0; i < WIDTH; i++)\n            pn[i] ^= b.pn[i];\n\n        return *this;\n    }\n\n    base_uint &operator&=(const base_uint &b)\n    {\n        for (int i = 0; i < WIDTH; i++)\n            pn[i] &= b.pn[i];\n\n        return *this;\n    }\n\n    base_uint &operator|=(const base_uint &b)\n    {\n        for (int i = 0; i < WIDTH; i++)\n            pn[i] |= b.pn[i];\n\n        return *this;\n    }\n\n    base_uint &operator^=(uint64_t b)\n    {\n        pn[0] ^= (unsigned int)b;\n        pn[1] ^= (unsigned int)(b >> 32);\n        return *this;\n    }\n\n    base_uint &operator|=(uint64_t b)\n    {\n        pn[0] |= (unsigned int)b;\n        pn[1] |= (unsigned int)(b >> 32);\n        return *this;\n    }\n\n    base_uint &operator<<=(unsigned int shift);\n    base_uint &operator>>=(unsigned int shift);\n\n    base_uint &operator+=(const base_uint &b)\n    {\n        uint64_t carry = 0;\n        for (int i = 0; i < WIDTH; i++)\n        {\n            uint64_t n = carry + pn[i] + b.pn[i];\n            pn[i] = n & 0xffffffff;\n            carry = n >> 32;\n        }\n\n        return *this;\n    }\n\n    base_uint &operator-=(const base_uint &b)\n    {\n        *this += -b;\n        return *this;\n    }\n\n    base_uint &operator+=(uint64_t b64)\n    {\n        base_uint b;\n        b = b64;\n        *this += b;\n        return *this;\n    }\n\n    base_uint &operator-=(uint64_t b64)\n    {\n        base_uint b;\n        b = b64;\n        *this += -b;\n        return *this;\n    }\n\n    base_uint &operator*=(uint32_t b32);\n    base_uint &operator*=(const base_uint &b);\n    base_uint &operator/=(const base_uint &b);\n\n    base_uint &operator++()\n    {\n        // prefix operator\n        int i = 0;\n        while (++pn[i] == 0 && i < WIDTH - 1)\n            i++;\n\n        return *this;\n    }\n\n    const base_uint operator++(int)\n    {\n        // postfix operator\n        const base_uint ret = *this;\n        ++(*this);\n        return ret;\n    }\n\n    base_uint &operator--()\n    {\n        // prefix operator\n        int i = 0;\n        while (--pn[i] == (uint32_t)-1 && i < WIDTH - 1)\n            i++;\n\n        return *this;\n    }\n\n    const base_uint operator--(int)\n    {\n        // postfix operator\n        const base_uint ret = *this;\n        --(*this);\n\n        return ret;\n    }\n\n    int CompareTo(const base_uint &b) const;\n    bool EqualTo(uint64_t b) const;\n\n    friend inline const base_uint operator+(const base_uint &a, const base_uint &b) { return base_uint(a) += b; }\n    friend inline const base_uint operator-(const base_uint &a, const base_uint &b) { return base_uint(a) -= b; }\n    friend inline const base_uint operator*(const base_uint &a, const base_uint &b) { return base_uint(a) *= b; }\n    friend inline const base_uint operator/(const base_uint &a, const base_uint &b) { return base_uint(a) /= b; }\n    friend inline const base_uint operator|(const base_uint &a, const base_uint &b) { return base_uint(a) |= b; }\n    friend inline const base_uint operator&(const base_uint &a, const base_uint &b) { return base_uint(a) &= b; }\n    friend inline const base_uint operator^(const base_uint &a, const base_uint &b) { return base_uint(a) ^= b; }\n    friend inline const base_uint operator>>(const base_uint &a, int shift) { return base_uint(a) >>= shift; }\n    friend inline const base_uint operator<<(const base_uint &a, int shift) { return base_uint(a) <<= shift; }\n    friend inline const base_uint operator*(const base_uint &a, uint32_t b) { return base_uint(a) *= b; }\n\n    friend inline bool operator==(const base_uint &a, const base_uint &b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) == 0; }\n    friend inline bool operator!=(const base_uint &a, const base_uint &b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) != 0; }\n    friend inline bool operator>(const base_uint &a, const base_uint &b) { return a.CompareTo(b) > 0; }\n    friend inline bool operator<(const base_uint &a, const base_uint &b) { return a.CompareTo(b) < 0; }\n    friend inline bool operator>=(const base_uint &a, const base_uint &b) { return a.CompareTo(b) >= 0; }\n    friend inline bool operator<=(const base_uint &a, const base_uint &b) { return a.CompareTo(b) <= 0; }\n    friend inline bool operator==(const base_uint &a, uint64_t b) { return a.EqualTo(b); }\n    friend inline bool operator!=(const base_uint &a, uint64_t b) { return !a.EqualTo(b); }\n\n    unsigned char *begin()\n    {\n        return (unsigned char *)&pn[0];\n    }\n\n    unsigned char *end()\n    {\n        return (unsigned char *)&pn[WIDTH];\n    }\n\n    const unsigned char *begin() const\n    {\n        return (unsigned char *)&pn[0];\n    }\n\n    const unsigned char *end() const\n    {\n        return (unsigned char *)&pn[WIDTH];\n    }\n\n    unsigned int size() const\n    {\n        return sizeof(pn);\n    }\n\n    /**\n     * Returns the position of the highest bit set plus one, or zero if the\n     * value is zero.\n     */\n    unsigned int bits() const;\n\n    uint64_t GetLow64() const\n    {\n        BITCOIN_ASSERT(WIDTH >= 2);\n        return pn[0] | (uint64_t)pn[1] << 32;\n    }\n};\n\n/** 256-bit unsigned big integer. */\nclass BC_API uint256_t : public base_uint<256>\n{\n  public:\n    uint256_t()\n    {\n    }\n    uint256_t(const base_uint<256> &b) : base_uint<256>(b)\n    {\n    }\n    uint256_t(uint64_t b) : base_uint<256>(b)\n    {\n    }\n\n    explicit uint256_t(const std::vector<unsigned char> &vch)\n        : base_uint<256>(vch)\n    {\n    }\n\n    /**\n     * The \"compact\" format is a representation of a whole\n     * number N using an unsigned 32bit number similar to a\n     * floating point format.\n     * The most significant 8 bits are the unsigned exponent of base 256.\n     * This exponent can be thought of as \"number of bytes of N\".\n     * The lower 23 bits are the mantissa.\n     * Bit number 24 (0x800000) represents the sign of N.\n     * N = (-1^sign) * mantissa * 256^(exponent-3)\n     *\n     * Satoshi's original implementation used BN_bn2mpi() and BN_mpi2bn().\n     * MPI uses the most significant bit of the first byte as sign.\n     * Thus 0x1234560000 is compact (0x05123456)\n     * and  0xc0de000000 is compact (0x0600c0de)\n     *\n     * Bitcoin only uses this \"compact\" format for encoding difficulty\n     * targets, which are unsigned 256bit quantities.  Thus, all the\n     * complexities of the sign bit and using base 256 are probably an\n     * implementation accident.\n     */\n    uint32_t GetCompact(bool fNegative = false) const;\n    uint256_t &SetCompact(uint32_t nCompact, bool *pfNegative = NULL,\n                          bool *pfOverflow = NULL);\n};\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/address.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_ADDRESS_HPP\n#define UC_MESSAGE_ADDRESS_HPP\n\n#include <istream>\n#include <memory>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/message/network_address.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API address\n{\n  public:\n    typedef std::shared_ptr<address> ptr;\n\n    static address factory_from_data(uint32_t version, const data_chunk &data);\n    static address factory_from_data(uint32_t version, std::istream &stream);\n    static address factory_from_data(uint32_t version, reader &source);\n\n    bool from_data(uint32_t version, const data_chunk &data);\n    bool from_data(uint32_t version, std::istream &stream);\n    bool from_data(uint32_t version, reader &source);\n    data_chunk to_data(uint32_t version) const;\n    void to_data(uint32_t version, std::ostream &stream) const;\n    void to_data(uint32_t version, writer &sink) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(uint32_t version) const;\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n\n    network_address::list addresses;\n};\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/alert.hpp",
    "content": "/*\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_ALERT_HPP\n#define UC_MESSAGE_ALERT_HPP\n\n#include <istream>\n#include <memory>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API alert\n{\n  public:\n    typedef std::shared_ptr<alert> ptr;\n\n    static alert factory_from_data(uint32_t version, const data_chunk &data);\n    static alert factory_from_data(uint32_t version, std::istream &stream);\n    static alert factory_from_data(uint32_t version, reader &source);\n\n    bool from_data(uint32_t version, const data_chunk &data);\n    bool from_data(uint32_t version, std::istream &stream);\n    bool from_data(uint32_t version, reader &source);\n    data_chunk to_data(uint32_t version) const;\n    void to_data(uint32_t version, std::ostream &stream) const;\n    void to_data(uint32_t version, writer &sink) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(uint32_t version) const;\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n\n    data_chunk payload;\n    data_chunk signature;\n};\n\nBC_API bool operator==(const alert &left, const alert &right);\nBC_API bool operator!=(const alert &left, const alert &right);\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/alert_payload.hpp",
    "content": "/*\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_ALERT_FORMATTED_PAYLOAD_HPP\n#define UC_MESSAGE_ALERT_FORMATTED_PAYLOAD_HPP\n\n#include <istream>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/elliptic_curve.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API alert_payload\n{\n  public:\n    static alert_payload factory_from_data(uint32_t version,\n                                           const data_chunk &data);\n    static alert_payload factory_from_data(uint32_t version,\n                                           std::istream &stream);\n    static alert_payload factory_from_data(uint32_t version,\n                                           reader &source);\n\n    bool from_data(uint32_t version, const data_chunk &data);\n    bool from_data(uint32_t version, std::istream &stream);\n    bool from_data(uint32_t version, reader &source);\n    data_chunk to_data(uint32_t version) const;\n    void to_data(uint32_t version, std::ostream &stream) const;\n    void to_data(uint32_t version, writer &sink) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(uint32_t version) const;\n\n    static const ec_uncompressed satoshi_public_key;\n\n    uint32_t version;\n    uint64_t relay_until;\n    uint64_t expiration;\n    uint32_t id;\n    uint32_t cancel;\n    std::vector<uint32_t> set_cancel;\n    uint32_t min_version;\n    uint32_t max_version;\n    std::vector<std::string> set_sub_version;\n    uint32_t priority;\n    std::string comment;\n    std::string status_bar;\n    std::string reserved;\n};\n\nBC_API bool operator==(const alert_payload &left, const alert_payload &right);\nBC_API bool operator!=(const alert_payload &left, const alert_payload &right);\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/block_msg.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_block_msg_HPP\n#define UC_MESSAGE_block_msg_HPP\n\n#include <cstdint>\n#include <cstddef>\n#include <istream>\n#include <memory>\n#include <UChain/coin/chain/block.hpp>\n#include <UChain/coin/chain/header.hpp>\n#include <UChain/coin/chain/transaction.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API block_msg\n    : public chain::block\n{\n  public:\n    typedef std::vector<block_msg> list;\n    typedef std::shared_ptr<block_msg> ptr;\n    typedef std::vector<ptr> ptr_list;\n    typedef std::vector<size_t> indexes;\n\n    static block_msg factory_from_data(uint32_t version,\n                                           const data_chunk &data, bool with_transaction_count = true);\n    static block_msg factory_from_data(uint32_t version,\n                                           std::istream &stream, bool with_transaction_count = true);\n    static block_msg factory_from_data(uint32_t version,\n                                           reader &source, bool with_transaction_count = true);\n\n    block_msg();\n    block_msg(const chain::block &other);\n    block_msg(const block_msg &other);\n    block_msg(const chain::header &header,\n                  const chain::transaction::list &transactions);\n\n    block_msg(chain::block &&other);\n    block_msg(block_msg &&other);\n    block_msg(chain::header &&header,\n                  chain::transaction::list &&transactions);\n\n    /// This class is move assignable but not copy assignable.\n    block_msg &operator=(block_msg &&other);\n    void operator=(const block_msg &) = delete;\n\n    bool from_data(uint32_t version, const data_chunk &data,\n                   bool with_transaction_count = true);\n    bool from_data(uint32_t version, std::istream &stream,\n                   bool with_transaction_count = true);\n    bool from_data(uint32_t version, reader &source,\n                   bool with_transaction_count = true);\n    data_chunk to_data(uint32_t version,\n                       bool with_transaction_count = true) const;\n    void to_data(uint32_t version, std::ostream &stream,\n                 bool with_transaction_count = true) const;\n    void to_data(uint32_t version, writer &sink,\n                 bool with_transaction_count = true) const;\n    uint64_t serialized_size(uint32_t version,\n                             bool with_transaction_count = true) const;\n\n    uint64_t originator() const;\n    void set_originator(uint64_t value);\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n\n  private:\n    uint64_t originator_;\n};\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/block_txs.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_block_txs_HPP\n#define UC_MESSAGE_block_txs_HPP\n\n#include <istream>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/chain/transaction.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API block_txs\n{\n  public:\n    typedef std::shared_ptr<block_txs> ptr;\n\n    static block_txs factory_from_data(uint32_t version,\n                                                const data_chunk &data);\n    static block_txs factory_from_data(uint32_t version,\n                                                std::istream &stream);\n    static block_txs factory_from_data(uint32_t version,\n                                                reader &source);\n\n    bool from_data(uint32_t version, const data_chunk &data);\n    bool from_data(uint32_t version, std::istream &stream);\n    bool from_data(uint32_t version, reader &source);\n    data_chunk to_data(uint32_t version) const;\n    void to_data(uint32_t version, std::ostream &stream) const;\n    void to_data(uint32_t version, writer &sink) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(uint32_t version) const;\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n\n    hash_digest block_hash;\n    chain::transaction::list transactions;\n};\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/compact_block.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_COMPACT_BLOCK_HPP\n#define UC_MESSAGE_COMPACT_BLOCK_HPP\n\n#include <istream>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/chain/header.hpp>\n#include <UChain/coin/message/prefilled_tx.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API compact_block\n{\n  public:\n    typedef std::shared_ptr<compact_block> ptr;\n    typedef mini_hash short_id;\n    typedef mini_hash_list short_id_list;\n\n    static compact_block factory_from_data(uint32_t version,\n                                           const data_chunk &data);\n    static compact_block factory_from_data(uint32_t version,\n                                           std::istream &stream);\n    static compact_block factory_from_data(uint32_t version,\n                                           reader &source);\n\n    bool from_data(uint32_t version, const data_chunk &data);\n    bool from_data(uint32_t version, std::istream &stream);\n    bool from_data(uint32_t version, reader &source);\n    data_chunk to_data(uint32_t version) const;\n    void to_data(uint32_t version, std::ostream &stream) const;\n    void to_data(uint32_t version, writer &sink) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(uint32_t version) const;\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n\n    chain::header header;\n    uint64_t nonce;\n    short_id_list short_ids;\n    prefilled_tx::list transactions;\n};\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/fee_filter.hpp",
    "content": "/*\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_FEE_FILTER_HPP\n#define UC_MESSAGE_FEE_FILTER_HPP\n\n#include <cstdint>\n#include <istream>\n#include <memory>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API fee_filter\n{\n  public:\n    typedef std::shared_ptr<fee_filter> ptr;\n\n    static fee_filter factory_from_data(uint32_t version, const data_chunk &data);\n    static fee_filter factory_from_data(uint32_t version, std::istream &stream);\n    static fee_filter factory_from_data(uint32_t version, reader &source);\n    static uint64_t satoshi_fixed_size(uint32_t version);\n\n    fee_filter();\n    fee_filter(uint64_t minimum);\n\n    bool from_data(uint32_t version, const data_chunk &data);\n    bool from_data(uint32_t version, std::istream &stream);\n    bool from_data(uint32_t version, reader &source);\n    data_chunk to_data(uint32_t version) const;\n    void to_data(uint32_t version, std::ostream &stream) const;\n    void to_data(uint32_t version, writer &sink) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(uint32_t version) const;\n\n    bool operator==(const fee_filter &other) const;\n    bool operator!=(const fee_filter &other) const;\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n\n    uint64_t minimum_fee;\n\n  private:\n    bool valid_;\n};\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/filter_add.hpp",
    "content": "/*\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_FILTER_ADD_HPP\n#define UC_MESSAGE_FILTER_ADD_HPP\n\n#include <istream>\n#include <memory>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API filter_add\n{\n  public:\n    typedef std::shared_ptr<filter_add> ptr;\n\n    static filter_add factory_from_data(uint32_t version,\n                                        const data_chunk &data);\n    static filter_add factory_from_data(uint32_t version,\n                                        std::istream &stream);\n    static filter_add factory_from_data(uint32_t version, reader &source);\n\n    bool from_data(uint32_t version, const data_chunk &data);\n    bool from_data(uint32_t version, std::istream &stream);\n    bool from_data(uint32_t version, reader &source);\n    data_chunk to_data(uint32_t version) const;\n    void to_data(uint32_t version, std::ostream &stream) const;\n    void to_data(uint32_t version, writer &sink) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(uint32_t version) const;\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n\n    data_chunk data;\n};\n\nBC_API bool operator==(const filter_add &left, const filter_add &right);\nBC_API bool operator!=(const filter_add &left, const filter_add &right);\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/filter_clear.hpp",
    "content": "/*\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_FILTER_CLEAR_HPP\n#define UC_MESSAGE_FILTER_CLEAR_HPP\n\n#include <istream>\n#include <memory>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API filter_clear\n{\n  public:\n    typedef std::shared_ptr<filter_clear> ptr;\n\n    static filter_clear factory_from_data(uint32_t version,\n                                          const data_chunk &data);\n    static filter_clear factory_from_data(uint32_t version,\n                                          std::istream &stream);\n    static filter_clear factory_from_data(uint32_t version,\n                                          reader &source);\n    static uint64_t satoshi_fixed_size(uint32_t version);\n\n    filter_clear();\n\n    bool from_data(uint32_t version, const data_chunk &data);\n    bool from_data(uint32_t version, std::istream &stream);\n    bool from_data(uint32_t version, reader &source);\n    data_chunk to_data(uint32_t version) const;\n    void to_data(uint32_t version, std::ostream &stream) const;\n    void to_data(uint32_t version, writer &sink) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(uint32_t version) const;\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n\n  private:\n    bool insufficient_version_;\n};\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/filter_load.hpp",
    "content": "/*\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_FILTER_LOAD_HPP\n#define UC_MESSAGE_FILTER_LOAD_HPP\n\n#include <istream>\n#include <memory>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API filter_load\n{\n  public:\n    typedef std::shared_ptr<filter_load> ptr;\n\n    static filter_load factory_from_data(uint32_t version,\n                                         const data_chunk &data);\n    static filter_load factory_from_data(uint32_t version,\n                                         std::istream &stream);\n    static filter_load factory_from_data(uint32_t version,\n                                         reader &source);\n\n    bool from_data(uint32_t version, const data_chunk &data);\n    bool from_data(uint32_t version, std::istream &stream);\n    bool from_data(uint32_t version, reader &source);\n    data_chunk to_data(uint32_t version) const;\n    void to_data(uint32_t version, std::ostream &stream) const;\n    void to_data(uint32_t version, writer &sink) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(uint32_t version) const;\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n\n    data_chunk filter;\n    uint32_t hash_functions;\n    uint32_t tweak;\n    uint8_t flags;\n};\n\nBC_API bool operator==(const filter_load &left, const filter_load &right);\nBC_API bool operator!=(const filter_load &left, const filter_load &right);\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/get_address.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_GET_ADDRESS_HPP\n#define UC_MESSAGE_GET_ADDRESS_HPP\n\n#include <istream>\n#include <memory>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API get_address\n{\n  public:\n    typedef std::shared_ptr<get_address> ptr;\n\n    static get_address factory_from_data(uint32_t version,\n                                         const data_chunk &data);\n    static get_address factory_from_data(uint32_t version,\n                                         std::istream &stream);\n    static get_address factory_from_data(uint32_t version, reader &source);\n    static uint64_t satoshi_fixed_size(uint32_t version);\n\n    bool from_data(uint32_t version, const data_chunk &data);\n    bool from_data(uint32_t version, std::istream &stream);\n    bool from_data(uint32_t version, reader &source);\n    data_chunk to_data(uint32_t version) const;\n    void to_data(uint32_t version, std::ostream &stream) const;\n    void to_data(uint32_t version, writer &sink) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(uint32_t version) const;\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n};\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/get_block_txs.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_GET_block_txs_HPP\n#define UC_MESSAGE_GET_block_txs_HPP\n\n#include <istream>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API get_block_txs\n{\n  public:\n    typedef std::shared_ptr<get_block_txs> ptr;\n\n    static get_block_txs factory_from_data(uint32_t version,\n                                                    const data_chunk &data);\n    static get_block_txs factory_from_data(uint32_t version,\n                                                    std::istream &stream);\n    static get_block_txs factory_from_data(uint32_t version,\n                                                    reader &source);\n\n    bool from_data(uint32_t version, const data_chunk &data);\n    bool from_data(uint32_t version, std::istream &stream);\n    bool from_data(uint32_t version, reader &source);\n    data_chunk to_data(uint32_t version) const;\n    void to_data(uint32_t version, std::ostream &stream) const;\n    void to_data(uint32_t version, writer &sink) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(uint32_t version) const;\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n\n    hash_digest block_hash;\n    std::vector<uint64_t> indexes;\n};\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/get_blocks.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_GET_BLOCKS_HPP\n#define UC_MESSAGE_GET_BLOCKS_HPP\n\n#include <istream>\n#include <memory>\n#include <string>\n#include <vector>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API get_blocks\n{\n  public:\n    typedef std::shared_ptr<get_blocks> ptr;\n\n    static get_blocks factory_from_data(uint32_t version,\n                                        const data_chunk &data);\n    static get_blocks factory_from_data(uint32_t version,\n                                        std::istream &stream);\n    static get_blocks factory_from_data(uint32_t version, reader &source);\n\n    get_blocks();\n    get_blocks(const hash_list &start, const hash_digest &stop);\n    get_blocks(hash_list &&start, hash_digest &&stop);\n\n    virtual bool from_data(uint32_t version, const data_chunk &data);\n    virtual bool from_data(uint32_t version, std::istream &stream);\n    virtual bool from_data(uint32_t version, reader &source);\n    data_chunk to_data(uint32_t version) const;\n    void to_data(uint32_t version, std::ostream &stream) const;\n    void to_data(uint32_t version, writer &sink) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(uint32_t version) const;\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n\n    // 10 sequential hashes, then exponential samples until reaching genesis.\n    hash_list start_hashes;\n    hash_digest stop_hash;\n};\n\nBC_API bool operator==(const get_blocks &left, const get_blocks &right);\nBC_API bool operator!=(const get_blocks &left, const get_blocks &right);\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/get_data.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_GET_DATA_HPP\n#define UC_MESSAGE_GET_DATA_HPP\n\n#include <initializer_list>\n#include <memory>\n#include <istream>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/message/inventory.hpp>\n#include <UChain/coin/message/inventory_vector.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API get_data\n    : public inventory\n{\n  public:\n    typedef std::shared_ptr<get_data> ptr;\n\n    static get_data factory_from_data(uint32_t version,\n                                      const data_chunk &data);\n    static get_data factory_from_data(uint32_t version, std::istream &stream);\n    static get_data factory_from_data(uint32_t version, reader &source);\n\n    get_data();\n    get_data(const inventory_vector::list &list);\n    get_data(const hash_list &hashes, inventory::type_id type);\n    get_data(const std::initializer_list<inventory_vector> &elements);\n\n    bool from_data(uint32_t version, const data_chunk &data) override;\n    bool from_data(uint32_t version, std::istream &stream) override;\n    bool from_data(uint32_t version, reader &source) override;\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n};\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/get_headers.hpp",
    "content": "/*\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_GET_HEADERS_HPP\n#define UC_MESSAGE_GET_HEADERS_HPP\n\n#include <istream>\n#include <memory>\n#include <string>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/message/get_blocks.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API get_headers\n    : public get_blocks\n{\n  public:\n    typedef std::shared_ptr<get_headers> ptr;\n\n    static get_headers factory_from_data(uint32_t version,\n                                         const data_chunk &data);\n    static get_headers factory_from_data(uint32_t version,\n                                         std::istream &stream);\n    static get_headers factory_from_data(uint32_t version, reader &source);\n\n    get_headers();\n    get_headers(const hash_list &start, const hash_digest &stop);\n    get_headers(hash_list &&start, hash_digest &&stop);\n\n    bool from_data(uint32_t version, const data_chunk &data) override;\n    bool from_data(uint32_t version, std::istream &stream) override;\n    bool from_data(uint32_t version, reader &source) override;\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n};\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/headers.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_HEADERS_HPP\n#define UC_MESSAGE_HEADERS_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <initializer_list>\n#include <istream>\n#include <memory>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/chain/header.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/message/inventory.hpp>\n#include <UChain/coin/message/inventory_vector.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API headers\n{\n  public:\n    typedef std::shared_ptr<headers> ptr;\n\n    static headers factory_from_data(uint32_t version, const data_chunk &data);\n    static headers factory_from_data(uint32_t version, std::istream &stream);\n    static headers factory_from_data(uint32_t version, reader &source);\n\n    headers();\n    headers(const chain::header::list &values);\n    headers(const std::initializer_list<chain::header> &values);\n\n    bool from_data(uint32_t version, const data_chunk &data);\n    bool from_data(uint32_t version, std::istream &stream);\n    bool from_data(uint32_t version, reader &source);\n    data_chunk to_data(uint32_t version) const;\n    void to_data(uint32_t version, std::ostream &stream) const;\n    void to_data(uint32_t version, writer &sink) const;\n    void to_hashes(hash_list &out) const;\n    void to_inventory(inventory_vector::list &out,\n                      inventory::type_id type) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(uint32_t version) const;\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n\n    chain::header::list elements;\n};\n\nBC_API bool operator==(const headers &left, const headers &right);\nBC_API bool operator!=(const headers &left, const headers &right);\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/heading.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_HEADING_HPP\n#define UC_MESSAGE_HEADING_HPP\n\n#include <cstdint>\n#include <cstddef>\n#include <istream>\n#include <string>\n#include <boost/array.hpp>\n#include <UChain/coin/constants.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/checksum.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nenum class message_type\n{\n    unknown,\n    address,\n    alert,\n    block_msg,\n    block_txs,\n    compact_block,\n    fee_filter,\n    filter_add,\n    filter_clear,\n    filter_load,\n    get_address,\n    get_block_txs,\n    get_blocks,\n    get_data,\n    get_headers,\n    headers,\n    inventory,\n    memory_pool,\n    merkle_block,\n    not_found,\n    ping,\n    pong,\n    reject,\n    send_compact_blocks,\n    send_headers,\n    tx_message,\n    verack,\n    version\n};\n\nclass BC_API heading\n{\n  public:\n    static size_t maximum_size();\n    static size_t maximum_payload_size(uint32_t version);\n    static size_t serialized_size();\n    static heading factory_from_data(const data_chunk &data);\n    static heading factory_from_data(std::istream &stream);\n    static heading factory_from_data(reader &source);\n\n    bool from_data(const data_chunk &data);\n    bool from_data(std::istream &stream);\n    bool from_data(reader &source);\n    data_chunk to_data() const;\n    void to_data(std::ostream &stream) const;\n    void to_data(writer &sink) const;\n    bool is_valid() const;\n    void reset();\n    message_type type() const;\n\n    uint32_t magic;\n    std::string command;\n    uint32_t payload_size;\n    uint32_t checksum;\n};\n\nBC_API bool operator==(const heading &left, const heading &right);\nBC_API bool operator!=(const heading &left, const heading &right);\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/inventory.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_INVENTORY_HPP\n#define UC_MESSAGE_INVENTORY_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <initializer_list>\n#include <istream>\n#include <memory>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/message/inventory_vector.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API inventory\n{\n  public:\n    typedef std::shared_ptr<inventory> ptr;\n    typedef inventory_vector::type_id type_id;\n\n    static inventory factory_from_data(uint32_t version,\n                                       const data_chunk &data);\n    static inventory factory_from_data(uint32_t version, std::istream &stream);\n    static inventory factory_from_data(uint32_t version, reader &source);\n\n    inventory();\n    inventory(const inventory_vector::list &values);\n    inventory(const hash_list &hashes, type_id type);\n    inventory(const std::initializer_list<inventory_vector> &values);\n\n    virtual bool from_data(uint32_t version, const data_chunk &data);\n    virtual bool from_data(uint32_t version, std::istream &stream);\n    virtual bool from_data(uint32_t version, reader &source);\n    data_chunk to_data(uint32_t version) const;\n    void to_data(uint32_t version, std::ostream &stream) const;\n    void to_data(uint32_t version, writer &sink) const;\n    void to_hashes(hash_list &out, type_id type) const;\n    void reduce(inventory_vector::list &out, type_id type) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(uint32_t version) const;\n    size_t count(type_id type) const;\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n\n    inventory_vector::list inventories;\n};\n\nBC_API bool operator==(const inventory &left, const inventory &right);\nBC_API bool operator!=(const inventory &left, const inventory &right);\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/inventory_vector.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_INVENTORY_VECTOR_HPP\n#define UC_MESSAGE_INVENTORY_VECTOR_HPP\n\n#include <istream>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API inventory_vector\n{\n  public:\n    typedef std::vector<inventory_vector> list;\n\n    enum class type_id\n    {\n        error,\n        transaction,\n        block,\n        filtered_block,\n        compact_block,\n        none\n    };\n\n    static type_id to_type(uint32_t value);\n    static uint32_t to_number(type_id type);\n\n    static inventory_vector factory_from_data(uint32_t version,\n                                              const data_chunk &data);\n    static inventory_vector factory_from_data(uint32_t version,\n                                              std::istream &stream);\n    static inventory_vector factory_from_data(uint32_t version,\n                                              reader &source);\n    static uint64_t satoshi_fixed_size(uint32_t version);\n\n    bool from_data(uint32_t version, const data_chunk &data);\n    bool from_data(uint32_t version, std::istream &stream);\n    bool from_data(uint32_t version, reader &source);\n    data_chunk to_data(uint32_t version) const;\n    void to_data(uint32_t version, std::ostream &stream) const;\n    void to_data(uint32_t version, writer &sink) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(uint32_t version) const;\n    bool is_block_type() const;\n    bool is_transaction_type() const;\n\n    type_id type;\n    hash_digest hash;\n};\n\nBC_API bool operator==(const inventory_vector &left,\n                       const inventory_vector &right);\nBC_API bool operator!=(const inventory_vector &left,\n                       const inventory_vector &right);\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/memory_pool.hpp",
    "content": "/*\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_MEMORY_POOL_HPP\n#define UC_MESSAGE_MEMORY_POOL_HPP\n\n#include <istream>\n#include <memory>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API memory_pool\n{\n  public:\n    typedef std::shared_ptr<memory_pool> ptr;\n\n    static memory_pool factory_from_data(uint32_t version,\n                                         const data_chunk &data);\n    static memory_pool factory_from_data(uint32_t version,\n                                         std::istream &stream);\n    static memory_pool factory_from_data(uint32_t version, reader &source);\n    static uint64_t satoshi_fixed_size(uint32_t version);\n\n    memory_pool();\n\n    bool from_data(uint32_t version, const data_chunk &data);\n    bool from_data(uint32_t version, std::istream &stream);\n    bool from_data(uint32_t version, reader &source);\n    data_chunk to_data(uint32_t version) const;\n    void to_data(uint32_t version, std::ostream &stream) const;\n    void to_data(uint32_t version, writer &sink) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(uint32_t version) const;\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n\n  private:\n    bool insufficient_version_;\n};\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/merkle_block.hpp",
    "content": "/*\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_MERKLE_BLOCK_HPP\n#define UC_MESSAGE_MERKLE_BLOCK_HPP\n\n#include <istream>\n#include <memory>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/chain/header.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API merkle_block\n{\n  public:\n    typedef std::shared_ptr<merkle_block> ptr;\n    typedef std::vector<merkle_block> list;\n\n    static merkle_block factory_from_data(uint32_t version,\n                                          const data_chunk &data);\n    static merkle_block factory_from_data(uint32_t version,\n                                          std::istream &stream);\n    static merkle_block factory_from_data(uint32_t version, reader &source);\n\n    bool from_data(uint32_t version, const data_chunk &data);\n    bool from_data(uint32_t version, std::istream &stream);\n    bool from_data(uint32_t version, reader &source);\n    data_chunk to_data(uint32_t version) const;\n    void to_data(uint32_t version, std::ostream &stream) const;\n    void to_data(uint32_t version, writer &sink) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(uint32_t version) const;\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n\n    chain::header header;\n    hash_list hashes;\n    data_chunk flags;\n};\n\nBC_API bool operator==(const merkle_block &left, const merkle_block &right);\nBC_API bool operator!=(const merkle_block &left, const merkle_block &right);\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/network_address.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_NETWORK_ADDRESS_HPP\n#define UC_MESSAGE_NETWORK_ADDRESS_HPP\n\n#include <cstdint>\n#include <istream>\n#include <vector>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\ntypedef byte_array<16> ip_address;\n\nBC_CONSTEXPR ip_address localhost_ip_address =\n    {\n        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n        0x00, 0x00, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x01};\n\nclass BC_API network_address\n{\n  public:\n    typedef std::vector<network_address> list;\n\n    static network_address factory_from_data(uint32_t version,\n                                             const data_chunk &data, bool with_timestamp /*= true*/);\n    static network_address factory_from_data(uint32_t version,\n                                             std::istream &stream, bool with_timestamp /*= true*/);\n    static network_address factory_from_data(uint32_t version,\n                                             reader &source, bool with_timestamp /*=true*/);\n    static uint64_t satoshi_fixed_size(uint32_t version,\n                                       bool with_timestamp /*= false*/);\n\n    bool from_data(uint32_t version, const data_chunk &data,\n                   bool with_timestamp /*= true*/);\n    bool from_data(uint32_t version, std::istream &stream,\n                   bool with_timestamp /*= true*/);\n    bool from_data(uint32_t version, reader &source,\n                   bool with_timestamp /*= true*/);\n    data_chunk to_data(uint32_t version,\n                       bool with_timestamp /*= true*/) const;\n    void to_data(uint32_t version, std::ostream &stream,\n                 bool with_timestamp /*= true*/) const;\n    void to_data(uint32_t version, writer &sink,\n                 bool with_timestamp /*= true*/) const;\n    bool is_valid() const;\n\n    unsigned int get_byte(int n) const;\n    bool is_ipv4() const; // IPv4 mapped address (::FFFF:0:0/96, 0.0.0.0/0)\n    bool is_ipv6() const; // IPv6 address (not mapped IPv4, not Tor)\n    bool is_private_network();\n    bool is_RFC1918() const; // IPv4 private networks (10.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12)\n    bool is_RFC3849() const; // IPv6 documentation address (2001:0DB8::/32)\n    bool is_RFC3927() const; // IPv4 autoconfig (169.254.0.0/16)\n    bool is_RFC3964() const; // IPv6 6to4 tunnelling (2002::/16)\n    bool is_RFC4193() const; // IPv6 unique local (FC00::/15)\n    bool is_RFC4380() const; // IPv6 Teredo tunnelling (2001::/32)\n    bool is_RFC4843() const; // IPv6 ORCHID (2001:10::/28)\n    bool is_RFC4862() const; // IPv6 autoconfig (FE80::/64)\n    bool is_RFC6052() const; // IPv6 well-known prefix (64:FF9B::/96)\n    bool is_RFC6145() const; // IPv6 IPv4-translated address (::FFFF:0:0:0/96)\n    bool is_tor() const;\n    bool is_local() const;\n    bool is_routable() const;\n    bool is_ulticast() const;\n\n    void reset();\n    uint64_t serialized_size(uint32_t version,\n                             bool with_timestamp /*= false*/) const;\n\n    // Starting version 31402, addresses are prefixed with a timestamp.\n    uint32_t timestamp;\n    uint64_t services;\n    ip_address ip;\n    uint16_t port;\n};\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/not_found.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_NOT_FOUND_HPP\n#define UC_MESSAGE_NOT_FOUND_HPP\n\n#include <initializer_list>\n#include <istream>\n#include <memory>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/constants.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/message/inventory.hpp>\n#include <UChain/coin/message/inventory_vector.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API not_found\n    : public inventory\n{\n  public:\n    typedef std::shared_ptr<not_found> ptr;\n\n    static not_found factory_from_data(uint32_t version,\n                                       const data_chunk &data);\n    static not_found factory_from_data(uint32_t version, std::istream &stream);\n    static not_found factory_from_data(uint32_t version, reader &source);\n\n    not_found();\n    not_found(const inventory_vector::list &values);\n    not_found(const hash_list &hashes, inventory::type_id type);\n    not_found(const std::initializer_list<inventory_vector> &values);\n\n    bool from_data(uint32_t version, const data_chunk &data) override;\n    bool from_data(uint32_t version, std::istream &stream) override;\n    bool from_data(uint32_t version, reader &source) override;\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n};\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/ping.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_PING_HPP\n#define UC_MESSAGE_PING_HPP\n\n#include <cstdint>\n#include <istream>\n#include <memory>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API ping\n{\n  public:\n    typedef std::shared_ptr<ping> ptr;\n\n    static ping factory_from_data(uint32_t version, const data_chunk &data);\n    static ping factory_from_data(uint32_t version, std::istream &stream);\n    static ping factory_from_data(uint32_t version, reader &source);\n    static uint64_t satoshi_fixed_size(uint32_t version);\n\n    ping();\n    ping(uint64_t nonce);\n\n    bool from_data(uint32_t version, const data_chunk &data);\n    bool from_data(uint32_t version, std::istream &stream);\n    bool from_data(uint32_t version, reader &source);\n\n    data_chunk to_data(uint32_t version) const;\n    void to_data(uint32_t version, std::ostream &stream) const;\n    void to_data(uint32_t version, writer &sink) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(uint32_t version) const;\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n\n    uint64_t nonce;\n\n  private:\n    bool valid_;\n};\n\nBC_API bool operator==(const ping &left, const ping &right);\nBC_API bool operator!=(const ping &left, const ping &right);\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/pong.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_PONG_HPP\n#define UC_MESSAGE_PONG_HPP\n\n#include <cstdint>\n#include <istream>\n#include <memory>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API pong\n{\n  public:\n    typedef std::shared_ptr<pong> ptr;\n\n    static pong factory_from_data(uint32_t version, const data_chunk &data);\n    static pong factory_from_data(uint32_t version, std::istream &stream);\n    static pong factory_from_data(uint32_t version, reader &source);\n    static uint64_t satoshi_fixed_size(uint32_t version);\n\n    bool from_data(uint32_t version, const data_chunk &data);\n    bool from_data(uint32_t version, std::istream &stream);\n    bool from_data(uint32_t version, reader &source);\n\n    data_chunk to_data(uint32_t version) const;\n    void to_data(uint32_t version, std::ostream &stream) const;\n    void to_data(uint32_t version, writer &sink) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(uint32_t version) const;\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n\n    uint64_t nonce;\n};\n\nBC_API bool operator==(const pong &left, const pong &right);\nBC_API bool operator!=(const pong &left, const pong &right);\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/prefilled_tx.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_prefilled_tx_HPP\n#define UC_MESSAGE_prefilled_tx_HPP\n\n#include <istream>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/chain/transaction.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API prefilled_tx\n{\n  public:\n    typedef std::vector<prefilled_tx> list;\n\n    static prefilled_tx factory_from_data(uint32_t version,\n                                                   const data_chunk &data);\n    static prefilled_tx factory_from_data(uint32_t version,\n                                                   std::istream &stream);\n    static prefilled_tx factory_from_data(uint32_t version,\n                                                   reader &source);\n\n    bool from_data(uint32_t version, const data_chunk &data);\n    bool from_data(uint32_t version, std::istream &stream);\n    bool from_data(uint32_t version, reader &source);\n    data_chunk to_data(uint32_t version) const;\n    void to_data(uint32_t version, std::ostream &stream) const;\n    void to_data(uint32_t version, writer &sink) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(uint32_t version) const;\n\n    uint64_t index;\n    chain::transaction transaction;\n};\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/reject.hpp",
    "content": "/*\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_REJECT_HPP\n#define UC_MESSAGE_REJECT_HPP\n\n#include <cstdint>\n#include <istream>\n#include <memory>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API reject\n{\n  public:\n    enum class error_code : uint8_t\n    {\n        undefined = 0x00,\n        malformed = 0x01,\n        invalid = 0x10,\n        obsolete = 0x11,\n        duplicate = 0x12,\n        nonstandard = 0x40,\n        dust = 0x41,\n        insufficient_fee = 0x42,\n        checkpoint = 0x43\n    };\n\n    typedef std::shared_ptr<reject> ptr;\n\n    static reject factory_from_data(uint32_t version, const data_chunk &data);\n    static reject factory_from_data(uint32_t version, std::istream &stream);\n    static reject factory_from_data(uint32_t version, reader &source);\n\n    bool from_data(uint32_t version, const data_chunk &data);\n    bool from_data(uint32_t version, std::istream &stream);\n    bool from_data(uint32_t version, reader &source);\n    data_chunk to_data(uint32_t version) const;\n    void to_data(uint32_t version, std::ostream &stream) const;\n    void to_data(uint32_t version, writer &sink) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(uint32_t version) const;\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n\n    std::string message;\n    error_code code;\n    std::string reason;\n    hash_digest data;\n\n  private:\n    static error_code error_code_from_byte(uint8_t byte);\n    static uint8_t error_code_to_byte(const error_code code);\n};\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/send_compact_blocks.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_SEND_COMPACT_BLOCKS_HPP\n#define UC_MESSAGE_SEND_COMPACT_BLOCKS_HPP\n\n#include <istream>\n#include <memory>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API send_compact_blocks\n{\n  public:\n    typedef std::shared_ptr<send_compact_blocks> ptr;\n\n    static send_compact_blocks factory_from_data(uint32_t version,\n                                                 const data_chunk &data);\n    static send_compact_blocks factory_from_data(uint32_t version,\n                                                 std::istream &stream);\n    static send_compact_blocks factory_from_data(uint32_t version,\n                                                 reader &source);\n    static uint64_t satoshi_fixed_size(uint32_t version);\n\n    bool from_data(uint32_t version, const data_chunk &data);\n    bool from_data(uint32_t version, std::istream &stream);\n    bool from_data(uint32_t version, reader &source);\n    data_chunk to_data(uint32_t version) const;\n    void to_data(uint32_t version, std::ostream &stream) const;\n    void to_data(uint32_t version, writer &sink) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(uint32_t version) const;\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n\n    bool high_bandwidth_mode;\n    uint64_t version;\n};\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/send_headers.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_SEND_HEADERS_HPP\n#define UC_MESSAGE_SEND_HEADERS_HPP\n\n#include <istream>\n#include <memory>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nclass BC_API send_headers\n{\n  public:\n    typedef std::shared_ptr<send_headers> ptr;\n\n    static send_headers factory_from_data(uint32_t version,\n                                          const data_chunk &data);\n    static send_headers factory_from_data(uint32_t version,\n                                          std::istream &stream);\n    static send_headers factory_from_data(uint32_t version,\n                                          reader &source);\n    static uint64_t satoshi_fixed_size(uint32_t version);\n\n    send_headers();\n\n    bool from_data(uint32_t version, const data_chunk &data);\n    bool from_data(uint32_t version, std::istream &stream);\n    bool from_data(uint32_t version, reader &source);\n    data_chunk to_data(uint32_t version) const;\n    void to_data(uint32_t version, std::ostream &stream) const;\n    void to_data(uint32_t version, writer &sink) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(uint32_t version) const;\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n\n  private:\n    bool version_unsupported_;\n};\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/verack.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_VERACK_HPP\n#define UC_MESSAGE_VERACK_HPP\n\n#include <istream>\n#include <memory>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\n// The checksum is ignored by the verack command.\nclass BC_API verack\n{\n  public:\n    typedef std::shared_ptr<verack> ptr;\n\n    static verack factory_from_data(uint32_t version, const data_chunk &data);\n    static verack factory_from_data(uint32_t version, std::istream &stream);\n    static verack factory_from_data(uint32_t version, reader &source);\n    static uint64_t satoshi_fixed_size(uint32_t version);\n\n    bool from_data(uint32_t version, const data_chunk &data);\n    bool from_data(uint32_t version, std::istream &stream);\n    bool from_data(uint32_t version, reader &source);\n    data_chunk to_data(uint32_t version) const;\n    void to_data(uint32_t version, std::ostream &stream) const;\n    void to_data(uint32_t version, writer &sink) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(uint32_t version) const;\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n};\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/message/version.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGE_ANNOUNCE_VERSION_HPP\n#define UC_MESSAGE_ANNOUNCE_VERSION_HPP\n\n#include <cstdint>\n#include <istream>\n#include <memory>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/constants.hpp>\n#include <UChain/coin/message/network_address.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\n// The checksum is ignored by the version command.\nclass BC_API version\n{\n  public:\n    typedef std::shared_ptr<version> ptr;\n\n    enum level : uint32_t\n    {\n        // This is currently unspecified.\n        bip152 = 70014,\n\n        // fee_filter\n        bip133 = 70013,\n\n        // send_headers\n        bip130 = 70012,\n\n        // reject (AND version.relay)\n        bip61 = 70002,\n\n        // filters, merkle_block, not_found (NOT version.relay)\n        bip37 = 70001,\n\n        // memory_pool\n        bip35 = 60002,\n\n        // ping.nonce, pong\n        bip31 = 60001,\n\n        // This preceded the BIP system.\n        headers = 31800,\n\n        // We require at least this of peers.\n        minimum = 31402,\n\n        // We support at most this internally (bound to settings default).\n        maximum = bip130\n    };\n\n    static version factory_from_data(uint32_t version, const data_chunk &data);\n    static version factory_from_data(uint32_t version, std::istream &stream);\n    static version factory_from_data(uint32_t version, reader &source);\n\n    bool from_data(uint32_t version, const data_chunk &data);\n    bool from_data(uint32_t version, std::istream &stream);\n    bool from_data(uint32_t version, reader &source);\n    data_chunk to_data(uint32_t version) const;\n    void to_data(uint32_t version, std::ostream &stream) const;\n    void to_data(uint32_t version, writer &sink) const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size(uint32_t version) const;\n\n    static const std::string command;\n    static const uint32_t version_minimum;\n    static const uint32_t version_maximum;\n\n    uint32_t value;\n    uint64_t services;\n    uint64_t timestamp;\n    network_address address_recevier;\n    network_address address_sender;\n    uint64_t nonce;\n    std::string user_agent;\n    uint32_t start_height;\n\n    // version >= 70001\n    bool relay;\n};\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/messages.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MESSAGES_HPP\n#define UC_MESSAGES_HPP\n\n#include <cstdint>\n#include <UChain/coin/message/address.hpp>\n#include <UChain/coin/message/block_msg.hpp>\n#include <UChain/coin/message/block_txs.hpp>\n#include <UChain/coin/message/compact_block.hpp>\n#include <UChain/coin/message/fee_filter.hpp>\n#include <UChain/coin/message/filter_add.hpp>\n#include <UChain/coin/message/filter_clear.hpp>\n#include <UChain/coin/message/filter_load.hpp>\n#include <UChain/coin/message/get_address.hpp>\n#include <UChain/coin/message/get_block_txs.hpp>\n#include <UChain/coin/message/get_blocks.hpp>\n#include <UChain/coin/message/get_data.hpp>\n#include <UChain/coin/message/get_headers.hpp>\n#include <UChain/coin/message/headers.hpp>\n#include <UChain/coin/message/heading.hpp>\n#include <UChain/coin/message/inventory.hpp>\n#include <UChain/coin/message/inventory_vector.hpp>\n#include <UChain/coin/message/memory_pool.hpp>\n#include <UChain/coin/message/merkle_block.hpp>\n#include <UChain/coin/message/network_address.hpp>\n#include <UChain/coin/message/not_found.hpp>\n#include <UChain/coin/message/ping.hpp>\n#include <UChain/coin/message/pong.hpp>\n#include <UChain/coin/message/reject.hpp>\n#include <UChain/coin/message/send_compact_blocks.hpp>\n#include <UChain/coin/message/send_headers.hpp>\n#include <UChain/coin/message/tx_msg.hpp>\n#include <UChain/coin/message/verack.hpp>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/utility/data.hpp>\n\n// Minimum conditional protocol version: 31800\n\n// libbitcoin-network\n// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n// version      v2      70001           added relay field\n// verack       v1\n// getaddr      v1\n// addr         v1\n// ping         v1\n// ping         v2      60001   BIP031  added nonce field\n// pong         v1      60001   BIP031\n// reject       v3      70002   BIP061\n// ----------------------------------------------------------------------------\n// alert        --                      no intent to support\n// checkorder   --                      obsolete\n// reply        --                      obsolete\n// submitorder  --                      obsolete\n// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n// libbitcoin-node\n// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n// getblocks    v1\n// inv          v1\n// getdata      v1\n// getdata      v3      70001   BIP037  allows filtered_block flag\n// block        v1\n// tx           v1\n// notfound     v2      70001\n// getheaders   v3      31800\n// headers      v3      31800\n// mempool      --      60002   BIP035\n// mempool      v3      70002           allow multiple inv messages in reply\n// sendheaders  v3      70012   BIP130\n// feefilter    v3      70013   BIP133\n// blocktxn     v3      70014   BIP152\n// cmpctblock   v3      70014   BIP152\n// getblocktxn  v3      70014   BIP152\n// sendcmpct    v3      70014   BIP152\n// merkleblock  v3      70001   BIP037  no bloom filters so unfiltered only\n// ----------------------------------------------------------------------------\n// filterload   --      70001   BIP037  no intent to support\n// filteradd    --      70001   BIP037  no intent to support\n// filterclear  --      70001   BIP037  no intent to support\n// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\n/**\n* Serialize a message object to the Bitcoin wire protocol encoding.\n*/\ntemplate <typename Message>\ndata_chunk serialize(uint32_t version, const Message &packet,\n                     uint32_t magic)\n{\n    // Serialize the payload (required for header size).\n    const auto payload = packet.to_data(version);\n\n    // Construct the payload header.\n    heading head;\n    head.magic = magic;\n    head.command = Message::command;\n    head.payload_size = static_cast<uint32_t>(payload.size());\n    head.checksum = bitcoin_checksum(payload);\n\n    // Serialize header and copy the payload into a single message buffer.\n    auto message = head.to_data();\n    extend_data(message, payload);\n    return message;\n}\n\n} // namespace message\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/unicode/console_streambuf.hpp",
    "content": "﻿/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CONSOLE_STREAMBUF_HPP\n#define UC_CONSOLE_STREAMBUF_HPP\n\n#include <cstddef>\n#include <streambuf>\n#include <UChain/coin/define.hpp>\n\nnamespace libbitcoin\n{\n\n/**\n * Class to patch Windows stdin keyboard input, file input is not a problem.\n * This class and members are no-ops when called in non-MSVC++ builds.\n */\nclass BC_API console_streambuf\n    : public std::wstreambuf\n{\n  public:\n    /**\n     * Initialize stdio to use utf8 translation on Windows.\n     * @param[in]  size  The stream buffer size.\n     */\n    static void initialize(size_t size);\n\n  protected:\n    /**\n     * Protected construction, use static initialize method.\n     * @param[in]  stream_buffer  The stream buffer to patch.\n     * @param[in]  size           The stream buffer size.\n     */\n    console_streambuf(std::wstreambuf const &stream_buffer, size_t size);\n\n    /**\n     * Delete stream buffer.\n     */\n    virtual ~console_streambuf();\n\n    /**\n     * Implement alternate console read.\n     * @param[in]  buffer  Pointer to the buffer to fill with console reads.\n     * @param[in]  size    The size of the buffer that may be populated.\n     */\n    virtual std::streamsize xsgetn(wchar_t *buffer, std::streamsize size);\n\n    /**\n     * Implement alternate console read.\n     */\n    virtual std::wstreambuf::int_type underflow();\n\n  private:\n    // The constructed buffer size.\n    size_t buffer_size_;\n\n    // The dynamically-allocated buffers.\n    wchar_t *buffer_;\n};\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/unicode/ifstream.hpp",
    "content": "﻿/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_IFSTREAM_HPP\n#define UC_IFSTREAM_HPP\n\n#include <fstream>\n#include <string>\n#include <UChain/coin/define.hpp>\n\nnamespace libbitcoin\n{\n\n/**\n * Use bc::ifstream in place of std::ifstream.\n * This provides utf8 to utf16 path translation for Windows.\n */\nclass BC_API ifstream\n    : public std::ifstream\n{\npublic:\n  /**\n     * Construct bc::ifstream.\n     * @param[in]  path  The utf8 path to the file.\n     * @param[in]  mode  The file opening mode.\n     */\n  ifstream(const std::string &path,\n           std::ifstream::openmode mode = std::ifstream::in);\n};\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/unicode/ofstream.hpp",
    "content": "﻿/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_OFSTREAM_HPP\n#define UC_OFSTREAM_HPP\n\n#include <fstream>\n#include <string>\n#include <UChain/coin/define.hpp>\n\nnamespace libbitcoin\n{\n\nconst uint64_t LOG_MAX_SIZE = 1024 * 1024 * 512;\n/**\n * Use bc::ofstream in place of std::ofstream.\n * This provides utf8 to utf16 path translation for Windows.\n */\nclass BC_API ofstream\n    : public std::ofstream\n{\n  public:\n    /**\n     * Construct bc::ofstream.\n     * @param[in]  path  The utf8 path to the file.\n     * @param[in]  mode  The file opening mode.\n     */\n    ofstream(const std::string &path,\n             std::ofstream::openmode mode = std::ofstream::out);\n\n    std::string path() const;\n    uint64_t max_size() const;\n    uint64_t &current_size();\n    uint64_t increment(uint64_t size);\n\n  private:\n    std::string path_;\n    uint64_t current_size_;\n    uint64_t max_size_;\n};\n\ninline std::string ofstream::path() const\n{\n    return path_;\n}\n\ninline uint64_t ofstream::max_size() const\n{\n    return max_size_;\n}\n\ninline uint64_t &ofstream::current_size()\n{\n    return current_size_;\n}\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/unicode/unicode.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_UNICODE_HPP\n#define UC_UNICODE_HPP\n\n#include <cstddef>\n#include <iostream>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n\n// Regarding Unicode design for Windows:\n//\n// Windows and other environments, such as Java, that supported Unicode prior\n// to the advent of utf8 utilize 16 bit characters. These are typically encoded\n// as wchar_t in C++. Unicode no longer fits in 16 bits and as such these\n// implementations now require variable length character encoding just as utf8.\n//\n// Libbitcoin embraces the \"utf8 everywhere\" design: http://utf8everywhere.org\n// The objective is to use utf8 as the canonical string encoding, pushing\n// wchar_t translation to the edge (stdio, argv, O/S and external API calls).\n// The macro BC_USE_UC_MAIN does most of the heavy lifting to ensure\n// that stdio and argv is configured for utf8. The 'to_utf' functions are\n// provided for API translations.\n\n// Regarding Unicode source files in VC++ builds:\n//\n// Don't use #pragma execution_character_set(\"utf-8\") in Windows.\n// This instruction causes sources to be explicitly interpreted as UTF8.\n// However this technique improperly encodes literals (\"フ\" for example).\n// Instead use non-BOM UTF encoded files. To do this use \"save as...\"\n// utf8 without a \"signature\" (BOM) in the Visual Studio save dialog.\n// This is the typical file format for C++ sources in other environments.\n\n// Regarding Unicode in console applications:\n//\n// BC_USE_UC_MAIN should be declared prior to bc::main() in a console\n// application. This enables Unicode argument and environment processing in\n// Windows. This macro implements main() and forwards to bc::main(), which\n// should be implemented as if it was main() with the expectation that argv\n// is utf8.\n//\n// Do not use std::cout|std::cerr|std::cin (aborts on assertion):\n// std::cout << \"text\";\n// std::cerr << \"text\";\n// std::string text;\n// std::cin >> text;\n//\n// Do not use the L qualifier when source is UTF-8 w/out BOM (mangles output):\n// const auto utf16 = L\"acción.кошка.日本国\";\n// std::wcout << utf16;\n\n// Regarding use of boost:\n//\n// When working with boost and utf8 narrow characters on Windows the thread\n// must be configured for utf8. When working with boost::filesystem::path the\n// static path object must be imbued with the utf8 locale or paths will be\n// incorrectly translated.\n\n#define BC_LOCALE_BACKEND \"icu\"\n#define BC_LOCALE_UTF8 \"en_US.UTF8\"\n\n#ifdef _MSC_VER\n#include <locale>\n#include <boost/filesystem.hpp>\n#include <boost/locale.hpp>\n#include <windows.h>\n#define BC_USE_UC_MAIN                                           \\\n    namespace libbitcoin                                         \\\n    {                                                            \\\n    int main(int argc, char *argv[]);                            \\\n    }                                                            \\\n                                                                 \\\n    int wmain(int argc, wchar_t *argv[])                         \\\n    {                                                            \\\n        using namespace libbitcoin;                              \\\n        boost::locale::generator locale;                         \\\n        std::locale::global(locale(BC_LOCALE_UTF8));             \\\n        boost::filesystem::path::imbue(std::locale());           \\\n                                                                 \\\n        auto variables = to_utf8(_wenviron);                     \\\n        environ = reinterpret_cast<char **>(variables.data());   \\\n                                                                 \\\n        auto arguments = to_utf8(argc, argv);                    \\\n        auto args = reinterpret_cast<char **>(arguments.data()); \\\n                                                                 \\\n        return libbitcoin::main(argc, args);                     \\\n    }\n#else\n#define BC_USE_UC_MAIN                       \\\n    namespace libbitcoin                     \\\n    {                                        \\\n    int main(int argc, char *argv[]);        \\\n    }                                        \\\n                                             \\\n    int main(int argc, char *argv[])         \\\n    {                                        \\\n        return libbitcoin::main(argc, argv); \\\n    }\n#endif\n\nnamespace libbitcoin\n{\n\n/**\n * Use bc::cin in place of std::cin.\n */\nextern std::istream &cin;\n\n/**\n * Use bc::cout in place of std::cout.\n */\nextern std::ostream &cout;\n\n/**\n * Use bc::cerr in place of std::cerr.\n */\nextern std::ostream &cerr;\n\n#ifdef WITH_ICU\n\n/**\n * Normalize a string value using nfc normalization.\n * This function requires the ICU dependency.\n * @param[in]  value  The value to normalize.\n * @return            The normalized value.\n */\nBC_API std::string to_normal_nfc_form(const std::string &value);\n\n/**\n * Normalize a string value using nfkd normalization.\n * This function requires the ICU dependency.\n * @param[in]  value  The value to normalize.\n * @return            The normalized value.\n */\nBC_API std::string to_normal_nfkd_form(const std::string &value);\n\n#endif\n\n/**\n * Convert wide environment vector to utf8 environment vector.\n * Caller should assign buffer and set result to environ as:\n * environ = reinterpret_cast<char**>(&buffer[0])\n * @param[in]  environment  The wide environment variables vector.\n * @return                  A buffer holding the narrow version of environment.\n */\nBC_API data_chunk to_utf8(wchar_t *environment[]);\n\n/**\n * Convert wide argument vector to utf8 argument vector.\n * Caller should assign buffer and reinterpret result as:\n * auto args = reinterpret_cast<char**>(&buffer[0])\n * @param[in]  argc  The number of elements in argv.\n * @param[in]  argv  The wide command line arguments.\n * @return           A buffer holding the narrow version of argv.\n */\nBC_API data_chunk to_utf8(int argc, wchar_t *argv[]);\n\n/**\n * Convert a wide (presumed UTF16) array to wide (UTF8/char).\n * @param[in]  out        The converted narrow array.\n * @param[in]  out_bytes  The allocated number of bytes in 'out'.\n * @param[in]  in         The wide character array to convert.\n * @param[in]  in_chars   The number of 'in' wide characters to convert.\n * @return                The number of bytes converted.\n */\nBC_API size_t to_utf8(char out[], size_t out_bytes, const wchar_t in[],\n                      size_t in_chars);\n\n/**\n * Convert a wide (presumed UTF16) string to narrow (UTF8/char).\n * @param[in]  wide  The utf16 string to convert.\n * @return           The resulting utf8 string.\n */\nBC_API std::string to_utf8(const std::wstring &wide);\n\n/**\n * Convert a narrow (presumed UTF8) array to wide (UTF16/wchar_t).\n * This is designed for buffering, where the narrow array may have been\n * truncated in the middle of a multiple byte character. The terminating\n * offset is returned in the 'unread' out parameter.\n * @param[in]  out        The converted wide array.\n * @param[in]  out_chars  The allocated number of wide characters in 'out'.\n * @param[in]  in         The narrow array to convert.\n * @param[in]  in_bytes   The number of 'in' bytes to convert.\n * @param[in]  truncated  The number of 'in' bytes [0..3] that were truncated.\n * @return                The number of characters converted.\n */\nBC_API size_t to_utf16(wchar_t out[], size_t out_chars, const char in[],\n                       size_t in_bytes, uint8_t &truncated);\n\n/**\n * Convert a narrow (presumed UTF8) string to wide (UTF16/wchar_t).\n * @param[in]  narrow  The utf8 string to convert.\n * @return             The resulting utf16 string.\n */\nBC_API std::wstring to_utf16(const std::string &narrow);\n\n/**\n * Initialize windows to use UTF8 for stdio. This cannot be uninitialized and\n * once set bc stdio must be used in place of std stdio.\n */\nBC_API void set_utf8_stdio();\n\n/**\n * Initialize windows to use UTF8 for stdin. This cannot be uninitialized and\n * once set bc::cin must be used in place of std::cin.\n */\nBC_API void set_utf8_stdin();\n\n/**\n * Initialize windows to use UTF8 for stdout. This cannot be uninitialized and\n * once set bc::cout must be used in place of std::cout.\n */\nBC_API void set_utf8_stdout();\n\n/**\n * Initialize windows to use UTF8 for stderr. This cannot be uninitialized and\n * once set bc::cerr must be used in place of std::cerr.\n */\nBC_API void set_utf8_stderr();\n\n/**\n * Initialize windows to use binary for stdin. This cannot be uninitialized.\n */\nBC_API void set_binary_stdin();\n\n/**\n * Initialize windows to use binary for stdout. This cannot be uninitialized.\n */\nBC_API void set_binary_stdout();\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/unicode/unicode_istream.hpp",
    "content": "﻿/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_UNICODE_ISTREAM_HPP\n#define UC_UNICODE_ISTREAM_HPP\n\n#include <cstddef>\n#include <iostream>\n#include <UChain/coin/define.hpp>\n\nnamespace libbitcoin\n{\n\n/**\n * Class to expose a narrowing input stream.\n * std::wcin must be patched by console_streambuf if used for Windows input.\n */\nclass BC_API unicode_istream\n    : public std::istream\n{\n  public:\n    /**\n     * Construct instance of a conditionally-narrowing input stream.\n     * @param[in]  narrow_stream  A narrow input stream such as std::cin.\n     * @param[in]  wide_stream    A wide input stream such as std::wcin.\n     * @param[in]  size           The wide buffer size.\n     */\n    unicode_istream(std::istream &narrow_stream, std::wistream &wide_stream,\n                    size_t size);\n\n    /**\n     * Delete the unicode_streambuf that wraps wide_stream.\n     */\n    ~unicode_istream();\n};\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/unicode/unicode_ostream.hpp",
    "content": "﻿/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_UNICODE_OSTREAM_HPP\n#define UC_UNICODE_OSTREAM_HPP\n\n#include <cstddef>\n#include <iostream>\n#include <UChain/coin/define.hpp>\n\nnamespace libbitcoin\n{\n\n/**\n * Class to expose a widening output stream.\n */\nclass BC_API unicode_ostream\n    : public std::ostream\n{\n  public:\n    /**\n     * Construct instance of a conditionally-widening output stream.\n     * @param[in]  narrow_stream  A narrow output stream such as std::cout.\n     * @param[in]  wide_stream    A wide output stream such as std::wcout.\n     * @param[in]  size           The wide buffer size.\n     */\n    unicode_ostream(std::ostream &narrow_stream, std::wostream &wide_stream,\n                    size_t size);\n\n    /**\n     * Delete the unicode_streambuf that wraps wide_stream.\n     */\n    ~unicode_ostream();\n};\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/unicode/unicode_streambuf.hpp",
    "content": "﻿/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_UNICODE_STREAMBUF_HPP\n#define UC_UNICODE_STREAMBUF_HPP\n\n#include <cstddef>\n#include <streambuf>\n#include <UChain/coin/compat.hpp>\n#include <UChain/coin/define.hpp>\n\nnamespace libbitcoin\n{\n\n/**\n * Class to translate internal utf8 iostreams to external utf16 iostreams.\n * This uses wide and narrow input and output buffers of 1024 characters/bytes.\n * However because of utf8-utf16 conversion ratios of up to 4:1 the effective\n * wide output buffering may be reduced to as much as 256 characters.\n */\nclass BC_API unicode_streambuf\n    : public std::streambuf\n{\n  public:\n    /**\n     * Construct unicode stream buffer from a weak reference to a wide buffer.\n     * @param[in]  wide_buffer  A wide stream buffer for i/o relay.\n     * @param[in]  size         The wide buffer size.\n     */\n    unicode_streambuf(std::wstreambuf *wide_buffer, size_t size);\n\n    /**\n     * Synchronize stream buffer.\n     */\n    virtual ~unicode_streambuf();\n\n  protected:\n    /**\n     * Implement underflow for support of input streams.\n     */\n    virtual std::streambuf::int_type underflow();\n\n    /**\n     * Implement overflow for support of output streams.\n     * @param[in]  character  A single byte to be explicitly put.\n     */\n    virtual std::streambuf::int_type overflow(\n        std::streambuf::int_type character);\n\n    /**\n     * Implement sync for support of output streams.\n     */\n    virtual int sync();\n\n  private:\n    // The constructed wide buffer size in number of characters.\n    size_t wide_size_;\n\n    // The derived narrow buffer size in utf8 (bytes).\n    size_t narrow_size_;\n\n    // The dynamically-allocated buffers.\n    wchar_t *wide_;\n    char *narrow_;\n\n    // The excapsulated wide streambuf.\n    std::wstreambuf *wide_buffer_;\n};\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/array_slice.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_ARRAY_SLICE_HPP\n#define UC_ARRAY_SLICE_HPP\n\n#include <cstddef>\n\nnamespace libbitcoin\n{\n\n/**\n * An read-only STL-style wrapper for array-style collections.\n *\n * This class allows std::array, std::vector, std::string, and c-style arrays\n * to be used interchangeably in functions that expect raw data.\n */\ntemplate <typename T>\nclass array_slice\n{\n  public:\n    template <typename Container>\n    array_slice(const Container &container);\n\n    // TODO: reliance this class causes unnecessary copying in cases where move\n    // arguments are not defined. This cannot itself be converted to move.\n    ////template <typename Container>\n    ////array_slice(Container&& container);\n\n    array_slice(const T *begin, const T *end);\n\n    const T *begin() const;\n    const T *end() const;\n    const T *data() const;\n    std::size_t size() const;\n    bool empty() const;\n\n  private:\n    const T *begin_;\n    const T *end_;\n};\n\n} // namespace libbitcoin\n\n#include <UChain/coin/impl/utility/array_slice.ipp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/asio.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_ASIO_HPP\n#define UC_ASIO_HPP\n\n#include <chrono>\n#include <memory>\n#include <boost/asio.hpp>\n#include <boost/thread.hpp>\n#include <UChain/coin/compat.hpp>\n\n// Convenience namespace for commonly used boost asio aliases.\n\nnamespace libbitcoin\n{\nnamespace asio\n{\n\nnamespace error = boost::asio::error;\n\ntypedef std::chrono::hours hours;\ntypedef std::chrono::minutes minutes;\ntypedef std::chrono::seconds seconds;\ntypedef std::chrono::milliseconds milliseconds;\ntypedef std::chrono::microseconds microseconds;\n\n// Steady clock: use for continuity, not time of day determinations.\ntypedef std::chrono::steady_clock steady_clock;\ntypedef steady_clock::duration duration;\ntypedef steady_clock::time_point time_point;\ntypedef boost::asio::basic_waitable_timer<steady_clock> timer;\n\ntypedef boost::asio::const_buffer const_buffer;\ntypedef boost::asio::io_service service;\ntypedef boost::asio::ip::address address;\ntypedef boost::asio::ip::address_v4 ipv4;\ntypedef boost::asio::ip::address_v6 ipv6;\ntypedef boost::asio::ip::tcp tcp;\ntypedef boost::asio::ip::tcp::endpoint endpoint;\n\ntypedef tcp::socket socket;\ntypedef tcp::acceptor acceptor;\ntypedef tcp::resolver resolver;\ntypedef tcp::resolver::query query;\ntypedef tcp::resolver::iterator iterator;\n\n// This is used because of thread_specific_ptr limitation.\ntypedef boost::thread thread;\n\ntypedef std::shared_ptr<socket> socket_ptr;\ntypedef std::shared_ptr<acceptor> acceptor_ptr;\ntypedef std::shared_ptr<resolver> resolver_ptr;\ntypedef std::shared_ptr<query> query_ptr;\n\nBC_CONSTEXPR int max_connections = boost::asio::socket_base::max_connections;\n\n} // namespace asio\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/assert.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_ASSERT_HPP\n#define UC_ASSERT_HPP\n\n#ifdef NDEBUG\n#define BITCOIN_ASSERT(expression)\n#define BITCOIN_ASSERT_MSG(expression, text)\n#define DEBUG_ONLY(expression)\n#else\n#include <cassert>\n#define BITCOIN_ASSERT(expression) assert(expression)\n#define BITCOIN_ASSERT_MSG(expression, text) assert((expression) && (text))\n#define DEBUG_ONLY(expression) expression\n#endif\n\n// This is used to prevent bogus compiler warnings about unused variables.\n// remove by -, -fno-unused\n//#define UNUSED(expression) (void)(expression)\n\n#include <UChain/coin/utility/monitor.hpp>\n#include <UChain/coin/utility/track.hpp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/atomic.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_ATOMIC_POINTER_HPP\n#define UC_ATOMIC_POINTER_HPP\n\n#include <utility>\n#include <UChain/coin/utility/thread.hpp>\n\nnamespace libbitcoin\n{\n\ntemplate <typename Type>\nclass atomic\n{\n  public:\n    /// Create an atomically-accessible default instance of the type.\n    atomic()\n    {\n    }\n\n    /// Create an atomically-accessible copied instance of the type.\n    atomic(const Type &instance)\n        : instance_(instance)\n    {\n    }\n\n    /// Create an atomically-accessible moved instance of the type.\n    atomic(Type &&instance)\n        : instance_(std::forward<Type>(instance))\n    {\n    }\n\n    Type load() const\n    {\n        // Critical Section\n        ///////////////////////////////////////////////////////////////////////\n        shared_lock lock(mutex_);\n\n        return instance_;\n        ///////////////////////////////////////////////////////////////////////\n    }\n\n    void store(const Type &instance)\n    {\n        // Critical Section\n        ///////////////////////////////////////////////////////////////////////\n        unique_lock lock(mutex_);\n\n        instance_ = instance;\n        ///////////////////////////////////////////////////////////////////////\n    }\n\n  private:\n    Type instance_;\n    mutable shared_mutex mutex_;\n};\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/binary.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_BINARY_HPP\n#define UC_BINARY_HPP\n\n#include <cstdint>\n#include <string>\n#include <UChain/coin/constants.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\n\nclass BC_API binary\n{\n  public:\n    typedef uint8_t block;\n    typedef std::size_t size_type;\n\n    static BC_CONSTEXPR size_type bits_per_block = byte_bits;\n    static size_type blocks_size(size_type bit_size);\n    static bool is_base2(const std::string &text);\n\n    binary();\n    binary(const binary &other);\n    binary(const std::string &bit_string);\n    binary(size_type size, data_slice blocks);\n\n    void resize(size_type size);\n    bool operator[](size_type index) const;\n    const data_chunk &blocks() const;\n    std::string encoded() const;\n\n    /// size in bits\n    size_type size() const;\n    void append(const binary &post);\n    void prepend(const binary &prior);\n    void shift_left(size_type distance);\n    void shift_right(size_type distance);\n    binary substring(size_type first, size_type length = max_size_t) const;\n\n    bool is_prefix_of(data_slice field) const;\n    bool is_prefix_of(uint32_t field) const;\n    bool is_prefix_of(const binary &field) const;\n\n    bool operator<(const binary &other) const;\n    bool operator==(const binary &other) const;\n    bool operator!=(const binary &other) const;\n    binary &operator=(const binary &other);\n    friend std::istream &operator>>(std::istream &in, binary &to);\n    friend std::ostream &operator<<(std::ostream &out, const binary &of);\n\n  private:\n    static uint8_t shift_block_right(uint8_t next, uint8_t current, uint8_t prior,\n                                     size_type original_offset, size_type intended_offset);\n\n    data_chunk blocks_;\n    uint8_t final_block_excess_;\n};\n\n} // namespace libbitcoin\n\nnamespace std\n{\ntemplate <>\nstruct hash<bc::binary>\n{\n    size_t operator()(const bc::binary &value) const\n    {\n        return std::hash<std::string>()(value.encoded());\n    }\n};\n} // namespace std\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/collection.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_COLLECTION_HPP\n#define UC_COLLECTION_HPP\n\n#include <iterator>\n#include <iostream>\n#include <vector>\n#include <UChain/coin/define.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\n\n#define BC_SENTENCE_DELIMITER \" \"\n\n/**\n * Cast vector/enumerable elements into a new vector.\n * @param      <Source>  The source element type.\n * @param      <Target>  The target element type.\n * @param[in]  source    The enumeration of Source elements to cast.\n * @returns              A new enumeration with elements cast to Target.\n */\ntemplate <typename Source, typename Target>\nstd::vector<Target> cast(const std::vector<Source> &source);\n\n/**\n * Find the position of a pair in an ordered list.\n * @param      <Pair>  The type of list member elements.\n * @param[in]  list    The list to search.\n * @param[in]  key     The key to the element to find.\n * @return             The position or -1 if not found.\n */\ntemplate <typename Pair, typename Key>\nint find_pair_position(const std::vector<const Pair> &list, Key &key);\n\n/**\n * Find the position of an element in an ordered list.\n * @param      <Element>  The type of list member elements.\n * @param[in]  list       The list to search.\n * @param[in]  value      The value of the element to find.\n * @return                The position or -1 if not found.\n */\ntemplate <typename Element, typename Container>\nint find_position(const Container &list, const Element &value);\n\n/**\n * Facilitate a list insertion sort by inserting into a sorted position.\n * @param      <Type>       The type of list member elements.\n * @param      <Predicate>  The sort predicate function signature.\n * @param[in]  list         The list to modify.\n * @param[in]  element      The element to insert.\n * @param[in]  predicate    The sort predicate.\n * @return                  The vector iterator.\n */\ntemplate <typename Type, typename Predicate>\ntypename std::vector<Type>::iterator insert_sorted(std::vector<Type> &list,\n                                                   const Type &element, Predicate predicate);\n\n/**\n * Move members of a source list to end of a target list. Source is cleared.\n * @param      <Type>     The type of list member elements.\n * @param[in]  target     The target list.\n * @param[in]  source     The source list\n */\ntemplate <typename Type>\nvoid move_append(std::vector<Type> &target, std::vector<Type> &source);\n\n/////**\n//// * Reverse a list, returning the new list.\n//// * @param      <Collection> The type of list.\n//// * @param[in]  list         The target list.\n//// * @returns                 The new reversed list\n//// */\n////template <typename Collection>\n////Collection reverse(const std::vector<Collection>& list);\n\n} // namespace libbitcoin\n\nnamespace std\n{\n\n/**\n * Make vectors of serializable elements serializable to std::ostream.\n * @param      <Type>  The type of list member elements.\n * @param[in]  output  The output stream to serialize to.\n * @param[in]  list    The list to serialize.\n * @return             The output stream.\n */\ntemplate <class Type>\nstd::ostream &operator<<(std::ostream &output, const std::vector<Type> &list);\n\n} // namespace std\n\n#include <UChain/coin/impl/utility/collection.ipp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/color.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_COLOR_HPP\n#define UC_COLOR_HPP\n\n#include <cstdint>\n#include <UChain/coin/compat.hpp>\n#include <UChain/coin/define.hpp>\n\nnamespace libbitcoin\n{\n\nstruct BC_API color\n{\n    uint8_t red;\n    uint8_t green;\n    uint8_t blue;\n    uint8_t alpha;\n};\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/conditional_lock.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CONDITIONAL_LOCK_HPP\n#define UC_CONDITIONAL_LOCK_HPP\n\n#include <memory>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/thread.hpp>\n\nnamespace libbitcoin\n{\n\nclass BC_API conditional_lock\n{\n  public:\n    /// Conditional lock using specified mutex pointer.\n    conditional_lock(std::shared_ptr<shared_mutex> mutex_ptr);\n\n    /// Unlock.\n    ~conditional_lock();\n\n  private:\n    const std::shared_ptr<shared_mutex> mutex_ptr_;\n};\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/container_sink.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CONTAINER_SINK_HPP\n#define UC_CONTAINER_SINK_HPP\n\n#include <algorithm>\n#include <cstdint>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/define.hpp>\n\nnamespace libbitcoin\n{\n\n// modified from boost.iostreams example\n// boost.org/doc/libs/1_55_0/libs/iostreams/doc/tutorial/container_source.html\ntemplate <typename Container, typename SinkType, typename CharType>\nclass BC_API container_sink\n{\n  public:\n    typedef CharType char_type;\n    typedef boost::iostreams::sink_tag category;\n\n    container_sink(Container &container)\n        : container_(container)\n    {\n        static_assert(sizeof(SinkType) == sizeof(CharType), \"invalid size\");\n    }\n\n    std::streamsize write(const char_type *buffer, std::streamsize size)\n    {\n        const auto safe_sink = reinterpret_cast<const SinkType *>(buffer);\n        container_.insert(container_.end(), safe_sink, safe_sink + size);\n        return size;\n    }\n\n  private:\n    Container &container_;\n};\n\ntemplate <typename Container>\nusing byte_sink = container_sink<Container, uint8_t, char>;\n\nusing data_sink = boost::iostreams::stream<byte_sink<data_chunk>>;\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/container_source.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CONTAINER_SOURCE_HPP\n#define UC_CONTAINER_SOURCE_HPP\n\n#include <algorithm>\n#include <cstdint>\n#include <boost/iostreams/categories.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/assert.hpp>\n\nnamespace libbitcoin\n{\n\n// modified from boost.iostreams example\n// boost.org/doc/libs/1_55_0/libs/iostreams/doc/tutorial/container_source.html\ntemplate <typename Container, typename SourceType, typename CharType>\nclass BC_API container_source\n{\n  public:\n    typedef CharType char_type;\n    typedef boost::iostreams::source_tag category;\n\n    container_source(const Container &container)\n        : container_(container), position_(0)\n    {\n        static_assert(sizeof(SourceType) == sizeof(CharType), \"invalid size\");\n    }\n\n    std::streamsize read(char_type *buffer, std::streamsize size)\n    {\n        const auto amount = container_.size() - position_;\n        const auto result = std::min(size,\n                                     static_cast<std::streamsize>(amount));\n\n        // TODO: use ios eof symbol (template-based).\n        if (result <= 0)\n            return -1;\n\n        const auto value = static_cast<typename Container::size_type>(result);\n        DEBUG_ONLY(const auto maximum =\n                       std::numeric_limits<typename Container::size_type>::max());\n        BITCOIN_ASSERT(value < maximum);\n        BITCOIN_ASSERT(position_ + value < maximum);\n\n        const auto limit = position_ + value;\n        const auto start = container_.begin() + position_;\n        const auto end = container_.begin() + limit;\n        std::copy(start, end, buffer);\n        position_ = limit;\n        return result;\n    }\n\n  private:\n    const Container &container_;\n    typename Container::size_type position_;\n};\n\ntemplate <typename Container>\nusing byte_source = container_source<Container, uint8_t, char>;\n\nusing data_source = boost::iostreams::stream<byte_source<data_chunk>>;\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/data.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATA_HPP\n#define UC_DATA_HPP\n\n#include <array>\n#include <cstddef>\n#include <cstdint>\n#include <initializer_list>\n#include <queue>\n#include <vector>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/array_slice.hpp>\n\nnamespace libbitcoin\n{\n\n// Define a byte array of a specified length.\ntemplate <size_t Size>\nusing byte_array = std::array<uint8_t, Size>;\n\ntemplate <size_t Size>\nstruct byte_array_parts\n{\n    byte_array<Size> left;\n    byte_array<Size> right;\n};\n\n// Define arbitrary byte storage types.\ntypedef byte_array<1> one_byte;\ntypedef array_slice<uint8_t> data_slice;\ntypedef std::vector<uint8_t> data_chunk;\ntypedef std::queue<data_chunk> data_queue;\ntypedef std::vector<data_chunk> data_stack;\ntypedef std::initializer_list<data_slice> loaf;\n\n/**\n * Create a single byte arrray with an initial value.\n */\ninline one_byte to_array(uint8_t byte);\n\n/**\n* Create a single byte data chunk with an initial value.\n*/\ninline data_chunk to_chunk(uint8_t byte);\n\n/**\n * Concatenate several data slices into a single data_chunk.\n * @param  extra_reserve  Include this many additional bytes when calling\n * `reserve` on the data_chunk (as an optimization).\n */\ninline data_chunk build_chunk(loaf slices, size_t extra_reserve = 0);\n\n/**\n * Concatenate several data slices into a single fixed size array.\n * Returns false if the slices don't fit in the array. Underfill is ok.\n */\ntemplate <size_t Size>\nbool build_array(byte_array<Size> &out, loaf slices);\n\n/**\n * Extend iterable object by appending other.\n */\ntemplate <class Target, class Extension>\nvoid extend_data(Target &target, const Extension &extension);\n\n/**\n * Constrain a numeric value within a given range.\n */\ntemplate <typename Value>\nValue range_constrain(Value value, Value minimum, Value maximum);\n\n/**\n * Extracty a subarray from start position with length end minus start.\n */\ntemplate <size_t Start, size_t End, size_t Size>\nbyte_array<End - Start> slice(const std::array<uint8_t, Size> &bytes);\n\n/**\n * Break an evenly-sized array array into two equal length parts.\n */\ntemplate <size_t Size>\nbyte_array_parts<Size / 2> split(const byte_array<Size> &bytes);\n\n/**\n * Concatenate two arrays into a new array.\n */\ntemplate <size_t Left, size_t Right>\nbyte_array<Left + Right> splice(const std::array<uint8_t, Left> &left,\n                                const std::array<uint8_t, Right> &right);\n\n/**\n * Concatenate three arrays into a new array.\n */\ntemplate <size_t Left, size_t Middle, size_t Right>\nbyte_array<Left + Middle + Right> splice(const std::array<uint8_t, Left> &left,\n                                         const std::array<uint8_t, Middle> &middle,\n                                         const std::array<uint8_t, Right> &right);\n\n/**\n * Convert the data slice to an array. Underfill is ok.\n */\ntemplate <size_t Size>\nbyte_array<Size> to_array(data_slice bytes);\n\n/**\n * Create a data chunk from an iterable object.\n */\ntemplate <typename Source>\ndata_chunk to_chunk(const Source &bytes);\n\n/**\n * Perform an exclusive or (xor) across two buffers to the length specified.\n * Return the resulting buffer. Caller must ensure length does not exceed\n * either buffer.\n */\ntemplate <size_t Size>\nbyte_array<Size> xor_data(data_slice bytes1, data_slice bytes2);\n\n/**\n * Perform an exclusive or (xor) across two buffers to the length specified.\n * Return the resulting buffer. Caller must ensure offset and length do not\n * exceed either buffer.\n */\ntemplate <size_t Size>\nbyte_array<Size> xor_data(data_slice bytes1, data_slice bytes2, size_t offset);\n\n/**\n * Perform an exclusive or (xor) across two buffers to the length specified.\n * Return the resulting buffer. Caller must ensure offsets and lengths do not\n * exceed the respective buffers.\n */\ntemplate <size_t Size>\nbyte_array<Size> xor_data(data_slice bytes1, data_slice bytes2, size_t offset1,\n                          size_t offset2);\n\n} // namespace libbitcoin\n\n#include <UChain/coin/impl/utility/data.ipp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/deadline.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DEADLINE_HPP\n#define UC_DEADLINE_HPP\n\n#include <memory>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/error.hpp>\n#include <UChain/coin/utility/asio.hpp>\n#include <UChain/coin/utility/enable_shared_from_base.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/thread.hpp>\n#include <UChain/coin/utility/threadpool.hpp>\n\nnamespace libbitcoin\n{\n\n/**\n * Class wrapper for boost::asio::deadline_timer, thread safe.\n * This simplifies invocation, eliminates boost-specific error handling and\n * makes timer firing and cancellation conditions safer.\n */\nclass BC_API deadline\n    : public enable_shared_from_base<deadline>,\n      track<deadline>\n{\n  public:\n    typedef std::shared_ptr<deadline> ptr;\n    typedef std::function<void(const code &)> handler;\n\n    /**\n     * Construct a deadline timer.\n     * @param[in]  pool      The thread pool used by the timer.\n     * @param[in]  duration  The default time period from start to expiration.\n     */\n    deadline(threadpool &pool, const asio::duration duration);\n\n    /// This class is not copyable.\n    deadline(const deadline &) = delete;\n    void operator=(const deadline &) = delete;\n\n    /**\n     * Start or restart the timer.\n     * The handler will not be invoked within the scope of this call.\n     * Use expired(ec) in handler to test for expiration.\n     * @param[in]  handle  Callback invoked upon expire or cancel.\n     */\n    void start(handler handle);\n\n    /**\n     * Start or restart the timer.\n     * The handler will not be invoked within the scope of this call.\n     * Use expired(ec) in handler to test for expiration.\n     * @param[in]  handle    Callback invoked upon expire or cancel.\n     * @param[in]  duration  The time period from start to expiration.\n     */\n    void start(handler handle, const asio::duration duration);\n\n    /**\n     * Cancel the timer. The handler will be invoked.\n     */\n    void stop();\n\n  private:\n    void handle_timer(const boost_code &ec, handler handle) const;\n\n    asio::timer timer_;\n    asio::duration duration_;\n    mutable shared_mutex mutex_;\n};\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/decorator.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DECORATOR_HPP\n#define UC_DECORATOR_HPP\n\n#include <functional>\n\nnamespace libbitcoin\n{\n\n/**\n * Defines a function decorator ala Python\n *\n *   void foo(int x, int y);\n *   function<void ()> wrapper(function<void (int)> f);\n *\n *   auto f = decorator(wrapper, bind(foo, 110, _1));\n *   f();\n */\n\ntemplate <typename Wrapper, typename Handler>\nstruct decorator_dispatch\n{\n    Wrapper wrapper;\n    Handler handler;\n\n    template <typename... Args>\n    auto operator()(Args &&... args)\n        -> decltype(wrapper(handler)(std::forward<Args>(args)...))\n    {\n        return wrapper(handler)(std::forward<Args>(args)...);\n    }\n};\n\ntemplate <typename Wrapper, typename Handler>\ndecorator_dispatch<Wrapper, typename std::decay<Handler>::type>\ndecorator(Wrapper &&wrapper, Handler &&handler)\n{\n    return {wrapper, handler};\n}\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/delegates.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DELEGATES_HPP\n#define UC_DELEGATES_HPP\n\n#include <functional>\n#include <UChain/coin/utility/work.hpp>\n\nnamespace libbitcoin\n{\nnamespace delegates\n{\n\n#define FORWARD_ARGS(args) \\\n    std::forward<Args>(args)...\n#define FORWARD_HANDLER(handler) \\\n    std::forward<Handler>(handler)\n#define BIND_HANDLER(handler, args) \\\n    std::bind(FORWARD_HANDLER(handler), FORWARD_ARGS(args))\n\n/// Binding delegate (current thread).\ntemplate <typename Handler>\nstruct bound\n{\n    template <typename... Args>\n    void operator()(Args &&... args)\n    {\n        work::bound(BIND_HANDLER(handler, args));\n    }\n\n    Handler handler;\n};\n\n/// Asynchronous delegate.\ntemplate <typename Handler>\nstruct concurrent\n{\n    template <typename... Args>\n    void operator()(Args &&... args)\n    {\n        heap.concurrent(BIND_HANDLER(handler, args));\n    }\n\n    Handler handler;\n    work &heap;\n};\n\n/// Ordered synchronous delegate.\ntemplate <typename Handler>\nstruct ordered\n{\n    template <typename... Args>\n    void operator()(Args &&... args)\n    {\n        heap.ordered(BIND_HANDLER(handler, args));\n    }\n\n    Handler handler;\n    work &heap;\n};\n\n/// Unordered synchronous delegate.\ntemplate <typename Handler>\nstruct unordered\n{\n    template <typename... Args>\n    void operator()(Args &&... args)\n    {\n        heap.unordered(BIND_HANDLER(handler, args));\n    }\n\n    Handler handler;\n    work &heap;\n};\n\n#undef FORWARD_ARGS\n#undef FORWARD_HANDLER\n#undef BIND_HANDLER\n\n} // namespace delegates\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/deserializer.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DESERIALIZER_HPP\n#define UC_DESERIALIZER_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <string>\n#include <UChain/coin/error.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n\nnamespace libbitcoin\n{\n\n/**\n * Deserializer that uses iterators and is oblivious to the underlying\n * container type. Is not threadsafe.\n *\n * Use the helper make_deserializer() to construct a deserializer without\n * needing to specify the Iterator type.\n *\n * Throws end_of_stream exception upon early termination during deserialize.\n * For example, calling read_8_bytes() with only 5 bytes remaining will throw.\n *\n * @code\n *  auto deserial = make_deserializer(data.begin(), data.end());\n *  try {\n *    uint64_t value = deserial.read_8_bytes();\n *  } catch (end_of_stream) {\n *    // ...\n *  }\n * @endcode\n */\ntemplate <typename Iterator, bool SafeCheckLast>\nclass deserializer\n    : public reader\n{\n  public:\n    deserializer(const Iterator begin, const Iterator end);\n\n    operator bool() const;\n    bool operator!() const;\n\n    bool is_exhausted() const;\n    uint8_t read_byte();\n    data_chunk read_data(size_t size);\n    size_t read_data(uint8_t *data, size_t size);\n    code read_error_code();\n    data_chunk read_data_to_eof();\n    hash_digest read_hash();\n    short_hash read_short_hash();\n    mini_hash read_mini_hash();\n\n    // These read data in little endian format:\n    uint16_t read_2_bytes_little_endian();\n    uint32_t read_4_bytes_little_endian();\n    uint64_t read_8_bytes_little_endian();\n\n    /**\n     * Variable uints are usually used for sizes.\n     * They're encoded using fewer bytes depending on the value itself.\n     */\n    uint64_t read_variable_uint_little_endian();\n\n    // These read data in big endian format:\n    uint16_t read_2_bytes_big_endian();\n    uint32_t read_4_bytes_big_endian();\n    uint64_t read_8_bytes_big_endian();\n\n    /**\n     * Variable uints are usually used for sizes.\n     * They're encoded using fewer bytes depending on the value itself.\n     */\n    uint64_t read_variable_uint_big_endian();\n\n    /**\n     * Reads an unsigned integer that has been encoded in big endian format.\n     */\n    template <typename T>\n    T read_big_endian();\n\n    /**\n     * Reads an unsigned integer that has been encoded in little endian format.\n     */\n    template <typename T>\n    T read_little_endian();\n\n    /**\n     * Read a fixed size string padded with zeroes.\n     */\n    std::string read_fixed_string(size_t length);\n\n    /**\n     * Read a variable length string.\n     */\n    std::string read_string();\n\n    /**\n     * Read a fixed-length data block.\n     */\n    template <unsigned N>\n    byte_array<N> read_bytes();\n\n    template <unsigned N>\n    byte_array<N> read_bytes_reverse();\n\n    /**\n     * Returns underlying iterator.\n     */\n    Iterator iterator() const;\n\n    /**\n     * Useful if you advance the iterator using other serialization\n     * methods or objects.\n     */\n    void set_iterator(const Iterator iterator);\n\n    /**\n     * Returns underlying iterator end.\n     */\n    Iterator end() const\n    {\n        return end_;\n    }\n\n  private:\n    // The compiler will optimise out calls to this function if !SafeCheckLast.\n    static void check_distance(Iterator it, const Iterator end,\n                               size_t distance);\n\n    Iterator iterator_;\n    const Iterator end_;\n};\n\n/**\n * Deserializer which performs bounds checking and throws end_of_stream\n * if the iterator exceeds 'end'.\n */\ntemplate <typename Iterator>\ndeserializer<Iterator, true> make_deserializer(const Iterator begin,\n                                               const Iterator end);\n\n/**\n * Faster deserializer with no bounds checking.\n */\ntemplate <typename Iterator>\ndeserializer<Iterator, false> make_deserializer_unsafe(const Iterator begin);\n\n} // namespace libbitcoin\n\n#include <UChain/coin/impl/utility/deserializer.ipp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/dispatcher.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DISPATCHER_HPP\n#define UC_DISPATCHER_HPP\n\n#include <functional>\n#include <string>\n#include <utility>\n#include <vector>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/delegates.hpp>\n#include <UChain/coin/utility/synchronizer.hpp>\n#include <UChain/coin/utility/threadpool.hpp>\n#include <UChain/coin/utility/work.hpp>\n\nnamespace libbitcoin\n{\n\n#define FORWARD_ARGS(args) \\\n    std::forward<Args>(args)...\n#define FORWARD_HANDLER(handler) \\\n    std::forward<Handler>(handler)\n#define BIND_HANDLER(handler, args) \\\n    std::bind(FORWARD_HANDLER(handler), FORWARD_ARGS(args))\n#define BIND_ARGS(args) \\\n    std::bind(FORWARD_ARGS(args))\n\n// Collection dispatch doesn't forward args as move args can only forward once.\n#define BIND_RACE(args, call) \\\n    std::bind(args..., call)\n#define BIND_ELEMENT(args, element, call) \\\n    std::bind(args..., element, call)\n\n/// This  class is thread safe.\n/// If the ios service is stopped jobs will not be dispatched.\nclass BC_API dispatcher\n{\n  public:\n    dispatcher(threadpool &pool, const std::string &name);\n\n    size_t ordered_backlog();\n    size_t unordered_backlog();\n    size_t concurrent_backlog();\n    size_t combined_backlog();\n\n    /// Invokes a job on the current thread.\n    template <typename... Args>\n    static void bound(Args &&... args)\n    {\n        BIND_ARGS(args)\n        ();\n    }\n\n    /// Posts a job to the service. Concurrent and not ordered.\n    template <typename... Args>\n    void concurrent(Args &&... args)\n    {\n        heap_.concurrent(BIND_ARGS(args));\n    }\n\n    /// Post a job to the strand. Ordered and not concurrent.\n    template <typename... Args>\n    void ordered(Args &&... args)\n    {\n        heap_.ordered(BIND_ARGS(args));\n    }\n\n    /// Posts a strand-wrapped job to the service. Not ordered or concurrent.\n    /// The wrap provides non-concurrency, order is prevented by service post.\n    template <typename... Args>\n    void unordered(Args &&... args)\n    {\n        heap_.unordered(BIND_ARGS(args));\n    }\n\n    /// Returns a delegate that will execute the job on the current thread.\n    template <typename... Args>\n    static auto bound_delegate(Args &&... args) -> delegates::bound<decltype(BIND_ARGS(args))>\n    {\n        return {\n            BIND_ARGS(args)};\n    }\n\n    /// Returns a delegate that will post the job via the service.\n    template <typename... Args>\n    auto concurrent_delegate(Args &&... args) -> delegates::concurrent<decltype(BIND_ARGS(args))>\n    {\n        return {\n            BIND_ARGS(args),\n            heap_};\n    }\n\n    /// Returns a delegate that will post the job via the strand.\n    template <typename... Args>\n    auto ordered_delegate(Args &&... args) -> delegates::ordered<decltype(BIND_ARGS(args))>\n    {\n        return {\n            BIND_ARGS(args),\n            heap_};\n    }\n\n    /// Returns a delegate that will post a wrapped job via the service.\n    template <typename... Args>\n    auto unordered_delegate(Args &&... args) -> delegates::unordered<decltype(BIND_ARGS(args))>\n    {\n        return {\n            BIND_ARGS(args),\n            heap_};\n    }\n\n    /// Executes multiple identical jobs concurrently until one completes.\n    template <typename Count, typename Handler, typename... Args>\n    void race(Count count, const std::string &name, Handler &&handler,\n              Args... args)\n    {\n        // The first fail will also terminate race and return the code.\n        static const size_t clearance_count = 1;\n        const auto call = synchronize(FORWARD_HANDLER(handler),\n                                      clearance_count, name, false);\n\n        for (Count iteration = 0; iteration < count; ++iteration)\n            concurrent(BIND_RACE(args, call));\n    }\n\n    /// Executes the job against each member of a collection concurrently.\n    template <typename Element, typename Handler, typename... Args>\n    void parallel(const std::vector<Element> &collection,\n                  const std::string &name, Handler &&handler, Args... args)\n    {\n        // Failures are suppressed, success always returned to handler.\n        const auto call = synchronize(FORWARD_HANDLER(handler),\n                                      collection.size(), name, true);\n\n        for (const auto &element : collection)\n            concurrent(BIND_ELEMENT(args, element, call));\n    }\n\n    /// Disperses the job against each member of a collection without order.\n    template <typename Element, typename Handler, typename... Args>\n    void disperse(const std::vector<Element> &collection,\n                  const std::string &name, Handler &&handler, Args... args)\n    {\n        // Failures are suppressed, success always returned to handler.\n        const auto call = synchronize(FORWARD_HANDLER(handler),\n                                      collection.size(), name, true);\n\n        for (const auto &element : collection)\n            unordered(BIND_ELEMENT(args, element, call));\n    }\n\n    /// Disperses the job against each member of a collection with order.\n    template <typename Element, typename Handler, typename... Args>\n    void serialize(const std::vector<Element> &collection,\n                   const std::string &name, Handler &&handler, Args... args)\n    {\n        // Failures are suppressed, success always returned to handler.\n        const auto call = synchronize(FORWARD_HANDLER(handler),\n                                      collection.size(), name, true);\n\n        for (const auto &element : collection)\n            ordered(BIND_ELEMENT(args, element, call));\n    }\n\n  private:\n    // This is thread safe.\n    work heap_;\n};\n\n#undef FORWARD_ARGS\n#undef FORWARD_HANDLER\n#undef BIND_HANDLER\n#undef BIND_ARGS\n#undef BIND_RACE\n#undef BIND_ELEMENT\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/enable_shared_from_base.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_ENABLE_SHARED_FROM_BASE_HPP\n#define UC_ENABLE_SHARED_FROM_BASE_HPP\n\n#include <memory>\n\nnamespace libbitcoin\n{\n\n/// Because enable_shared_from_this doesn't support inheritance.\ntemplate <class Base>\nclass enable_shared_from_base\n    : public std::enable_shared_from_this<Base>\n{\n  protected:\n    template <class Derived>\n    std::shared_ptr<Derived> shared_from_base()\n    {\n        return std::static_pointer_cast<Derived>(this->shared_from_this());\n    }\n};\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/endian.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_ENDIAN_HPP\n#define UC_ENDIAN_HPP\n\n#include <istream>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\n\ntemplate <typename T, typename Iterator>\nT from_big_endian(Iterator start, Iterator end);\n\ntemplate <typename T, typename Iterator>\nT from_little_endian(Iterator start, Iterator end);\n\ntemplate <typename T, typename Iterator>\nT from_big_endian_unsafe(Iterator in);\n\ntemplate <typename T, typename Iterator>\nT from_little_endian_unsafe(Iterator in);\n\ntemplate <typename T>\nT from_big_endian_stream_unsafe(std::istream &stream);\n\ntemplate <typename T>\nT from_little_endian_stream_unsafe(std::istream &stream);\n\ntemplate <typename T>\nbyte_array<sizeof(T)> to_big_endian(T n);\n\ntemplate <typename T>\nbyte_array<sizeof(T)> to_little_endian(T n);\n\n} // namespace libbitcoin\n\n#include <UChain/coin/impl/utility/endian.ipp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/exceptions.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_EXCEPTIONS_HPP\n#define UC_EXCEPTIONS_HPP\n\n#include <exception>\n#include <UChain/coin/define.hpp>\n\nnamespace libbitcoin\n{\n\nclass BC_API end_of_stream\n    : std::exception\n{\n};\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/istream_reader.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_ISTREAM_READER_HPP\n#define UC_ISTREAM_READER_HPP\n\n#include <cstdint>\n#include <istream>\n#include <UChain/coin/utility/reader.hpp>\n\nnamespace libbitcoin\n{\n\nclass BC_API istream_reader\n    : public reader\n{\n  public:\n    istream_reader(std::istream &stream);\n\n    operator bool() const;\n    bool operator!() const;\n\n    bool is_exhausted() const;\n    uint8_t read_byte();\n    data_chunk read_data(size_t size);\n    size_t read_data(uint8_t *data, size_t size);\n    data_chunk read_data_to_eof();\n    hash_digest read_hash();\n    short_hash read_short_hash();\n    mini_hash read_mini_hash();\n\n    // These read data in little endian format:\n    uint16_t read_2_bytes_little_endian();\n    uint32_t read_4_bytes_little_endian();\n    uint64_t read_8_bytes_little_endian();\n    uint64_t read_variable_uint_little_endian();\n\n    // These read data in big endian format:\n    uint16_t read_2_bytes_big_endian();\n    uint32_t read_4_bytes_big_endian();\n    uint64_t read_8_bytes_big_endian();\n    uint64_t read_variable_uint_big_endian();\n\n    /**\n     * Read a fixed size string padded with zeroes.\n     */\n    std::string read_fixed_string(size_t length);\n\n    /**\n     * Read a variable length string.\n     */\n    std::string read_string();\n\n    /**\n     * Reads an unsigned integer that has been encoded in big endian format.\n     */\n    template <typename T>\n    T read_big_endian();\n\n    /**\n     * Reads an unsigned integer that has been encoded in little endian format.\n     */\n    template <typename T>\n    T read_little_endian();\n\n    /**\n     * Read a fixed-length data block.\n     */\n    template <unsigned Size>\n    byte_array<Size> read_bytes();\n\n    template <unsigned Size>\n    byte_array<Size> read_bytes_reverse();\n\n  private:\n    std::istream &stream_;\n};\n\n} // namespace libbitcoin\n\n#include <UChain/coin/impl/utility/istream_reader.ipp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/log.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_LOG_HPP\n#define UC_LOG_HPP\n\n#include <functional>\n#include <map>\n#include <sstream>\n#include <string>\n#include <UChain/coin/define.hpp>\n\nnamespace libbitcoin\n{\n\nclass BC_API log\n{\n  public:\n    enum class level\n    {\n        trace,\n        debug,\n        info,\n        warning,\n        error,\n        fatal,\n        null\n    };\n\n    typedef std::function<void(level, const std::string &, const std::string &)>\n        functor;\n\n    log(level value, const std::string &domain);\n    log(log &&other);\n    ~log();\n\n    /// Clear all log configuration.\n    static void clear();\n\n    /// Convert the log level value to English text.\n    static std::string to_text(level value);\n\n    // Stream to these functions.\n    static log trace(const std::string &domain);\n    static log debug(const std::string &domain);\n    static log info(const std::string &domain);\n    static log warning(const std::string &domain);\n    static log error(const std::string &domain);\n    static log fatal(const std::string &domain);\n\n    template <typename Type>\n    log &operator<<(Type const &value)\n    {\n        stream_ << value;\n        return *this;\n    }\n\n    /// Set the output functor for this log instance.\n    void set_output_function(functor value);\n\n  private:\n    typedef std::map<level, functor> destinations;\n\n    static void output_ignore(level value, const std::string &domain,\n                              const std::string &body);\n    static void output_cout(level value, const std::string &domain,\n                            const std::string &body);\n    static void output_cerr(level value, const std::string &domain,\n                            const std::string &body);\n\n    static void to_stream(std::ostream &out, level value,\n                          const std::string &domain, const std::string &body);\n\n    static destinations destinations_;\n\n    level level_;\n    std::string domain_;\n    std::ostringstream stream_;\n};\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/logging.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_LOGGING_HPP\n#define UC_NETWORK_LOGGING_HPP\n\n#include <fstream>\n#include <iostream>\n#include <UChain/coin.hpp>\n#include <UChain/network/define.hpp>\n\nnamespace libbitcoin\n{\n\n/// Set up global logging.\nBCT_API void initialize_logging(bc::ofstream &debug, bc::ofstream &error,\n                                std::ostream &output_stream, std::ostream &error_stream, std::string level = \"DEBUG\");\n\n/// Class Logger\nclass Logger\n{\n#define self Logger\n\n  public:\n    self() noexcept\n    {\n        initialize_logging(debug_log_, error_log_, std::cout, std::cerr);\n    }\n\n    self(const self &) = delete;\n    self(const self &&) = delete;\n\n    ~self() noexcept\n    {\n        log::clear();\n        debug_log_.close();\n        error_log_.close();\n    }\n\n  public:\n    /// Constant for logging file open mode (append output).\n    static BC_CONSTEXPR std::ofstream::openmode log_open_mode =\n        std::ofstream::out | std::ofstream::app;\n\n  private:\n    bc::ofstream debug_log_{\"debug.log\", log_open_mode};\n    bc::ofstream error_log_{\"error.log\", log_open_mode};\n\n#undef self\n}; // class Logger\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/monitor.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MONITOR_HPP\n#define UC_MONITOR_HPP\n\n#include <atomic>\n#include <cstddef>\n#include <memory>\n#include <string>\n#include <UChain/coin/define.hpp>\n\nnamespace libbitcoin\n{\n\n/// A reference counting wrapper for closures placed on the asio work heap.\nclass BC_API monitor\n{\n  public:\n    typedef std::atomic<size_t> count;\n    typedef std::shared_ptr<count> count_ptr;\n\n    monitor(count_ptr counter, const std::string &name);\n    ~monitor();\n\n    template <typename Handler>\n    void invoke(Handler handler) const\n    {\n        ////trace(*counter_, \"*\");\n        handler();\n    }\n\n    void trace(size_t count, const std::string &action) const;\n\n  private:\n    count_ptr counter_;\n    const std::string name_;\n};\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/notifier.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NOTIFIER_HPP\n#define UC_NOTIFIER_HPP\n\n#include <cstddef>\n#include <functional>\n#include <memory>\n#include <string>\n#include <unordered_map>\n#include <UChain/coin/utility/asio.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/dispatcher.hpp>\n#include <UChain/coin/utility/enable_shared_from_base.hpp>\n#include <UChain/coin/utility/thread.hpp>\n#include <UChain/coin/utility/threadpool.hpp>\n////#include <UChain/coin/utility/track.hpp>\n\nnamespace libbitcoin\n{\n\ntemplate <typename Key, typename... Args>\nclass notifier\n    : public enable_shared_from_base<notifier<Key, Args...>>\n/*, track<notifier<Key, Args...>>*/\n{\n  public:\n    typedef std::function<bool(Args...)> handler;\n    typedef std::shared_ptr<notifier<Key, Args...>> ptr;\n\n    /// Construct an instance.\n    /// A limit of zero is unlimited, the class_name is for debugging.\n    notifier(threadpool &pool, size_t limit, const std::string &class_name);\n    notifier(threadpool &pool, const std::string &class_name);\n    ~notifier();\n\n    /// Enable new subscriptions.\n    void start();\n\n    /// Prevent new subscriptions.\n    void stop();\n\n    /// Subscribe to notifications for the specified amount of time.\n    /// Return true from the handler to resubscribe to notifications.\n    /// If key is matched the existing subscription is extended by duration.\n    /// If stopped this will invoke the hander with the specified arguments.\n    void subscribe(handler handler, const Key &key,\n                   const asio::duration &duration, Args... stopped_args);\n\n    /// Remove the subscription matching the specified key.\n    /// If subscribed this invokes notification with the specified arguments.\n    void unsubscribe(const Key &key, Args... unsubscribed_args);\n\n    /// Remove any expired subscriptions (blocking).\n    /// Invokes expiration notification with the specified arguments.\n    void purge(Args... expired_args);\n\n    /// Invoke all handlers sequentially (blocking).\n    void invoke(Args... args);\n\n    /// Invoke all handlers sequentially (non-blocking).\n    void relay(Args... args);\n\n  private:\n    typedef struct\n    {\n        handler notify;\n        asio::time_point expires;\n    } value;\n    typedef std::unordered_map<Key, value> map;\n\n    void do_invoke(Args... args);\n\n    const size_t limit_;\n    bool stopped_;\n    map subscriptions_;\n    dispatcher dispatch_;\n    mutable upgrade_mutex invoke_mutex_;\n    mutable upgrade_mutex subscribe_mutex_;\n};\n\n} // namespace libbitcoin\n\n#include <UChain/coin/impl/utility/notifier.ipp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/ostream_writer.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_OSTREAM_WRITER_HPP\n#define UC_OSTREAM_WRITER_HPP\n\n#include <ostream>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\n\nclass BC_API ostream_writer\n    : public writer\n{\n  public:\n    ostream_writer(std::ostream &stream);\n\n    operator bool() const;\n    bool operator!() const;\n\n    void write_byte(uint8_t value);\n    void write_data(const data_chunk &data);\n    void write_data(const uint8_t *data, size_t size);\n    void write_hash(const hash_digest &value);\n    void write_short_hash(const short_hash &value);\n    void write_mini_hash(const mini_hash &value);\n\n    // These write data in little endian format:\n    void write_2_bytes_little_endian(uint16_t value);\n    void write_4_bytes_little_endian(uint32_t value);\n    void write_8_bytes_little_endian(uint64_t value);\n    void write_variable_uint_little_endian(uint64_t value);\n\n    // These write data in big endian format:\n    void write_2_bytes_big_endian(uint16_t value);\n    void write_4_bytes_big_endian(uint32_t value);\n    void write_8_bytes_big_endian(uint64_t value);\n    void write_variable_uint_big_endian(uint64_t value);\n\n    /**\n     * Write a fixed size string padded with zeroes.\n     */\n    void write_fixed_string(const std::string &value, size_t size);\n\n    /**\n     * Write a variable length string.\n     */\n    void write_string(const std::string &value);\n\n    /**\n     * Writes an unsigned integer that has been encoded in big endian format.\n     */\n    template <typename T>\n    void write_big_endian(T value);\n\n    /**\n     * Reads an unsigned integer that has been encoded in little endian format.\n     */\n    template <typename T>\n    void write_little_endian(T value);\n\n    template <typename T>\n    void write_data(T &value);\n\n    /**\n     * Write a fixed-length data block.\n     */\n    template <unsigned Size>\n    void write_bytes(const byte_array<Size> &value);\n\n    template <unsigned Size>\n    void write_bytes_reverse(const byte_array<Size> &value);\n\n  private:\n    std::ostream &stream_;\n};\n\n} // namespace libbitcoin\n\n#include <UChain/coin/impl/utility/ostream_writer.ipp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/png.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_PNG_HPP\n#define UC_PNG_HPP\n\n#include <cstdint>\n#include <istream>\n#include <UChain/coin/compat.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/color.hpp>\n#include <UChain/coin/utility/data.hpp>\n\n#ifdef WITH_PNG\n#include <png.h>\n\nnamespace libbitcoin\n{\n\nclass BC_API png\n{\n  public:\n    static BC_CONSTEXPR uint32_t margin = 2;\n    static BC_CONSTEXPR uint32_t dots_per_inch = 72;\n    static BC_CONSTEXPR uint32_t inches_per_meter = (100.0 / 2.54);\n\n    static const color get_default_foreground()\n    {\n        static BC_CONSTEXPR color default_foreground{0, 0, 0, 255};\n        return default_foreground;\n    }\n\n    static const color get_default_background()\n    {\n        static BC_CONSTEXPR color default_background{255, 255, 255, 255};\n        return default_background;\n    }\n\n    /**\n     * A method that takes encoded qrcode as a data chunk and writes it to\n     * an output stream in png format with the default parameters.  The\n     * size parameter specifies the number of dots (pixels) per qr code\n     * modules.\n     */\n    static bool write_png(const data_chunk &data, uint32_t size,\n                          std::ostream &out);\n\n    /**\n     * A method that takes encoded qrcode data as a data chunk and writes\n     * it to an output stream in png format with the specified parameters.\n     */\n    static bool write_png(const data_chunk &data, uint32_t size,\n                          uint32_t dots_per_inch, uint32_t margin, uint32_t inches_per_meter,\n                          const color &foreground, const color &background, std::ostream &out);\n\n    /**\n     * A method that reads encoded qrcode data via an input stream and\n     * writes it to an output stream in png format with the default\n     * parameters.  The size parameter specifies the number of dots\n     * (pixels) per qr code modules.\n     */\n    static bool write_png(std::istream &in, uint32_t size, std::ostream &out);\n\n    /**\n     * A method that reads encoded qrcode data via an input stream and\n     * writes it to an output stream in png format with the specified\n     * parameters.\n     */\n    static bool write_png(std::istream &in, uint32_t size,\n                          uint32_t dots_per_inch, const uint32_t margin,\n                          uint32_t inches_per_meter, const color &foreground,\n                          const color &background, std::ostream &out);\n};\n\n} // namespace libbitcoin\n\n#endif // WITH_PNG\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/random.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_RANDOM_HPP\n#define UC_RANDOM_HPP\n\n#include <cstdint>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/asio.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\n\n/**\n * Generate a pseudo random number within the domain.\n * @return  The 64 bit number (use % to subset domain).\n */\nBC_API uint64_t pseudo_random();\n\n/**\n * Generate a non-zero pseudo random number within the domain.\n * @return  The 64 bit number (use % to subset domain).\n */\nBC_API uint64_t nonzero_pseudo_random();\n\n/**\n * Fill a buffer with randomness using the default random engine.\n * @param[in]  chunk  The buffer to fill with randomness.\n */\nBC_API void pseudo_random_fill(data_chunk &chunk);\n\n/**\n * Convert a time duration to a value in the range [max/ratio, max].\n * @param[in]  maximum  The maximum value to return.\n * @param[in]  ratio    The determinant of the minimum duration as the inverse\n *                      portion of the maximum duration.\n * @return              The randomized duration.\n */\nBC_API asio::duration pseudo_randomize(const asio::duration &maximum,\n                                       uint8_t ratio = 2);\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/reader.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_READER_HPP\n#define UC_READER_HPP\n\n#include <string>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/math/hash.hpp>\n\nnamespace libbitcoin\n{\n\nclass BC_API reader\n{\n  public:\n    virtual operator bool() const = 0;\n    virtual bool operator!() const = 0;\n\n    virtual bool is_exhausted() const = 0;\n    virtual uint8_t read_byte() = 0;\n    virtual data_chunk read_data(size_t size) = 0;\n    virtual size_t read_data(uint8_t *data, size_t size) = 0;\n    virtual data_chunk read_data_to_eof() = 0;\n    virtual hash_digest read_hash() = 0;\n    virtual short_hash read_short_hash() = 0;\n    virtual mini_hash read_mini_hash() = 0;\n\n    // These read data in little endian format:\n    virtual uint16_t read_2_bytes_little_endian() = 0;\n    virtual uint32_t read_4_bytes_little_endian() = 0;\n    virtual uint64_t read_8_bytes_little_endian() = 0;\n    virtual uint64_t read_variable_uint_little_endian() = 0;\n\n    // These read data in big endian format:\n    virtual uint16_t read_2_bytes_big_endian() = 0;\n    virtual uint32_t read_4_bytes_big_endian() = 0;\n    virtual uint64_t read_8_bytes_big_endian() = 0;\n    virtual uint64_t read_variable_uint_big_endian() = 0;\n\n    /**\n     * Read a fixed size string padded with zeroes.\n     */\n    virtual std::string read_fixed_string(size_t length) = 0;\n\n    /**\n     * Read a variable length string.\n     */\n    virtual std::string read_string() = 0;\n};\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/resource_lock.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_RESOURCE_LOCK_HPP\n#define UC_RESOURCE_LOCK_HPP\n\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <boost/interprocess/sync/file_lock.hpp>\n\nnamespace libbitcoin\n{\n\n/**\n * A resource lock device that ensures exclusive access to a resource.\n * It takes a path for creating a lock file object that can be used\n * for telling the usage of some resource between processes.\n * Example: opening/closing blockchain database.\n */\nclass resource_lock\n{\n  public:\n    typedef boost::filesystem::path file_path;\n\n    // Take an explicit path.\n    resource_lock(const file_path &lock_path);\n\n    bool lock();\n    bool unlock();\n\n  private:\n    typedef boost::interprocess::file_lock boost_file_lock;\n    typedef std::shared_ptr<boost_file_lock> lock_ptr;\n\n    const file_path &lock_path_;\n    lock_ptr lock_;\n};\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/resubscriber.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_RESUBSCRIBER_HPP\n#define UC_RESUBSCRIBER_HPP\n\n#include <functional>\n#include <memory>\n#include <string>\n#include <vector>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/dispatcher.hpp>\n#include <UChain/coin/utility/enable_shared_from_base.hpp>\n#include <UChain/coin/utility/thread.hpp>\n#include <UChain/coin/utility/threadpool.hpp>\n////#include <UChain/coin/utility/track.hpp>\n\nnamespace libbitcoin\n{\n\ntemplate <typename... Args>\nclass resubscriber\n    : public enable_shared_from_base<resubscriber<Args...>>\n/*, track<resubscriber<Args...>>*/\n{\n  public:\n    typedef std::function<bool(Args...)> handler;\n    typedef std::shared_ptr<resubscriber<Args...>> ptr;\n\n    /// Construct an instance. The class_name is for debugging.\n    resubscriber(threadpool &pool, const std::string &class_name);\n    ~resubscriber();\n\n    /// Enable new subscriptions.\n    void start();\n\n    /// Prevent new subscriptions.\n    void stop();\n\n    /// Subscribe to notifications with an option to resubscribe.\n    /// Return true from the handler to resubscribe to notifications.\n    void subscribe(handler handler, Args... stopped_args);\n\n    /// Invoke all handlers sequentially (blocking).\n    void invoke(Args... args);\n\n    /// Invoke all handlers sequentially (non-blocking).\n    void relay(Args... args);\n\n  private:\n    typedef std::vector<handler> list;\n\n    void do_invoke(Args... args);\n\n    bool stopped_;\n    list subscriptions_;\n    dispatcher dispatch_;\n    mutable upgrade_mutex invoke_mutex_;\n    mutable upgrade_mutex subscribe_mutex_;\n};\n\n} // namespace libbitcoin\n\n#include <UChain/coin/impl/utility/resubscriber.ipp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/scope_lock.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS) \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SCOPE_LOCK_HPP\n#define UC_SCOPE_LOCK_HPP\n\n#include <memory>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/thread.hpp>\n\nnamespace libbitcoin\n{\n\n// This is just unique_lock with a ptr member type, for convenience.\nclass BC_API scope_lock\n{\n  public:\n    typedef std::shared_ptr<scope_lock> ptr;\n\n    /// Lock using the specified mutex reference.\n    scope_lock(shared_mutex &mutex);\n\n    /// Unlock.\n    ~scope_lock();\n\n  private:\n    shared_mutex &mutex_;\n};\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/serializer.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SERIALIZER_HPP\n#define UC_SERIALIZER_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <string>\n#include <UChain/coin/error.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\n\n/**\n * Serializer that uses iterators and is oblivious to the underlying\n * container type. Is not threadsafe.\n *\n * Use the helper make_serializer() to construct a serializer without\n * needing to specify the Iterator type.\n *\n * Makes no assumptions about the size of the underlying container type.\n * User is responsible for allocating enough space prior to serialization.\n *\n * @code\n *  data_chunk buffer(8);\n *  auto serial = make_serializer(buffer.begin());\n *  serial.write_8_bytes(110);\n * @endcode\n */\ntemplate <typename Iterator>\nclass serializer\n    : public writer\n{\n  public:\n    serializer(const Iterator begin);\n\n    operator bool() const;\n    bool operator!() const;\n    void write_byte(uint8_t value);\n    void write_data(const data_chunk &data);\n    void write_data(const uint8_t *data, size_t size);\n    void write_error_code(const code &ec);\n    void write_hash(const hash_digest &hash);\n    void write_short_hash(const short_hash &hash);\n    void write_mini_hash(const mini_hash &hash);\n\n    // These write data in little endian format:\n    void write_2_bytes_little_endian(uint16_t value);\n    void write_4_bytes_little_endian(uint32_t value);\n    void write_8_bytes_little_endian(uint64_t value);\n\n    /**\n     * Variable uints are usually used for sizes.\n     * They're encoded using fewer bytes depending on the value itself.\n     */\n    void write_variable_uint_little_endian(uint64_t value);\n\n    // These write data in big endian format:\n    void write_2_bytes_big_endian(uint16_t value);\n    void write_4_bytes_big_endian(uint32_t value);\n    void write_8_bytes_big_endian(uint64_t value);\n\n    /**\n     * Variable uints are usually used for sizes.\n     * They're encoded using fewer bytes depending on the value itself.\n     */\n    void write_variable_uint_big_endian(uint64_t value);\n\n    /**\n     * Encodes an unsigned integer in big-endian format.\n     */\n    template <typename T>\n    void write_big_endian(T n);\n\n    /**\n     * Encodes an unsigned integer in little-endian format.\n     */\n    template <typename T>\n    void write_little_endian(T n);\n\n    /**\n     * Encodes a list of bytes.\n     */\n    template <typename T>\n    void write_data(const T &data);\n\n    /**\n     * Write a fixed size string padded with zeroes.\n     */\n    void write_fixed_string(const std::string &value, size_t size);\n\n    /**\n     * Write a variable length string.\n     */\n    void write_string(const std::string &value);\n\n    /**\n     * Returns underlying iterator.\n     */\n    Iterator iterator();\n\n    /**\n     * Useful if you want to serialize some data using another\n     * routine and then continue with this serializer.\n     */\n    void set_iterator(Iterator iterator);\n\n  private:\n    template <typename T>\n    void write_data_reverse(const T &data);\n\n    Iterator iterator_;\n};\n\ntemplate <typename Iterator>\nserializer<Iterator> make_serializer(Iterator begin);\n\n} // namespace libbitcoin\n\n#include <UChain/coin/impl/utility/serializer.ipp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/string.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_STRING_HPP\n#define UC_STRING_HPP\n\n#include <string>\n#include <vector>\n#include <UChain/coin/define.hpp>\n\nnamespace libbitcoin\n{\n\n/**\n * Join a list of strings into a single string, in order.\n * @param[in]  words      The list of strings to join.\n * @param[in]  delimiter  The delimiter, defaults to \" \".\n * @return                The resulting string.\n */\nBC_API std::string join(const std::vector<std::string> &words,\n                        const std::string &delimiter = \" \");\n\n/**\n * Split a list of strings into a string vector string, in order, white space\n * delimited.\n * @param[in]  sentence   The string to split.\n * @param[in]  delimiter  The delimeter, defaults to \" \".\n * @param[in]  trim       Trim the sentence for whitespace, defaults to true.\n * @return                The list of resulting strings.\n */\nBC_API std::vector<std::string> split(const std::string &sentence,\n                                      const std::string &delimiter = \" \", bool trim = true);\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/subscriber.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SUBSCRIBER_HPP\n#define UC_SUBSCRIBER_HPP\n\n#include <functional>\n#include <memory>\n#include <string>\n#include <vector>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/dispatcher.hpp>\n#include <UChain/coin/utility/enable_shared_from_base.hpp>\n#include <UChain/coin/utility/thread.hpp>\n#include <UChain/coin/utility/threadpool.hpp>\n////#include <UChain/coin/utility/track.hpp>\n\nnamespace libbitcoin\n{\n\ntemplate <typename... Args>\nclass subscriber\n    : public enable_shared_from_base<subscriber<Args...>>\n/*, track<subscriber<Args...>>*/\n{\n  public:\n    typedef std::function<void(Args...)> handler;\n    typedef std::shared_ptr<subscriber<Args...>> ptr;\n\n    subscriber(threadpool &pool, const std::string &class_name);\n    ~subscriber();\n\n    /// Enable new subscriptions.\n    void start();\n\n    /// Prevent new subscriptions.\n    void stop();\n\n    /// Subscribe to notifications (for one invocation only).\n    void subscribe(handler handler, Args... stopped_args);\n\n    /// Invoke and clear all handlers sequentially (blocking).\n    void invoke(Args... args);\n\n    /// Invoke and clear all handlers sequentially (non-blocking).\n    void relay(Args... args);\n\n  private:\n    typedef std::vector<handler> list;\n\n    void do_invoke(Args... args);\n\n    bool stopped_;\n    list subscriptions_;\n    dispatcher dispatch_;\n    mutable upgrade_mutex invoke_mutex_;\n    mutable upgrade_mutex subscribe_mutex_;\n};\n\n} // namespace libbitcoin\n\n#include <UChain/coin/impl/utility/subscriber.ipp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/synchronizer.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SYNCHRONIZER_HPP\n#define UC_SYNCHRONIZER_HPP\n\n#include <cstddef>\n#include <memory>\n#include <UChain/coin/error.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/thread.hpp>\n\nnamespace libbitcoin\n{\n\n// It is not possible for this class to produce a deadlock.\n\ntemplate <typename Handler>\nclass synchronizer\n{\n  public:\n    synchronizer(Handler handler, size_t clearance_count,\n                 const std::string &name, bool suppress_errors)\n        : handler_(handler),\n          name_(name),\n          clearance_count_(clearance_count),\n          counter_(std::make_shared<size_t>(0)),\n          mutex_(std::make_shared<upgrade_mutex>()),\n          suppress_errors_(suppress_errors)\n    {\n    }\n\n    template <typename... Args>\n    void operator()(const code &ec, Args &&... args)\n    {\n        // Critical Section\n        ///////////////////////////////////////////////////////////////////////\n        mutex_->lock_upgrade();\n\n        const auto initial_count = *counter_;\n        BITCOIN_ASSERT(initial_count <= clearance_count_);\n\n        if (initial_count == clearance_count_)\n        {\n            mutex_->unlock_upgrade();\n            //-----------------------------------------------------------------\n            return;\n        }\n\n        const auto terminate = ec && !suppress_errors_;\n        const auto count = terminate ? clearance_count_ : initial_count + 1;\n        const auto cleared = count == clearance_count_;\n\n        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n        mutex_->unlock_upgrade_and_lock();\n        (*counter_) = count;\n        mutex_->unlock();\n        ///////////////////////////////////////////////////////////////////////\n\n        if (cleared)\n        {\n            // If not suppressing errors pass the last result code.\n            // This is useful when clearance count is one.\n            const auto result = suppress_errors_ ? error::success : ec;\n            handler_(result, std::forward<Args>(args)...);\n        }\n    }\n\n  private:\n    Handler handler_;\n    const std::string name_;\n    const size_t clearance_count_;\n    const bool suppress_errors_;\n\n    // We use pointer to reference the same value/mutex across instance copies.\n    std::shared_ptr<size_t> counter_;\n    std::shared_ptr<upgrade_mutex> mutex_;\n};\n\ntemplate <typename Handler>\nsynchronizer<Handler> synchronize(Handler handler, size_t clearance_count,\n                                  const std::string &name, bool suppress_errors = false)\n{\n    return synchronizer<Handler>(handler, clearance_count, name,\n                                 suppress_errors);\n}\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/thread.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_THREAD_HPP\n#define UC_THREAD_HPP\n\n#include <memory>\n#include <boost/thread.hpp>\n#include <UChain/coin/define.hpp>\n\nnamespace libbitcoin\n{\n\nenum class thread_priority\n{\n    high,\n    normal,\n    low,\n    lowest\n};\n\ntypedef boost::mutex unique_mutex;\ntypedef boost::shared_mutex shared_mutex;\ntypedef boost::upgrade_mutex upgrade_mutex;\n\ntypedef boost::mutex::scoped_lock scoped_lock;\ntypedef boost::unique_lock<shared_mutex> unique_lock;\ntypedef boost::shared_lock<shared_mutex> shared_lock;\ntypedef boost::upgrade_lock<shared_mutex> upgrade_lock;\n\nBC_API void set_thread_priority(thread_priority priority);\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/threadpool.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_THREADPOOL_HPP\n#define UC_THREADPOOL_HPP\n\n#include <memory>\n#include <functional>\n#include <thread>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/asio.hpp>\n#include <UChain/coin/utility/thread.hpp>\n\nnamespace libbitcoin\n{\n\n/**\n * A collection of threads which can be passed operations through io_service.\n */\nclass BC_API threadpool\n{\n  public:\n    /**\n     * Threadpool constructor. spawn()s number_threads threads.\n     * @param[in]   number_threads  Number of threads to spawn.\n     * @param[in]   priority        Priority of threads to spawn.\n     */\n    threadpool(size_t number_threads = 0,\n               thread_priority priority = thread_priority::normal);\n\n    ~threadpool();\n\n    threadpool(const threadpool &) = delete;\n    void operator=(const threadpool &) = delete;\n\n    /**\n     * Add n threads to this threadpool.\n     * @param[in]   number_threads  Number of threads to add.\n     * @param[in]   priority        Priority of threads to add.\n     */\n    void spawn(size_t number_threads = 1,\n               thread_priority priority = thread_priority::normal);\n\n    /**\n     * Abandon outstanding operations without dispatching handlers.\n     * Terminate threads once work is complete.\n     * Prevents the enqueuing of new handlers.\n     * Caller should next call join, which will block until complete.\n     *\n     * WARNING: This can result in leaks in the case of heap allocated objects\n     * referenced captured in handlers that may not execute.\n     */\n    void abort();\n\n    /**\n     * Allow outstanding operations and handlers to finish normally.\n     * Terminate threads once work is complete.\n     * Allows the enqueuing of new handlers.\n     * Caller should next call join, which will block until complete.\n     */\n    void shutdown();\n\n    /**\n     * Wait for all threads in the pool to terminate.\n     *\n     * WARNING: Do not call this within any of the threads owned by this\n     * threadpool. Doing so will cause a resource deadlock and an\n     * std::system_error exception will be thrown.\n     */\n    void join();\n\n    /**\n     * Underlying boost::io_service object.\n     */\n    asio::service &service();\n\n    /**\n     * Underlying boost::io_service object.\n     */\n    const asio::service &service() const;\n\n  private:\n    void spawn_once(thread_priority priority = thread_priority::normal);\n\n    asio::service service_;\n    std::vector<asio::thread> threads_;\n    std::shared_ptr<asio::service::work> work_;\n};\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/time.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef INCLUDE_BITCOIN_BITCOIN_UTILITY_TIME_HPP_\n#define INCLUDE_BITCOIN_BITCOIN_UTILITY_TIME_HPP_\n#include <stdint.h>\n\nnamespace libbitcoin\n{ //namespace libbitcoin\n\nint64_t unix_millisecond();\n\n} //namespace libbitcoin\n\n#endif /* INCLUDE_BITCOIN_BITCOIN_UTILITY_TIME_HPP_ */\n"
  },
  {
    "path": "include/UChain/coin/utility/timer.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_TIMER_HPP\n#define UC_TIMER_HPP\n\n#include <chrono>\n#include <UChain/coin/utility/asio.hpp>\n\n// boost::timer::auto_cpu_timer requires the boost timer lib dependency.\n\nnamespace libbitcoin\n{\n\n// From: github.com/picanumber/bureaucrat/blob/master/time_lapse.h\n\n/// Class to measure the execution time of a callable.\ntemplate <typename Time = asio::milliseconds, class Clock = asio::steady_clock>\nstruct timer\n{\n    /// Returns the quantity (count) of the elapsed time as TimeT units.\n    template <typename Function, typename... Args>\n    static typename Time::rep execution(Function func, Args &&... args)\n    {\n        const auto start = Clock::now();\n        func(std::forward<Args>(args)...);\n        const auto difference = Clock::now() - start;\n        const auto duration = std::chrono::duration_cast<Time>(difference);\n        return duration.count();\n    }\n\n    /// Returns the duration (in chrono's type system) of the elapsed time.\n    template <typename Function, typename... Args>\n    static Time duration(Function func, Args &&... args)\n    {\n        auto start = Clock::now();\n        func(std::forward<Args>(args)...);\n        return std::chrono::duration_cast<Time>(Clock::now() - start);\n    }\n};\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/track.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_TRACK_HPP\n#define UC_TRACK_HPP\n\n#include <atomic>\n#include <cstddef>\n#include <string>\n\n#define CONSTRUCT_TRACK(class_name) \\\n    track<class_name>(#class_name)\n\ntemplate <class Shared>\nclass track\n{\n  public:\n    static std::atomic<size_t> instances;\n\n  protected:\n    track(const std::string &class_name);\n    ~track();\n\n  private:\n    const std::string class_;\n#ifndef NDEBUG\n    std::size_t count_;\n#endif\n};\n\n#include <UChain/coin/impl/utility/track.ipp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/variable_uint_size.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_VARIABLE_UINT_SIZE_HPP\n#define UC_VARIABLE_UINT_SIZE_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <string>\n#include <UChain/coin/define.hpp>\n\nnamespace libbitcoin\n{\n\nBC_API size_t variable_uint_size(uint64_t value);\nBC_API size_t variable_string_size(const std::string &str);\nBC_API std::string limit_size_string(const std::string &str, size_t limit_size);\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/work.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_WORK_HPP\n#define UC_WORK_HPP\n\n#include <functional>\n#include <string>\n#include <utility>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/asio.hpp>\n#include <UChain/coin/utility/monitor.hpp>\n#include <UChain/coin/utility/threadpool.hpp>\n\nnamespace libbitcoin\n{\n\n#define ORDERED \"ordered\"\n#define UNORDERED \"unordered\"\n#define CONCURRENT \"concurrent\"\n\n#define FORWARD_ARGS(args) \\\n    std::forward<Args>(args)...\n#define FORWARD_HANDLER(handler) \\\n    std::forward<Handler>(handler)\n#define BIND_HANDLER(handler, args) \\\n    std::bind(FORWARD_HANDLER(handler), FORWARD_ARGS(args))\n\n/// This  class is thread safe.\n/// boost asio class wrapper to enable work heap management.\nclass BC_API work\n{\n  public:\n    /// Create an instance.\n    work(threadpool &pool, const std::string &name);\n\n    /// This class is not copyable.\n    work(const work &) = delete;\n    void operator=(const work &) = delete;\n\n    /// Execute the job on the current thread.\n    template <typename Handler, typename... Args>\n    static void bound(Handler &&handler, Args &&... args)\n    {\n        BIND_HANDLER(handler, args)\n        ();\n    }\n\n    /// Service post ensures the job does not execute in the current thread.\n    template <typename Handler, typename... Args>\n    void concurrent(Handler &&handler, Args &&... args)\n    {\n        service_.post(inject(BIND_HANDLER(handler, args), CONCURRENT,\n                             concurrent_));\n    }\n\n    /// Use a strand to prevent concurrency and post vs. dispatch to\n    /// ensure that the job is not executed in the current thread.\n    template <typename Handler, typename... Args>\n    void ordered(Handler &&handler, Args &&... args)\n    {\n        strand_.post(inject(BIND_HANDLER(handler, args), ORDERED, ordered_));\n    }\n\n    /// Use a strand wrapper to prevent concurrency and a service post\n    /// to deny ordering while ensuring execution on another thread.\n    template <typename Handler, typename... Args>\n    void unordered(Handler &&handler, Args &&... args)\n    {\n        service_.post(strand_.wrap(inject(BIND_HANDLER(handler, args),\n                                          UNORDERED, unordered_)));\n    }\n\n    size_t ordered_backlog();\n    size_t unordered_backlog();\n    size_t concurrent_backlog();\n    size_t combined_backlog();\n\n  private:\n    template <typename Handler>\n    auto inject(Handler handler, const std::string &context,\n                monitor::count_ptr counter) -> std::function<void()>\n    {\n        const auto label = name_ + \"_\" + context;\n        const auto capture = std::make_shared<monitor>(counter, label);\n        return [=]() { capture->invoke(handler); };\n\n        //// TODO: determine how to define return type across platforms.\n        ////return std::bind(&monitor::invoke<Handler>, capture, handler);\n    }\n\n    // These are thread safe.\n    monitor::count_ptr ordered_;\n    monitor::count_ptr unordered_;\n    monitor::count_ptr concurrent_;\n    asio::service &service_;\n    asio::service::strand strand_;\n    const std::string name_;\n};\n\n#undef FORWARD_ARGS\n#undef FORWARD_HANDLER\n#undef BIND_HANDLER\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/utility/writer.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_WRITER_HPP\n#define UC_WRITER_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/variable_uint_size.hpp>\n\nnamespace libbitcoin\n{\n\nclass BC_API writer\n{\n  public:\n    virtual operator bool() const = 0;\n    virtual bool operator!() const = 0;\n\n    virtual void write_byte(uint8_t value) = 0;\n    virtual void write_data(const data_chunk &data) = 0;\n    virtual void write_data(const uint8_t *data, size_t size) = 0;\n    virtual void write_hash(const hash_digest &value) = 0;\n    virtual void write_short_hash(const short_hash &value) = 0;\n    virtual void write_mini_hash(const mini_hash &value) = 0;\n\n    // These write data in little endian format:\n    virtual void write_2_bytes_little_endian(uint16_t value) = 0;\n    virtual void write_4_bytes_little_endian(uint32_t value) = 0;\n    virtual void write_8_bytes_little_endian(uint64_t value) = 0;\n    virtual void write_variable_uint_little_endian(uint64_t value) = 0;\n\n    // These write data in big endian format:\n    virtual void write_2_bytes_big_endian(uint16_t value) = 0;\n    virtual void write_4_bytes_big_endian(uint32_t value) = 0;\n    virtual void write_8_bytes_big_endian(uint64_t value) = 0;\n    virtual void write_variable_uint_big_endian(uint64_t value) = 0;\n\n    /**\n     * Write a fixed size string padded with zeroes.\n     */\n    virtual void write_fixed_string(const std::string &value, size_t size) = 0;\n\n    /**\n     * Write a variable length string.\n     */\n    virtual void write_string(const std::string &value) = 0;\n};\n\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/version.hpp",
    "content": "///////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 2011-2018 libbitcoin developers\n// Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n//        GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY\n//\n///////////////////////////////////////////////////////////////////////////////\n#ifndef UC_VERSION_HPP\n#define UC_VERSION_HPP\n\n/**\n * The semantic version of this repository as: [major].[minor].[patch]\n * For interpretation of the versioning scheme see: http://semver.org\n */\n\n#define UC_VERSION \"0.0.6\"\n#define UC_MAJOR_VERSION 0\n#define UC_MINOR_VERSION 0\n#define UC_PATCH_VERSION 6\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/wallet/bitcoin_uri.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_WALLET_BITCOIN_URI_HPP\n#define UC_WALLET_BITCOIN_URI_HPP\n\n#include <cstdint>\n#include <iostream>\n#include <map>\n#include <string>\n#include <boost/optional.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/wallet/payment_address.hpp>\n#include <UChain/coin/wallet/stealth_address.hpp>\n#include <UChain/coin/wallet/uri_reader.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\n/// A bitcoin URI corresponding to BIP 21 and BIP 72.\n/// The object is not constant, setters can change state after construction.\nclass BC_API bitcoin_uri\n    : public uri_reader\n{\n  public:\n    /// Constructors.\n    bitcoin_uri();\n    bitcoin_uri(const bitcoin_uri &other);\n    bitcoin_uri(const std::string &uri, bool strict = true);\n\n    /// Operators.\n    bool operator<(const bitcoin_uri &other) const;\n    bool operator==(const bitcoin_uri &other) const;\n    bool operator!=(const bitcoin_uri &other) const;\n    bitcoin_uri &operator=(const bitcoin_uri &other);\n    friend std::istream &operator>>(std::istream &in, bitcoin_uri &to);\n    friend std::ostream &operator<<(std::ostream &out,\n                                    const bitcoin_uri &from);\n\n    /// Test whether the URI has been initialized.\n    operator const bool() const;\n\n    /// Get the serialized URI representation.\n    std::string encoded() const;\n\n    /// Property getters.\n    uint64_t amount() const;\n    std::string label() const;\n    std::string message() const;\n    std::string r() const;\n    std::string address() const;\n    payment_address payment() const;\n    stealth_address stealth() const;\n    std::string parameter(const std::string &key) const;\n\n    /// Property setters.\n    void set_amount(uint64_t satoshis);\n    void set_label(const std::string &label);\n    void set_message(const std::string &message);\n    void set_r(const std::string &r);\n    bool set_address(const std::string &address);\n    void set_address(const payment_address &payment);\n    void set_address(const stealth_address &stealth);\n\n    /// uri_reader implementation.\n    void set_strict(bool strict);\n    bool set_scheme(const std::string &scheme);\n    bool set_authority(const std::string &authority);\n    bool set_path(const std::string &path);\n    bool set_fragment(const std::string &fragment);\n    bool set_parameter(const std::string &key, const std::string &value);\n\n  private:\n    /// Private helpers.\n    bool set_amount(const std::string &satoshis);\n\n    /// Member state.\n    bool strict_;\n    std::string scheme_;\n    std::string address_;\n    std::map<std::string, std::string> query_;\n};\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/wallet/dictionary.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_WALLET_DICTIONARY_HPP\n#define UC_WALLET_DICTIONARY_HPP\n\n#include <array>\n#include <vector>\n#include <UChain/coin/compat.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\n/**\n * A valid mnemonic dictionary has exactly this many words.\n */\nstatic BC_CONSTEXPR size_t dictionary_size = 2048;\n\n/**\n * A dictionary for creating mnemonics.\n * The bip39 spec calls this a \"wordlist\".\n * This is a POD type, which means the compiler can write it directly\n * to static memory with no run-time overhead.\n */\ntypedef std::array<const char *, dictionary_size> dictionary;\n\n/**\n * A collection of candidate dictionaries for mnemonic validation.\n */\ntypedef std::vector<const dictionary *> dictionary_list;\n\nnamespace language\n{\n// Individual built-in languages:\nextern const dictionary en;\nextern const dictionary es;\nextern const dictionary ja;\nextern const dictionary zh_Hans;\nextern const dictionary zh_Hant;\n\n// All built-in languages:\nextern const dictionary_list all;\n} // namespace language\n\nnamespace symbol\n{\n// built in ban dict (upper case):\nbool is_sensitive(const std::string &symbol);\n\n// built in forbidden dict (upper case):\nbool is_forbidden(const std::string &symbol);\n\n// All built-in ban list:\n} // namespace symbol\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/wallet/ec_private.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_EC_PRIVATE_HPP\n#define UC_EC_PRIVATE_HPP\n\n#include <cstdint>\n#include <string>\n#include <UChain/coin/compat.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/checksum.hpp>\n#include <UChain/coin/math/elliptic_curve.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/wallet/ec_public.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\nclass payment_address;\n\n/// Private keys with public key compression metadata:\nstatic BC_CONSTEXPR size_t wif_uncompressed_size = 37u;\ntypedef byte_array<wif_uncompressed_size> wif_uncompressed;\n\nstatic BC_CONSTEXPR size_t wif_compressed_size = wif_uncompressed_size + 1u;\ntypedef byte_array<wif_compressed_size> wif_compressed;\n\n/// Use to pass an ec secret with compresson and version information.\nclass BC_API ec_private\n{\n  public:\n    // WIF carries a compression flag for payment address generation but\n    // assumes a mapping to payment address version. This is insufficient\n    // as a parameterized mapping is required, so we use the same technique as\n    // with hd keys, merging the two necessary values into one version.\n    static const uint8_t wif;\n    // - bad modify\n    static uint8_t mainnet_p2kh;\n    static const uint16_t mainnet;\n    static const uint8_t compressed_sentinel;\n\n    static inline uint8_t to_address_prefix(uint16_t version)\n    {\n        return version & 0x00FF;\n    }\n\n    static inline uint8_t to_wif_prefix(uint16_t version)\n    {\n        return version >> 8;\n    }\n\n    // Unfortunately can't use this below to define mainnet (MSVC).\n    static inline uint16_t to_version(uint8_t address, uint8_t wif)\n    {\n        return uint16_t(wif) << 8 | address;\n    }\n\n    /// Constructors.\n    ec_private();\n    ec_private(const ec_private &other);\n    ec_private(const std::string &wif, uint8_t version = mainnet_p2kh);\n    ec_private(const wif_compressed &wif, uint8_t version = mainnet_p2kh);\n    ec_private(const wif_uncompressed &wif, uint8_t version = mainnet_p2kh);\n\n    /// The version is 16 bits. The most significant byte is the WIF prefix and\n    /// the least significant byte is the address perfix. 0x8000 by default.\n    ec_private(const ec_secret &secret, uint16_t version = mainnet,\n               bool compress = true);\n\n    /// Operators.\n    bool operator<(const ec_private &other) const;\n    bool operator==(const ec_private &other) const;\n    bool operator!=(const ec_private &other) const;\n    ec_private &operator=(const ec_private &other);\n    friend std::istream &operator>>(std::istream &in, ec_private &to);\n    friend std::ostream &operator<<(std::ostream &out, const ec_private &of);\n\n    /// Cast operators.\n    operator const bool() const;\n    operator const ec_secret &() const;\n\n    /// Serializer.\n    std::string encoded() const;\n\n    /// Accessors.\n    const ec_secret &secret() const;\n    const uint16_t version() const;\n    const uint8_t payment_version() const;\n    const uint8_t wif_version() const;\n    const bool compressed() const;\n\n    /// Methods.\n    ec_public to_public() const;\n    payment_address to_payment_address() const;\n\n  private:\n    /// Validators.\n    static bool is_wif(data_slice decoded);\n\n    /// Factories.\n    static ec_private from_string(const std::string &wif, uint8_t version);\n    static ec_private from_compressed(const wif_compressed &wif, uint8_t version);\n    static ec_private from_uncompressed(const wif_uncompressed &wif, uint8_t version);\n\n    /// Members.\n    /// These should be const, apart from the need to implement assignment.\n    bool valid_;\n    bool compress_;\n    uint16_t version_;\n    ec_secret secret_;\n};\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/wallet/ec_public.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_EC_PUBLIC_HPP\n#define UC_EC_PUBLIC_HPP\n\n#include <cstdint>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/math/elliptic_curve.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\nclass ec_private;\nclass payment_address;\n\n/// Use to pass an ec point as either ec_compressed or ec_uncompressed.\n/// ec_public doesn't carry a version for address creation or base58 encoding.\nclass BC_API ec_public\n{\n  public:\n    static const uint8_t compressed_even;\n    static const uint8_t compressed_odd;\n    static const uint8_t uncompressed;\n    // - bad modify\n    static uint8_t mainnet_p2kh;\n\n    /// Constructors.\n    ec_public();\n    ec_public(const ec_public &other);\n    ec_public(const ec_private &secret);\n    ec_public(const data_chunk &decoded);\n    ec_public(const std::string &base16);\n    ec_public(const ec_compressed &point, bool compress = true);\n    ec_public(const ec_uncompressed &point, bool compress = false);\n\n    /// Operators.\n    bool operator<(const ec_public &other) const;\n    bool operator==(const ec_public &other) const;\n    bool operator!=(const ec_public &other) const;\n    ec_public &operator=(const ec_public &other);\n    friend std::istream &operator>>(std::istream &in, ec_public &to);\n    friend std::ostream &operator<<(std::ostream &out, const ec_public &of);\n\n    /// Cast operators.\n    operator const bool() const;\n    operator const ec_compressed &() const;\n\n    /// Serializer.\n    std::string encoded() const;\n\n    /// Accessors.\n    const ec_compressed &point() const;\n    const uint16_t version() const;\n    const uint8_t payment_version() const;\n    const uint8_t wif_version() const;\n    const bool compressed() const;\n\n    /// Methods.\n    bool to_data(data_chunk &out) const;\n    bool to_uncompressed(ec_uncompressed &out) const;\n    payment_address to_payment_address(uint8_t version = mainnet_p2kh) const;\n\n  private:\n    /// Validators.\n    static bool is_point(data_slice decoded);\n\n    /// Factories.\n    static ec_public from_data(const data_chunk &decoded);\n    static ec_public from_private(const ec_private &secret);\n    static ec_public from_string(const std::string &base16);\n    static ec_public from_point(const ec_uncompressed &point, bool compress);\n\n    /// Members.\n    /// These should be const, apart from the need to implement assignment.\n    bool valid_;\n    bool compress_;\n    uint8_t version_;\n    ec_compressed point_;\n};\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/wallet/ek_private.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_WALLET_EK_PRIVATE_HPP\n#define UC_WALLET_EK_PRIVATE_HPP\n\n#include <iostream>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/wallet/encrypted_keys.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\n/// Use to pass an encrypted private key.\nclass BC_API ek_private\n{\n  public:\n    /// Constructors.\n    ek_private();\n    ek_private(const std::string &encoded);\n    ek_private(const encrypted_private &key);\n    ek_private(const ek_private &other);\n\n    /// Operators.\n    bool operator<(const ek_private &other) const;\n    bool operator==(const ek_private &other) const;\n    bool operator!=(const ek_private &other) const;\n    ek_private &operator=(const ek_private &other);\n    friend std::istream &operator>>(std::istream &in, ek_private &to);\n    friend std::ostream &operator<<(std::ostream &out, const ek_private &of);\n\n    /// Cast operators.\n    operator const bool() const;\n    operator const encrypted_private &() const;\n\n    /// Serializer.\n    std::string encoded() const;\n\n    /// Accessors.\n    const encrypted_private &private_key() const;\n\n  private:\n    /// Factories.\n    static ek_private from_string(const std::string &encoded);\n\n    /// Members.\n    /// These should be const, apart from the need to implement assignment.\n    bool valid_;\n    encrypted_private private_;\n};\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/wallet/ek_public.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_WALLET_EK_PUBLIC_HPP\n#define UC_WALLET_EK_PUBLIC_HPP\n\n#include <iostream>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/wallet/encrypted_keys.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\n/// Use to pass an encrypted public key.\nclass BC_API ek_public\n{\n  public:\n    /// Constructors.\n    ek_public();\n    ek_public(const std::string &encoded);\n    ek_public(const encrypted_public &key);\n    ek_public(const ek_public &other);\n\n    /// Operators.\n    bool operator<(const ek_public &other) const;\n    bool operator==(const ek_public &other) const;\n    bool operator!=(const ek_public &other) const;\n    ek_public &operator=(const ek_public &other);\n    friend std::istream &operator>>(std::istream &in, ek_public &to);\n    friend std::ostream &operator<<(std::ostream &out, const ek_public &of);\n\n    /// Cast operators.\n    operator const bool() const;\n    operator const encrypted_public &() const;\n\n    /// Serializer.\n    std::string encoded() const;\n\n    /// Accessors.\n    const encrypted_public &public_key() const;\n\n  private:\n    /// Factories.\n    static ek_public from_string(const std::string &encoded);\n\n    /// Members.\n    /// These should be const, apart from the need to implement assignment.\n    bool valid_;\n    encrypted_public public_;\n};\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/wallet/ek_token.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_WALLET_EK_TOKEN_HPP\n#define UC_WALLET_EK_TOKEN_HPP\n\n#include <iostream>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/wallet/encrypted_keys.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\n/**\n * Serialization helper to convert between base58 string and bip38 token.\n */\nclass BC_API ek_token\n{\n  public:\n    /// Constructors.\n    ek_token();\n    ek_token(const std::string &encoded);\n    ek_token(const encrypted_token &key);\n    ek_token(const ek_token &other);\n\n    /// Operators.\n    bool operator<(const ek_token &other) const;\n    bool operator==(const ek_token &other) const;\n    bool operator!=(const ek_token &other) const;\n    ek_token &operator=(const ek_token &other);\n    friend std::istream &operator>>(std::istream &in, ek_token &to);\n    friend std::ostream &operator<<(std::ostream &out, const ek_token &of);\n\n    /// Cast operators.\n    operator const bool() const;\n    operator const encrypted_token &() const;\n\n    /// Serializer.\n    std::string encoded() const;\n\n    /// Accessors.\n    const encrypted_token &token() const;\n\n  private:\n    /// Factories.\n    static ek_token from_string(const std::string &encoded);\n\n    /// Members.\n    /// These should be const, apart from the need to implement assignment.\n    bool valid_;\n    encrypted_token token_;\n};\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/wallet/encrypted_keys.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_ENCRYPTED_KEYS_HPP\n#define UC_ENCRYPTED_KEYS_HPP\n\n#include <string>\n#include <UChain/coin/compat.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/crypto.hpp>\n#include <UChain/coin/math/elliptic_curve.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/wallet/payment_address.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\n/**\n * The maximum lot and sequence values for encrypted key token creation.\n */\nstatic BC_CONSTEXPR uint32_t ek_max_lot = 1048575;\nstatic BC_CONSTEXPR uint32_t ek_max_sequence = 4095;\n\n/**\n * A seed for use in creating an intermediate passphrase (token).\n */\nstatic BC_CONSTEXPR size_t ek_salt_size = 4;\ntypedef byte_array<ek_salt_size> ek_salt;\n\n/**\n * A seed for use in creating an intermediate passphrase (token).\n */\nstatic BC_CONSTEXPR size_t ek_entropy_size = 8;\ntypedef byte_array<ek_entropy_size> ek_entropy;\n\n/**\n * A seed for use in creating a key pair.\n */\nstatic BC_CONSTEXPR size_t ek_seed_size = 24;\ntypedef byte_array<ek_seed_size> ek_seed;\n\n/**\n * An intermediate passphrase (token) type (checked but not base58 encoded).\n */\nstatic BC_CONSTEXPR size_t encrypted_token_encoded_size = 72;\nstatic BC_CONSTEXPR size_t encrypted_token_decoded_size = 53;\ntypedef byte_array<encrypted_token_decoded_size> encrypted_token;\n\n/**\n * An encrypted private key type (checked but not base58 encoded).\n */\nstatic BC_CONSTEXPR size_t ek_private_encoded_size = 58;\nstatic BC_CONSTEXPR size_t ek_private_decoded_size = 43;\ntypedef byte_array<ek_private_decoded_size> encrypted_private;\n\n/**\n * DEPRECATED\n * An encrypted public key type (checked but not base58 encoded).\n * This is refered to as a confirmation code in bip38.\n */\nstatic BC_CONSTEXPR size_t encrypted_public_encoded_size = 75;\nstatic BC_CONSTEXPR size_t encrypted_public_decoded_size = 55;\ntypedef byte_array<encrypted_public_decoded_size> encrypted_public;\n\n// BIP38\n// It is requested that the unused flag bytes NOT be used for denoting that\n// the key belongs to an alt-chain [This shoud read \"flag bits\"].\nenum ek_flag : uint8_t\n{\n    lot_sequence_key = 1 << 2,\n    ec_compressed_key = 1 << 5,\n    ec_non_multiplied_low = 1 << 6,\n    ec_non_multiplied_high = 1 << 7,\n\n    /// Two bits are used to represent \"not multiplied\".\n    ec_non_multiplied = (ec_non_multiplied_low | ec_non_multiplied_high)\n};\n\n/**\n * Create an intermediate passphrase for subsequent key pair generation.\n * @param[out] out_token   The new intermediate passphrase.\n * @param[in]  passphrase  A passphrase for use in the encryption.\n * @param[in]  entropy     A random value for use in the encryption.\n * @return false if the token could not be created from the entropy.\n */\nBC_API bool create_token(encrypted_token &out_token,\n                         const std::string &passphrase, const ek_entropy &entropy);\n\n/**\n * Create an intermediate passphrase for subsequent key pair generation.\n * @param[out] out_token   The new intermediate passphrase.\n * @param[in]  passphrase  A passphrase for use in the encryption.\n * @param[in]  salt        A random value for use in the encryption.\n * @param[in]  lot         A lot, max allowed value 1048575 (2^20-1).\n * @param[in]  sequence    A sequence, max allowed value 4095 (2^12-1).\n * @return false if the lot and/or sequence are out of range or the token\n * could not be created from the entropy.\n */\nBC_API bool create_token(encrypted_token &out_token,\n                         const std::string &passphrase, const ek_salt &salt, uint32_t lot,\n                         uint32_t sequence);\n\n/**\n * Create an encrypted private key from an intermediate passphrase.\n * The `out_point` paramter is always compressed, so to use it it should be\n * decompressed as necessary to match the state of the `compressed` parameter.\n * @param[out] out_private  The new encrypted private key.\n * @param[out] out_point    The ec compressed public key of the new key pair.\n * @param[in]  token        An intermediate passphrase string.\n * @param[in]  seed         A random value for use in the encryption.\n * @param[in]  version      The coin address version byte.\n * @param[in]  compressed   Set true to associate ec public key compression.\n * @return false if the token checksum is not valid.\n */\nBC_API bool create_key_pair(encrypted_private &out_private,\n                            ec_compressed &out_point, const encrypted_token &token,\n                            const ek_seed &seed, uint8_t version, bool compressed = true);\n\n/**\n * DEPRECATED\n * Create an encrypted key pair from an intermediate passphrase.\n * The `out_point` paramter is always compressed, so to use it it should be\n * decompressed as necessary to match the state of the `compressed` parameter.\n * @param[out] out_private  The new encrypted private key.\n * @param[out] out_public   The new encrypted public key.\n * @param[out] out_point    The compressed ec public key of the new key pair.\n * @param[in]  token        An intermediate passphrase string.\n * @param[in]  seed         A random value for use in the encryption.\n * @param[in]  version      The coin address version byte.\n * @param[in]  compressed   Set true to associate ec public key compression.\n * @return false if the token checksum is not valid.\n */\nBC_API bool create_key_pair(encrypted_private &out_private,\n                            encrypted_public &out_public, ec_compressed &out_point,\n                            const encrypted_token &token, const ek_seed &seed, uint8_t version,\n                            bool compressed = true);\n\nvoid aes256_common_encrypt(data_chunk &mnemonic, data_chunk &passphrase, data_chunk &encry_output);\nvoid aes256_common_decrypt(const data_chunk &mnemonic, data_chunk &passphrase, data_chunk &decry_output);\n\nvoid encrypt_string(const std::string &mnemonic,\n                    std::string &passphrase, std::string &encry_output);\n\nvoid decrypt_string(const std::string &mnemonic,\n                    std::string &passphrase, std::string &decry_output);\n\n#ifdef WITH_ICU\n\n/**\n * Encrypt the ec secret to an encrypted public key using the passphrase.\n * @param[out] out_private  The new encrypted private key.\n * @param[in]  secret       An ec secret to encrypt.\n * @param[in]  passphrase   A passphrase for use in the encryption.\n * @param[in]  version      The coin address version byte.\n * @param[in]  compressed   Set true to associate ec public key compression.\n * @return false if the secret could not be converted to a public key.\n */\nBC_API bool encrypt(encrypted_private &out_private, const ec_secret &secret,\n                    const std::string &passphrase, uint8_t version, bool compressed = true);\n\n/**\n * Decrypt the ec secret associated with the encrypted private key.\n * @param[out] out_secret      The decrypted ec secret.\n * @param[out] out_version     The coin address version.\n * @param[out] out_compressed  The compression of the associated ec public key.\n * @param[in]  key             An encrypted private key.\n * @param[in]  passphrase      The passphrase from the encryption or token.\n * @return false if the key checksum or passphrase is not valid.\n */\nBC_API bool decrypt(ec_secret &out_secret, uint8_t &out_version,\n                    bool &out_compressed, const encrypted_private &key,\n                    const std::string &passphrase);\n\n/**\n * DEPRECATED\n * Decrypt the ec point associated with the encrypted public key.\n * @param[out] out_point       The decrypted ec compressed point.\n * @param[out] out_version     The coin address version of the public key.\n * @param[out] out_compressed  The public key specified compression state.\n * @param[in]  key             An encrypted public key.\n * @param[in]  passphrase      The passphrase of the associated token.\n * @return false if the key    checksum or passphrase is not valid.\n */\nBC_API bool decrypt(ec_compressed &out_point, uint8_t &out_version,\n                    bool &out_compressed, const encrypted_public &key,\n                    const std::string &passphrase);\n\n#endif // WITH_ICU\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/wallet/hd_private.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_WALLET_HD_PRIVATE_KEY_HPP\n#define UC_WALLET_HD_PRIVATE_KEY_HPP\n\n#include <cstdint>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/elliptic_curve.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/wallet/ec_private.hpp>\n#include <UChain/coin/wallet/ec_public.hpp>\n#include <UChain/coin/wallet/hd_public.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\n/// An extended private key, as defined by BIP 32.\nclass BC_API hd_private\n    : public hd_public\n{\n  public:\n    static const uint64_t mainnet;\n\n    static inline uint32_t to_prefix(uint64_t prefixes)\n    {\n        return prefixes >> 32;\n    }\n\n    static inline uint64_t to_prefixes(uint32_t private_prefix,\n                                       uint32_t public_prefix)\n    {\n        return uint64_t(private_prefix) << 32 | public_prefix;\n    }\n\n    /// Constructors.\n    hd_private();\n    hd_private(const hd_private &other);\n    hd_private(const data_chunk &seed, uint64_t prefixes = mainnet);\n    hd_private(const hd_key &private_key);\n    hd_private(const hd_key &private_key, uint64_t prefixes);\n    hd_private(const hd_key &private_key, uint32_t public_prefix);\n    hd_private(const std::string &encoded);\n    hd_private(const std::string &encoded, uint64_t prefixes);\n    hd_private(const std::string &encoded, uint32_t public_prefix);\n\n    /// Operators.\n    bool operator<(const hd_private &other) const;\n    bool operator==(const hd_private &other) const;\n    bool operator!=(const hd_private &other) const;\n    hd_private &operator=(const hd_private &other);\n    friend std::istream &operator>>(std::istream &in, hd_private &to);\n    friend std::ostream &operator<<(std::ostream &out,\n                                    const hd_private &of);\n\n    /// Cast operators.\n    operator const ec_secret &() const;\n\n    /// Serializer.\n    std::string encoded() const;\n\n    /// Accessors.\n    const ec_secret &secret() const;\n\n    /// Methods.\n    hd_key to_hd_key() const;\n    hd_public to_public() const;\n    hd_private derive_private(uint32_t index) const;\n    hd_public derive_public(uint32_t index) const;\n\n  private:\n    /// Factories.\n    static hd_private from_seed(data_slice seed, uint64_t prefixes);\n    static hd_private from_key(const hd_key &decoded);\n    static hd_private from_key(const hd_key &decoded, uint32_t prefix);\n    static hd_private from_key(const hd_key &decoded, uint64_t public_prefix);\n    static hd_private from_string(const std::string &encoded);\n    static hd_private from_string(const std::string &encoded,\n                                  uint32_t public_prefix);\n    static hd_private from_string(const std::string &encoded,\n                                  uint64_t prefixes);\n\n    hd_private(const ec_secret &secret, const hd_chain_code &chain_code,\n               const hd_lineage &lineage);\n\n    /// Members.\n    /// This should be const, apart from the need to implement assignment.\n    ec_secret secret_;\n};\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/wallet/hd_public.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_WALLET_HD_PUBLIC_KEY_HPP\n#define UC_WALLET_HD_PUBLIC_KEY_HPP\n\n#include <cstdint>\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/elliptic_curve.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/wallet/ec_public.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\n/// A constant used in key derivation.\nstatic BC_CONSTEXPR uint32_t hd_first_hardened_key = 1 << 31;\n\n/// An hd key chain code.\nstatic BC_CONSTEXPR size_t hd_chain_code_size = 32;\ntypedef byte_array<hd_chain_code_size> hd_chain_code;\n\n/// A decoded hd public or private key.\nstatic BC_CONSTEXPR size_t hd_key_size = 82;\ntypedef byte_array<hd_key_size> hd_key;\n\n/// Key derivation information used in the serialization format.\nstruct BC_API hd_lineage\n{\n    uint64_t prefixes;\n    uint8_t depth;\n    uint32_t parent_fingerprint;\n    uint32_t child_number;\n\n    bool operator==(const hd_lineage &other) const;\n    bool operator!=(const hd_lineage &other) const;\n};\n\nclass hd_private;\n\n/// An extended public key, as defined by BIP 32.\nclass BC_API hd_public\n{\n  public:\n    static const uint32_t mainnet;\n\n    static inline uint32_t to_prefix(uint64_t prefixes)\n    {\n        return prefixes & 0x00000000FFFFFFFF;\n    }\n\n    /// Constructors.\n    hd_public();\n    hd_public(const hd_public &other);\n    hd_public(const hd_key &public_key);\n    hd_public(const hd_key &public_key, uint32_t prefix);\n    hd_public(const std::string &encoded);\n    hd_public(const std::string &encoded, uint32_t prefix);\n\n    /// Operators.\n    bool operator<(const hd_public &other) const;\n    bool operator==(const hd_public &other) const;\n    bool operator!=(const hd_public &other) const;\n    hd_public &operator=(const hd_public &other);\n    friend std::istream &operator>>(std::istream &in, hd_public &to);\n    friend std::ostream &operator<<(std::ostream &out,\n                                    const hd_public &of);\n\n    /// Cast operators.\n    operator const bool() const;\n    operator const ec_compressed &() const;\n\n    /// Serializer.\n    std::string encoded() const;\n\n    /// Accessors.\n    const hd_chain_code &chain_code() const;\n    const hd_lineage &lineage() const;\n    const ec_compressed &point() const;\n\n    /// Methods.\n    hd_key to_hd_key() const;\n    hd_public derive_public(uint32_t index) const;\n\n  protected:\n    /// Factories.\n    static hd_public from_secret(const ec_secret &secret,\n                                 const hd_chain_code &chain_code, const hd_lineage &lineage);\n\n    /// Helpers.\n    uint32_t fingerprint() const;\n\n    /// Members.\n    /// These should be const, apart from the need to implement assignment.\n    bool valid_;\n    hd_chain_code chain_;\n    hd_lineage lineage_;\n    ec_compressed point_;\n\n  private:\n    static hd_public from_key(const hd_key &public_key);\n    static hd_public from_string(const std::string &encoded);\n    static hd_public from_key(const hd_key &public_key, uint32_t prefix);\n    static hd_public from_string(const std::string &encoded, uint32_t prefix);\n\n    hd_public(const ec_compressed &point,\n              const hd_chain_code &chain_code, const hd_lineage &lineage);\n};\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/wallet/mini_keys.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_MINI_KEYS_HPP\n#define UC_MINI_KEYS_HPP\n\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/elliptic_curve.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\n/**\n * Convert Cascasius minikey to secret parameter.\n */\nBC_API bool minikey_to_secret(ec_secret out_secret, const std::string &key);\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/wallet/mnemonic.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_WALLET_MNEMONIC_HPP\n#define UC_WALLET_MNEMONIC_HPP\n\n#include <cstddef>\n#include <string>\n#include <vector>\n#include <UChain/coin/compat.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/unicode/unicode.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/wallet/dictionary.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\n/**\n * A valid mnemonic word count is evenly divisible by this number.\n */\nstatic BC_CONSTEXPR size_t mnemonic_word_multiple = 3;\n\n/**\n * A valid seed byte count is evenly divisible by this number.\n */\nstatic BC_CONSTEXPR size_t mnemonic_seed_multiple = 4;\n\n/**\n * Represents a mnemonic word list.\n */\ntypedef std::vector<std::string> word_list;\n\n/**\n * Create a new mnenomic (list of words) from provided entropy and a dictionary\n * selection. The mnemonic can later be converted to a seed for use in wallet\n * creation. Entropy byte count must be evenly divisible by 4.\n */\nBC_API word_list create_mnemonic(data_slice entropy,\n                                 const dictionary &lexicon = language::en);\n\n/**\n * Checks a mnemonic against a dictionary to determine if the\n * words are spelled correctly and the checksum matches.\n * The words must have been created using mnemonic encoding.\n */\nBC_API bool validate_mnemonic(const word_list &mnemonic,\n                              const dictionary &lexicon);\n\n/**\n * Checks that a mnemonic is valid in at least one of the provided languages.\n */\nBC_API bool validate_mnemonic(const word_list &mnemonic,\n                              const dictionary_list &lexicons = language::all);\n\n/**\n * Convert a mnemonic with no passphrase to a wallet-generation seed.\n */\nBC_API long_hash decode_mnemonic(const word_list &mnemonic);\n\n#ifdef WITH_ICU\n\n/**\n * Convert a mnemonic and passphrase to a wallet-generation seed.\n * Any passphrase can be used and will change the resulting seed.\n */\nBC_API long_hash decode_mnemonic(const word_list &mnemonic,\n                                 const std::string &passphrase);\n\n#endif\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/wallet/payment_address.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_WALLET_PAYMENT_ADDRESS_HPP\n#define UC_WALLET_PAYMENT_ADDRESS_HPP\n\n#include <algorithm>\n#include <cstdint>\n#include <string>\n#include <UChain/coin/chain/script/script.hpp>\n#include <UChain/coin/compat.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/checksum.hpp>\n#include <UChain/coin/math/elliptic_curve.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/wallet/ec_private.hpp>\n#include <UChain/coin/wallet/ec_public.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\nstatic BC_CONSTEXPR size_t payment_size = 1u + short_hash_size + checksum_size;\ntypedef byte_array<payment_size> payment;\n\n/// A class for working with non-stealth payment addresses.\nclass BC_API payment_address\n{\n  public:\n    // - bad modify\n    static uint8_t mainnet_p2kh;\n    static const uint8_t mainnet_p2sh;\n    static const std::string blackhole_address;\n\n    /// Extract a payment address from an input or output script.\n    /// The address will be invalid if and only if the script type is not\n    /// supported or the script is itself invalid.\n    static payment_address extract(const chain::script &script,\n                                   uint8_t p2kh_version = mainnet_p2kh, uint8_t p2sh_version = mainnet_p2sh);\n\n    /// Constructors.\n    payment_address();\n    payment_address(const payment &decoded);\n    payment_address(const ec_private &secret);\n    payment_address(const std::string &address);\n    payment_address(const payment_address &other);\n    payment_address(const short_hash &hash, uint8_t version = mainnet_p2kh);\n    payment_address(const ec_public &point, uint8_t version = mainnet_p2kh);\n    payment_address(const chain::script &script, uint8_t version = mainnet_p2sh);\n\n    /// Operators.\n    bool operator<(const payment_address &other) const;\n    bool operator==(const payment_address &other) const;\n    bool operator!=(const payment_address &other) const;\n    payment_address &operator=(const payment_address &other);\n    friend std::istream &operator>>(std::istream &in, payment_address &to);\n    friend std::ostream &operator<<(std::ostream &out,\n                                    const payment_address &of);\n\n    /// Cast operators.\n    operator const bool() const;\n    operator const short_hash &() const;\n\n    /// Serializer.\n    std::string encoded() const;\n\n    /// Accessors.\n    uint8_t version() const;\n    const short_hash &hash() const;\n\n    /// Methods.\n    payment to_payment() const;\n\n  private:\n    /// Validators.\n    static bool is_address(data_slice decoded);\n\n    /// Factories.\n    static payment_address from_string(const std::string &address);\n    static payment_address from_payment(const payment &decoded);\n    static payment_address from_private(const ec_private &secret);\n    static payment_address from_public(const ec_public &point, uint8_t version);\n    static payment_address from_script(const chain::script &script,\n                                       uint8_t version);\n\n    /// Members.\n    /// These should be const, apart from the need to implement assignment.\n    bool valid_;\n    uint8_t version_;\n    short_hash hash_;\n};\n\n/// The pre-encoded structure of a payment address or other similar data.\nstruct BC_API wrapped_data\n{\n    uint8_t version;\n    data_chunk payload;\n    uint32_t checksum;\n};\n\n} // namespace wallet\n} // namespace libbitcoin\n\n// Allow payment_address to be in indexed in std::*map classes.\nnamespace std\n{\ntemplate <>\nstruct hash<bc::wallet::payment_address>\n{\n    size_t operator()(const bc::wallet::payment_address &address) const\n    {\n        return std::hash<bc::short_hash>()(address.hash());\n    }\n};\n\n} // namespace std\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/wallet/qrcode.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_QRENCODE_HPP\n#define UC_QRENCODE_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <iostream>\n#include <UChain/coin/compat.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n\n#ifdef WITH_QRENCODE\n#include <qrencode.h>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\nclass BC_API qr\n{\n    typedef QRencodeMode encode_mode;\n    typedef QRecLevel error_recovery_level;\n\n  public:\n    static BC_CONSTEXPR uint32_t version = 0;\n    static BC_CONSTEXPR bool case_sensitive = true;\n    static BC_CONSTEXPR encode_mode mode = QR_MODE_8;\n    static BC_CONSTEXPR error_recovery_level level = QR_ECLEVEL_L;\n\n    /**\n     * A method that takes an input stream and writes the encoded qr data\n     * to the specified output stream with default parameter values.\n     */\n    BC_API static bool encode(std::istream &in, std::ostream &out);\n\n    /**\n     * A method that takes a data chunk and returns the encoded qr data as\n     * a data_chunk with default parameter values.\n     */\n    BC_API static data_chunk encode(const data_chunk &data);\n\n    /**\n     * A method that takes a data chunk and returns the encoded qr data as\n     * a data chunk with the specified parameter values.\n     */\n    BC_API static data_chunk encode(const data_chunk &data,\n                                    const uint32_t version, const error_recovery_level level,\n                                    const encode_mode mode, const bool case_sensitive);\n\n    /**\n     * A method that takes an input stream and writes the encoded qr data\n     * to the output stream with the specified parameter values.\n     */\n    BC_API static bool encode(std::istream &in, uint32_t version,\n                              error_recovery_level level, encode_mode mode, bool case_sensitive,\n                              std::ostream &out);\n};\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#endif // WITH_QRENCODE\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/wallet/select_outputs.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_WALLET_SELECT_OUTPUTS_HPP\n#define UC_WALLET_SELECT_OUTPUTS_HPP\n\n#include <cstdint>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/chain/output.hpp>\n#include <UChain/coin/chain/point.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\nstruct BC_API select_outputs\n{\n    enum class algorithm\n    {\n        greedy\n    };\n\n    /// Select optimal outpoints for a spend from unspent outputs list.\n    /// Return includes the amount of change remaining from the spend.\n    static void select(chain::points_info &out,\n                       chain::output_info::list unspent, uint64_t minimum_value,\n                       algorithm option = algorithm::greedy);\n};\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/wallet/settings.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_WALLET_SETTINGS_HPP\n#define UC_WALLET_SETTINGS_HPP\n\n#include <cstdint>\n#include <UChain/coin/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\nstruct BC_API settings\n{\n    uint8_t address_public_key;\n    uint8_t address_script;\n    uint8_t address_stealth;\n    uint8_t private_key;\n    uint64_t private_key_hd;\n    uint64_t public_key_hd;\n};\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/wallet/stealth_address.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_WALLET_STEALTH_ADDRESS_HPP\n#define UC_WALLET_STEALTH_ADDRESS_HPP\n\n#include <cstdint>\n#include <vector>\n#include <UChain/coin/chain/script/script.hpp>\n#include <UChain/coin/constants.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/elliptic_curve.hpp>\n#include <UChain/coin/utility/binary.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\n/// A class for working with stealth payment addresses.\nclass BC_API stealth_address\n{\n  public:\n    /// DEPRECATED: we intend to make p2kh same as payment address versions.\n    static const uint8_t mainnet_p2kh;\n    static const uint8_t reuse_key_flag;\n    static const uint8_t max_filter_bits;\n\n    /// Constructors.\n    stealth_address();\n    stealth_address(const data_chunk &decoded);\n    stealth_address(const std::string &encoded);\n    stealth_address(const stealth_address &other);\n    stealth_address(const binary &filter, const ec_compressed &scan_key,\n                    const point_list &spend_keys, uint8_t signatures = 0,\n                    uint8_t version = mainnet_p2kh);\n\n    /// Operators.\n    bool operator<(const stealth_address &other) const;\n    bool operator==(const stealth_address &other) const;\n    bool operator!=(const stealth_address &other) const;\n    stealth_address &operator=(const stealth_address &other);\n    friend std::istream &operator>>(std::istream &in, stealth_address &to);\n    friend std::ostream &operator<<(std::ostream &out,\n                                    const stealth_address &of);\n\n    /// Cast operators.\n    operator bool() const;\n    operator data_chunk() const;\n\n    /// Serializer.\n    std::string encoded() const;\n\n    /// Accessors.\n    uint8_t version() const;\n    const ec_compressed &scan_key() const;\n    const point_list &spend_keys() const;\n    uint8_t signatures() const;\n    const binary &filter() const;\n\n    /// Methods.\n    data_chunk to_chunk() const;\n\n  private:\n    /// Factories.\n    static stealth_address from_string(const std::string &encoded);\n    static stealth_address from_stealth(const data_chunk &decoded);\n    static stealth_address from_stealth(const binary &filter,\n                                        const ec_compressed &scan_key, const point_list &spend_keys,\n                                        uint8_t signatures, uint8_t version);\n\n    /// Parameter order is used to change the constructor signature.\n    stealth_address(uint8_t version, const binary &filter,\n                    const ec_compressed &scan_key, const point_list &spend_keys,\n                    uint8_t signatures);\n\n    /// Helpers.\n    bool reuse_key() const;\n    uint8_t options() const;\n\n    /// Members.\n    /// These should be const, apart from the need to implement assignment.\n    bool valid_;\n    uint8_t version_;\n    ec_compressed scan_key_;\n    point_list spend_keys_;\n    uint8_t signatures_;\n    binary filter_;\n};\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/wallet/uri.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_WALLET_URI_HPP\n#define UC_WALLET_URI_HPP\n\n#include <map>\n#include <string>\n#include <UChain/coin/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\n/**\n * A parsed URI according to RFC 3986.\n */\nclass BC_API uri\n{\n  public:\n    /**\n     * Decodes a URI from a string.\n     * @param strict Set to false to tolerate unescaped special characters.\n     */\n    bool decode(const std::string &encoded, bool strict = true);\n    std::string encoded() const;\n\n    /**\n     * Returns the lowercased URI scheme.\n     */\n    std::string scheme() const;\n    void set_scheme(const std::string &scheme);\n\n    /**\n     * Obtains the unescaped authority part, if any (user@server:port).\n     */\n    std::string authority() const;\n    bool has_authority() const;\n    void set_authority(const std::string &authority);\n    void remove_authority();\n\n    /**\n     * Obtains the unescaped path part.\n     */\n    std::string path() const;\n    void set_path(const std::string &path);\n\n    /**\n     * Returns the unescaped query string, if any.\n     */\n    std::string query() const;\n    bool has_query() const;\n    void set_query(const std::string &query);\n    void remove_query();\n\n    /**\n     * Returns the unescaped fragment string, if any.\n     */\n    std::string fragment() const;\n    bool has_fragment() const;\n    void set_fragment(const std::string &fragment);\n    void remove_fragment();\n\n    typedef std::map<std::string, std::string> query_map;\n\n    /**\n     * Interprets the query string as a sequence of key-value pairs.\n     * All query strings are valid, so this function cannot fail.\n     * The results are unescaped. Both keys and values can be zero-length,\n     * and if the same key is appears multiple times, the final one wins.\n     */\n    query_map decode_query() const;\n    void encode_query(const query_map &map);\n\n  private:\n    // All parts are stored with their original escaping:\n    std::string scheme_;\n    std::string authority_;\n    std::string path_;\n    std::string query_;\n    std::string fragment_;\n\n    bool has_authority_ = false;\n    bool has_query_ = false;\n    bool has_fragment_ = false;\n};\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin/wallet/uri_reader.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_WALLET_URI_READER_HPP\n#define UC_WALLET_URI_READER_HPP\n\n#include <string>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/wallet/uri.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\n/**\n * Interface for URI deserialization.\n * The URI parser calls these methods as it extracts each URI component.\n * A false return from any setter is expected to terminate the parser.\n */\nclass BC_API uri_reader\n{\n  public:\n    /**\n     * Parses any URI string into its individual components.\n     * @param[in]  uri     The URI to parse.\n     * @param[in]  strict  Only accept properly-escaped parameters.\n     * @return The parsed URI or a default instance if the `uri` is malformed\n     * according to the  `UriReader`.\n     */\n    template <class UriReader>\n    static UriReader parse(const std::string &uri, bool strict = true)\n    {\n        bc::wallet::uri parsed;\n        if (!parsed.decode(uri, strict))\n            return UriReader();\n\n        UriReader out;\n        out.set_strict(strict);\n        out.set_scheme(parsed.scheme());\n        if (parsed.has_authority() && !out.set_authority(parsed.authority()))\n            return UriReader();\n\n        if (!parsed.path().empty() && !out.set_path(parsed.path()))\n            return UriReader();\n\n        if (parsed.has_fragment() && !out.set_fragment(parsed.fragment()))\n            return UriReader();\n\n        const auto query = parsed.decode_query();\n        for (const auto &term : query)\n        {\n            const auto &key = term.first;\n            const auto &value = term.second;\n            if (!key.empty() && !out.set_parameter(key, value))\n                return UriReader();\n        }\n\n        return out;\n    }\n\n    /// uri_reader interface.\n    virtual void set_strict(bool strict) = 0;\n    virtual bool set_scheme(const std::string &scheme) = 0;\n    virtual bool set_authority(const std::string &authority) = 0;\n    virtual bool set_path(const std::string &path) = 0;\n    virtual bool set_fragment(const std::string &fragment) = 0;\n    virtual bool set_parameter(const std::string &key,\n                               const std::string &value) = 0;\n};\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/coin.hpp",
    "content": "///////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 2014-2018 libbitcoin developers (see COPYING).\n//\n//        GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY\n//\n///////////////////////////////////////////////////////////////////////////////\n#ifndef UC_BITCOIN_HPP\n#define UC_BITCOIN_HPP\n\n/**\n * API Users: Include only this header. Direct use of other headers is fragile\n * and unsupported as header organization is subject to change.\n *\n * Maintainers: Do not include this header internal to this library.\n */\n\n#include <UChain/coin/compat.h>\n#include <UChain/coin/compat.hpp>\n#include <UChain/coin/constants.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/error.hpp>\n#include <UChain/coin/handlers.hpp>\n#include <UChain/coin/messages.hpp>\n#include <UChain/coin/version.hpp>\n#include <UChain/coin/chain/block.hpp>\n#include <UChain/coin/chain/header.hpp>\n#include <UChain/coin/chain/history.hpp>\n#include <UChain/coin/chain/input.hpp>\n#include <UChain/coin/chain/output.hpp>\n#include <UChain/coin/chain/point.hpp>\n#include <UChain/coin/chain/point_iterator.hpp>\n#include <UChain/coin/chain/spend.hpp>\n#include <UChain/coin/chain/stealth.hpp>\n#include <UChain/coin/chain/transaction.hpp>\n#include <UChain/coin/chain/script/opcode.hpp>\n#include <UChain/coin/chain/script/operation.hpp>\n#include <UChain/coin/chain/script/script.hpp>\n#include <UChain/coin/config/authority.hpp>\n#include <UChain/coin/config/base16.hpp>\n#include <UChain/coin/config/base2.hpp>\n#include <UChain/coin/config/base58.hpp>\n#include <UChain/coin/config/base64.hpp>\n#include <UChain/coin/config/checkpoint.hpp>\n#include <UChain/coin/config/directory.hpp>\n#include <UChain/coin/config/endpoint.hpp>\n#include <UChain/coin/config/hash160.hpp>\n#include <UChain/coin/config/hash256.hpp>\n#include <UChain/coin/config/parameter.hpp>\n#include <UChain/coin/config/parser.hpp>\n#include <UChain/coin/config/printer.hpp>\n#include <UChain/coin/config/sodium.hpp>\n#include <UChain/coin/formats/base_10.hpp>\n#include <UChain/coin/formats/base_16.hpp>\n#include <UChain/coin/formats/base_58.hpp>\n#include <UChain/coin/formats/base_64.hpp>\n#include <UChain/coin/formats/base_85.hpp>\n#include <UChain/coin/math/checksum.hpp>\n#include <UChain/coin/math/crypto.hpp>\n#include <UChain/coin/math/elliptic_curve.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/math/hash_number.hpp>\n#include <UChain/coin/math/script_number.hpp>\n#include <UChain/coin/math/stealth.hpp>\n#include <UChain/coin/math/uint256.hpp>\n#include <UChain/coin/message/address.hpp>\n#include <UChain/coin/message/block_msg.hpp>\n#include <UChain/coin/message/block_txs.hpp>\n#include <UChain/coin/message/compact_block.hpp>\n#include <UChain/coin/message/fee_filter.hpp>\n#include <UChain/coin/message/filter_add.hpp>\n#include <UChain/coin/message/filter_clear.hpp>\n#include <UChain/coin/message/filter_load.hpp>\n#include <UChain/coin/message/get_address.hpp>\n#include <UChain/coin/message/get_block_txs.hpp>\n#include <UChain/coin/message/get_blocks.hpp>\n#include <UChain/coin/message/get_data.hpp>\n#include <UChain/coin/message/get_headers.hpp>\n#include <UChain/coin/message/header_msg.hpp>\n#include <UChain/coin/message/headers.hpp>\n#include <UChain/coin/message/heading.hpp>\n#include <UChain/coin/message/inventory.hpp>\n#include <UChain/coin/message/inventory_vector.hpp>\n#include <UChain/coin/message/memory_pool.hpp>\n#include <UChain/coin/message/merkle_block.hpp>\n#include <UChain/coin/message/network_address.hpp>\n#include <UChain/coin/message/not_found.hpp>\n#include <UChain/coin/message/ping.hpp>\n#include <UChain/coin/message/pong.hpp>\n#include <UChain/coin/message/prefilled_tx.hpp>\n#include <UChain/coin/message/reject.hpp>\n#include <UChain/coin/message/send_compact_blocks.hpp>\n#include <UChain/coin/message/send_headers.hpp>\n#include <UChain/coin/message/tx_msg.hpp>\n#include <UChain/coin/message/verack.hpp>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/unicode/console_streambuf.hpp>\n#include <UChain/coin/unicode/ifstream.hpp>\n#include <UChain/coin/unicode/ofstream.hpp>\n#include <UChain/coin/unicode/unicode.hpp>\n#include <UChain/coin/unicode/unicode_istream.hpp>\n#include <UChain/coin/unicode/unicode_ostream.hpp>\n#include <UChain/coin/unicode/unicode_streambuf.hpp>\n#include <UChain/coin/utility/array_slice.hpp>\n#include <UChain/coin/utility/asio.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/atomic.hpp>\n#include <UChain/coin/utility/binary.hpp>\n#include <UChain/coin/utility/collection.hpp>\n#include <UChain/coin/utility/color.hpp>\n#include <UChain/coin/utility/conditional_lock.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/deadline.hpp>\n#include <UChain/coin/utility/decorator.hpp>\n#include <UChain/coin/utility/delegates.hpp>\n#include <UChain/coin/utility/deserializer.hpp>\n#include <UChain/coin/utility/dispatcher.hpp>\n#include <UChain/coin/utility/enable_shared_from_base.hpp>\n#include <UChain/coin/utility/endian.hpp>\n#include <UChain/coin/utility/exceptions.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/log.hpp>\n#include <UChain/coin/utility/logging.hpp>\n#include <UChain/coin/utility/monitor.hpp>\n#include <UChain/coin/utility/notifier.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n#include <UChain/coin/utility/png.hpp>\n#include <UChain/coin/utility/random.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/resource_lock.hpp>\n#include <UChain/coin/utility/resubscriber.hpp>\n#include <UChain/coin/utility/scope_lock.hpp>\n#include <UChain/coin/utility/serializer.hpp>\n#include <UChain/coin/utility/string.hpp>\n#include <UChain/coin/utility/subscriber.hpp>\n#include <UChain/coin/utility/synchronizer.hpp>\n#include <UChain/coin/utility/thread.hpp>\n#include <UChain/coin/utility/threadpool.hpp>\n#include <UChain/coin/utility/timer.hpp>\n#include <UChain/coin/utility/track.hpp>\n#include <UChain/coin/utility/variable_uint_size.hpp>\n#include <UChain/coin/utility/work.hpp>\n#include <UChain/coin/utility/writer.hpp>\n#include <UChain/coin/wallet/bitcoin_uri.hpp>\n#include <UChain/coin/wallet/dictionary.hpp>\n#include <UChain/coin/wallet/ec_private.hpp>\n#include <UChain/coin/wallet/ec_public.hpp>\n#include <UChain/coin/wallet/ek_private.hpp>\n#include <UChain/coin/wallet/ek_public.hpp>\n#include <UChain/coin/wallet/ek_token.hpp>\n#include <UChain/coin/wallet/encrypted_keys.hpp>\n#include <UChain/coin/wallet/hd_private.hpp>\n#include <UChain/coin/wallet/hd_public.hpp>\n#include <UChain/coin/wallet/msg.hpp>\n#include <UChain/coin/wallet/mini_keys.hpp>\n#include <UChain/coin/wallet/mnemonic.hpp>\n#include <UChain/coin/wallet/payment_address.hpp>\n#include <UChain/coin/wallet/qrcode.hpp>\n#include <UChain/coin/wallet/select_outputs.hpp>\n#include <UChain/coin/wallet/settings.hpp>\n#include <UChain/coin/wallet/stealth_address.hpp>\n#include <UChain/coin/wallet/uri.hpp>\n#include <UChain/coin/wallet/uri_reader.hpp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/data_base.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_DATA_BASE_HPP\n#define UC_DATABASE_DATA_BASE_HPP\n\n#include <atomic>\n#include <cstddef>\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <boost/interprocess/sync/file_lock.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/databases/block_db.hpp>\n#include <UChain/database/databases/spend_db.hpp>\n#include <UChain/database/databases/tx_db.hpp>\n#include <UChain/database/databases/history_db.hpp>\n#include <UChain/database/databases/stealth_db.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/settings.hpp>\n\n#include <boost/variant.hpp>\n#include <UChainService/txs/token/token.hpp>\n#include <UChainService/txs/ucn/ucn.hpp>\n#include <UChainService/txs/message/msg.hpp>\n#include <UChainService/txs/wallet/wallet.hpp>\n#include <UChainService/txs/token/token_detail.hpp>\n#include <UChainService/txs/token/token_transfer.hpp>\n#include <UChainService/txs/asset.hpp>\n\n#include <UChainService/data/databases/wallet_db.hpp>\n#include <UChainService/data/databases/wallet_address_db.hpp>\n#include <UChainService/data/databases/token_db.hpp>\n#include <UChainService/data/databases/blockchain_token_db.hpp>\n#include <UChainService/data/databases/address_token_db.hpp>\n#include <UChainService/data/databases/wallet_token_db.hpp>\n#include <UChainService/txs/uid/uid.hpp>\n#include <UChainService/data/databases/blockchain_token_cert_db.hpp>\n#include <UChainService/data/databases/blockchain_uid_db.hpp>\n#include <UChainService/data/databases/address_uid_db.hpp>\n#include <UChainService/data/databases/blockchain_candidate_db.hpp>\n#include <UChainService/data/databases/candidate_history_db.hpp>\n\nusing namespace libbitcoin::wallet;\nusing namespace libbitcoin::chain;\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\ntypedef uint64_t handle;\n\nclass BCD_API data_base\n{\n  public:\n    typedef boost::filesystem::path path;\n\n    class store\n    {\n      public:\n        store(const path &prefix);\n        bool touch_all() const;\n        bool touch_uids() const;\n        bool uids_exist() const;\n        bool touch_tokens() const;\n        bool tokens_exist() const;\n        bool touch_certs() const;\n        bool certs_exist() const;\n        bool touch_candidates() const;\n        bool candidates_exist() const;\n\n        path database_lock;\n        path blocks_lookup;\n        path blocks_index;\n        path history_lookup;\n        path history_rows;\n        path stealth_rows;\n        path spends_lookup;\n        path transactions_lookup;\n        /* begin database for wallet, token, address_token, uid relationship */\n        path wallets_lookup;\n        path tokens_lookup;\n        path certs_lookup;\n        path address_tokens_lookup;\n        path address_tokens_rows;\n        path wallet_tokens_lookup;\n        path wallet_tokens_rows;\n        path uids_lookup;\n        path address_uids_lookup;\n        path address_uids_rows;\n        path wallet_addresses_lookup;\n        path wallet_addresses_rows;\n        /* end database for wallet, token, address_token, uid ,address_uid relationship */\n        path candidates_lookup;\n        path address_candidates_lookup;\n        path address_candidates_rows;\n        path candidate_history_lookup;\n        path candidate_history_rows;\n    };\n\n    class db_metadata\n    {\n      public:\n        db_metadata();\n        db_metadata(std::string version);\n        void reset();\n        bool from_data(const data_chunk &data);\n        bool from_data(std::istream &stream);\n        bool from_data(reader &source);\n        data_chunk to_data() const;\n        void to_data(std::ostream &stream) const;\n        void to_data(writer &sink) const;\n        uint64_t serialized_size() const;\n\n#ifdef UC_DEBUG\n        std::string to_string() const;\n#endif\n        friend std::istream &operator>>(std::istream &input, db_metadata &metadata);\n        friend std::ostream &operator<<(std::ostream &output, const db_metadata &metadata);\n        static const std::string current_version;\n        static const std::string file_name;\n\n        std::string version_;\n    };\n\n    /// Create a new database file with a given path prefix and default paths.\n    static bool initialize(const path &prefix, const chain::block &genesis);\n    /// If database exists then upgrades to version 63.\n    static bool upgrade_version_63(const path &prefix);\n\n    static bool touch_file(const path &file_path);\n    static void write_metadata(const path &metadata_path, data_base::db_metadata &metadata);\n    static void read_metadata(const path &metadata_path, data_base::db_metadata &metadata);\n    /// Construct all databases.\n    data_base(const settings &settings);\n\n    /// Stop all databases (threads must be joined).\n    ~data_base();\n    // Startup and shutdown.\n    // ------------------------------------------------------------------------\n\n    /// Create and start all databases.\n    bool create();\n    bool create_uids();\n    bool create_tokens();\n    bool create_certs();\n    bool create_candidates();\n\n    /// Start all databases.\n    bool start();\n\n    /// Signal all databases to stop work.\n    bool stop();\n\n    /// Stop all databases (threads must be joined).\n    bool close();\n\n    // Locking.\n    // ------------------------------------------------------------------------\n\n    handle begin_read();\n    bool begin_write();\n    bool end_write();\n    bool is_read_valid(handle handle);\n    bool is_write_locked(handle handle);\n\n    // Push and pop.\n    // ------------------------------------------------------------------------\n\n    /// Commit block at next height with indexing and no duplicate protection.\n    void push(const chain::block &block);\n\n    /// Commit block at given height with indexing and no duplicate protection.\n    /// If height is not count + 1 then the count will not equal top height.\n    void push(const chain::block &block, uint64_t height);\n\n    /// Throws if the chain is empty.\n    chain::block pop();\n\n    /* begin store token info into  database */\n\n    void push_asset(const asset &attach, const payment_address &address,\n                    const output_point &outpoint, uint32_t output_height, uint64_t value);\n\n    void push_ucn(const ucn &ucn, const short_hash &key,\n                  const output_point &outpoint, uint32_t output_height, uint64_t value);\n\n    void push_ucn_award(const ucn_award &ucn, const short_hash &key,\n                        const output_point &outpoint, uint32_t output_height, uint64_t value);\n\n    void push_message(const chain::blockchain_message &msg, const short_hash &key,\n                      const output_point &outpoint, uint32_t output_height, uint64_t value);\n\n    void push_token(const token &sp, const short_hash &key,\n                    const output_point &outpoint, uint32_t output_height, uint64_t value);\n\n    void push_token_cert(const token_cert &sp_cert, const short_hash &key,\n                         const output_point &outpoint, uint32_t output_height, uint64_t value);\n\n    void push_token_detail(const token_detail &sp_detail, const short_hash &key,\n                           const output_point &outpoint, uint32_t output_height, uint64_t value);\n\n    void push_token_transfer(const token_transfer &sp_transfer, const short_hash &key,\n                             const output_point &outpoint, uint32_t output_height, uint64_t value);\n\n    void push_uid(const uid &sp, const short_hash &key,\n                  const output_point &outpoint, uint32_t output_height, uint64_t value);\n\n    void push_uid_detail(const uid_detail &sp_detail, const short_hash &key,\n                         const output_point &outpoint, uint32_t output_height, uint64_t value);\n\n    void push_candidate(const candidate &candidate, const short_hash &key,\n                        const output_point &outpoint, uint32_t output_height, uint64_t value,\n                        const std::string from_uid, std::string to_uid);\n\n    class asset_visitor : public boost::static_visitor<void>\n    {\n      public:\n        asset_visitor(data_base *db, const short_hash &sh_hash, const output_point &outpoint,\n                      uint32_t output_height, uint64_t value, const std::string from_uid, std::string to_uid) : db_(db), sh_hash_(sh_hash), outpoint_(outpoint), output_height_(output_height), value_(value),\n                                                                                                                from_uid_(from_uid), to_uid_(to_uid)\n        {\n        }\n        void operator()(const token &t) const\n        {\n            return db_->push_token(t, sh_hash_, outpoint_, output_height_, value_);\n        }\n        void operator()(const token_cert &t) const\n        {\n            return db_->push_token_cert(t, sh_hash_, outpoint_, output_height_, value_);\n        }\n        void operator()(const ucn &t) const\n        {\n            return db_->push_ucn(t, sh_hash_, outpoint_, output_height_, value_);\n        }\n        void operator()(const ucn_award &t) const\n        {\n            return db_->push_ucn_award(t, sh_hash_, outpoint_, output_height_, value_);\n        }\n        void operator()(const chain::blockchain_message &t) const\n        {\n            return db_->push_message(t, sh_hash_, outpoint_, output_height_, value_);\n        }\n        void operator()(const uid &t) const\n        {\n            return db_->push_uid(t, sh_hash_, outpoint_, output_height_, value_);\n        }\n        void operator()(const candidate &t) const\n        {\n            return db_->push_candidate(t, sh_hash_, outpoint_, output_height_, value_, from_uid_, to_uid_);\n        }\n\n      private:\n        data_base *db_;\n        short_hash sh_hash_;\n        output_point outpoint_;\n        uint32_t output_height_;\n        uint64_t value_;\n        std::string from_uid_;\n        std::string to_uid_;\n    };\n\n    class token_visitor : public boost::static_visitor<void>\n    {\n      public:\n        token_visitor(data_base *db, const short_hash &key,\n                      const output_point &outpoint, uint32_t output_height, uint64_t value) : db_(db), key_(key), outpoint_(outpoint), output_height_(output_height), value_(value)\n        {\n        }\n        void operator()(const token_detail &t) const\n        {\n            return db_->push_token_detail(t, key_, outpoint_, output_height_, value_);\n        }\n        void operator()(const token_transfer &t) const\n        {\n            return db_->push_token_transfer(t, key_, outpoint_, output_height_, value_);\n        }\n\n      private:\n        data_base *db_;\n        short_hash key_;\n        output_point outpoint_;\n        uint32_t output_height_;\n        uint64_t value_;\n    };\n\n    void set_admin(const std::string &name, const std::string &passwd);\n    void set_blackhole_uid();\n    void set_block_vote_token();\n    void set_reward_pool_candidate();\n    /* begin store token info into  database */\n\n  protected:\n    data_base(const store &paths, size_t history_height, size_t stealth_height);\n    data_base(const path &prefix, size_t history_height, size_t stealth_height);\n\n  private:\n    typedef chain::input::list inputs;\n    typedef chain::output::list outputs;\n    typedef std::atomic<size_t> sequential_lock;\n    typedef boost::interprocess::file_lock file_lock;\n\n    static bool initialize_uids(const path &prefix);\n    static bool initialize_tokens(const path &prefix);\n    static bool initialize_certs(const path &prefix);\n    static bool initialize_candidates(const path &prefix);\n\n    static void uninitialize_lock(const path &lock);\n    static file_lock initialize_lock(const path &lock);\n\n    void synchronize();\n    void synchronize_uids();\n    void synchronize_tokens();\n    void synchronize_certs();\n    void synchronize_candidates();\n\n    void push_inputs(const hash_digest &tx_hash, size_t height,\n                     const inputs &inputs);\n    void push_outputs(const hash_digest &tx_hash, size_t height,\n                      const outputs &outputs);\n    void push_stealth(const hash_digest &tx_hash, size_t height,\n                      const outputs &outputs);\n    void pop_inputs(const inputs &inputs, size_t height);\n    void pop_outputs(const outputs &outputs, size_t height);\n\n    const path lock_file_path_;\n    const size_t history_height_;\n    const size_t stealth_height_;\n\n    // Atomic counter for implementing the sequential lock pattern.\n    sequential_lock sequential_lock_;\n\n    // Allows us to restrict database access to our process (or fail).\n    std::shared_ptr<file_lock> file_lock_;\n\n    // Cross-database mutext to prevent concurrent file remapping.\n    std::shared_ptr<shared_mutex> mutex_;\n\n    // temp block timestamp\n    uint32_t timestamp_;\n\n  public:\n    /// Individual database query engines.\n    block_database blocks;\n    history_database history;\n    spend_database spends;\n    stealth_database stealth;\n    tx_database transactions;\n    /* begin database for wallet, token, address_token,uid relationship */\n    wallet_database wallets;\n    blockchain_token_database tokens;\n    address_token_database address_tokens;\n    wallet_token_database wallet_tokens;\n    blockchain_token_cert_database certs;\n    blockchain_uid_database uids;\n    address_uid_database address_uids;\n    wallet_address_database wallet_addresses;\n    /* end database for wallet, token, address_token relationship */\n    blockchain_candidate_database candidates;\n    candidate_history_database candidate_history;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/databases/base_db.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS) \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_BASE_DATABASE_HPP\n#define UC_DATABASE_BASE_DATABASE_HPP\n\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory_map.hpp>\n#include <UChain/database/result/base_result.hpp>\n#include <UChain/database/primitives/slab_hash_table.hpp>\n#include <UChain/database/primitives/slab_manager.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n/// This enables lookups of bases by hash.\n/// An alternative and faster method is lookup from a unique index\n/// that is assigned upon storage.\n/// This is so we can quickly reconstruct blocks given a list of tx indexes\n/// belonging to that block. These are stored with the block.\nclass BCD_API base_database\n{\n  public:\n    typedef slab_hash_table<hash_digest> slab_map;\n    /// Construct the database.\n    base_database(const boost::filesystem::path &map_filename,\n                  std::shared_ptr<shared_mutex> mutex = nullptr);\n\n    /// Close the database (all threads must first be stopped).\n    ~base_database();\n\n    /// Initialize a new base database.\n    bool create();\n\n    /// Call before using the database.\n    bool start();\n\n    /// Call to signal a stop of current operations.\n    bool stop();\n\n    /// Call to unload the memory map.\n    bool close();\n\n    /// Fetch base from its hash.\n    memory_ptr get(const hash_digest &hash) const;\n\n    /// every subclass should have its own store method, so store method is not define in this class\n\n    /// Delete a base from database.\n    void remove(const hash_digest &hash);\n\n    /// Synchronise storage with disk so things are consistent.\n    /// Should be done at the end of every block write.\n    void sync();\n\n    /// The hash table size (bucket count).\n    size_t get_bucket_count() const;\n\n  private:\n    // Hash table used for looking up txs by hash.\n    memory_map lookup_file_;\n    slab_hash_table_header lookup_header_;\n    slab_manager lookup_manager_;\n\n  protected:\n    slab_map lookup_map_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/databases/block_db.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_BLOCK_DATABASE_HPP\n#define UC_DATABASE_BLOCK_DATABASE_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory_map.hpp>\n#include <UChain/database/primitives/record_manager.hpp>\n#include <UChain/database/primitives/slab_hash_table.hpp>\n#include <UChain/database/result/block_result.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n/// Stores block_headers each with a list of transaction indexes.\n/// Lookup possible by hash or height.\nclass BCD_API block_database\n{\n  public:\n    static const file_offset empty;\n\n    /// Construct the database.\n    block_database(const boost::filesystem::path &map_filename,\n                   const boost::filesystem::path &index_filename,\n                   std::shared_ptr<shared_mutex> mutex = nullptr);\n\n    /// Close the database (all threads must first be stopped).\n    ~block_database();\n\n    /// Initialize a new transaction database.\n    bool create();\n\n    /// Call before using the database.\n    bool start();\n\n    /// Call to signal a stop of current operations.\n    bool stop();\n\n    /// Call to unload the memory map.\n    bool close();\n\n    /// Fetch block by height using the index table.\n    block_result get(size_t height) const;\n\n    /// Fetch block by hash using the hashtable.\n    block_result get(const hash_digest &hash) const;\n\n    /// Store a block in the database.\n    void store(const chain::block &block);\n\n    /// Store a block in the database.\n    void store(const chain::block &block, size_t height);\n\n    /// Unlink all blocks upwards from (and including) from_height.\n    void unlink(size_t from_height);\n\n    /// Remove block from block hash table\n    void remove(const hash_digest &hash);\n\n    /// Synchronise storage with disk so things are consistent.\n    /// Should be done at the end of every block write.\n    void sync();\n\n    /// The index of the highest existing block, independent of gaps.\n    bool top(size_t &out_height) const;\n\n    /// Return the first and last gaps in the blockchain, or false if none.\n    bool gap_range(size_t &out_first, size_t &out_last) const;\n\n    /// The index of the first missing block starting from given height.\n    bool next_gap(size_t &out_height, size_t start_height) const;\n\n  private:\n    typedef slab_hash_table<hash_digest> slab_map;\n\n    /// Zeroize the specfied index positions.\n    void zeroize(array_index first, array_index count);\n\n    /// Write block hash table position into the block index.\n    void write_position(file_offset position, array_index height);\n\n    /// Use block index to get block hash table position from height.\n    file_offset read_position(array_index height) const;\n\n    /// Hash table used for looking up blocks by hash.\n    memory_map lookup_file_;\n    slab_hash_table_header lookup_header_;\n    slab_manager lookup_manager_;\n    slab_map lookup_map_;\n\n    /// Table used for looking up blocks by height.\n    /// Resolves to a position within the slab.\n    memory_map index_file_;\n    record_manager index_manager_;\n\n    // Guard against concurrent update of a range of block indexes.\n    upgrade_mutex mutex_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/databases/history_db.hpp",
    "content": "/** \n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_HISTORY_DATABASE_HPP\n#define UC_DATABASE_HISTORY_DATABASE_HPP\n\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory_map.hpp>\n#include <UChain/database/primitives/record_multimap.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nstruct BCD_API history_statinfo\n{\n    /// Number of buckets used in the hashtable.\n    /// load factor = addrs / buckets\n    const size_t buckets;\n\n    /// Total number of unique addresses in the database.\n    const size_t addrs;\n\n    /// Total number of rows across all addresses.\n    const size_t rows;\n};\n\n/// This is a multimap where the key is the Bitcoin address hash,\n/// which returns several rows giving the history for that address.\nclass BCD_API history_database\n{\n  public:\n    /// Construct the database.\n    history_database(const boost::filesystem::path &lookup_filename,\n                     const boost::filesystem::path &rows_filename,\n                     std::shared_ptr<shared_mutex> mutex = nullptr);\n\n    /// Close the database (all threads must first be stopped).\n    ~history_database();\n\n    /// Initialize a new history database.\n    bool create();\n\n    /// Call before using the database.\n    bool start();\n\n    /// Call to signal a stop of current operations.\n    bool stop();\n\n    /// Call to unload the memory map.\n    bool close();\n\n    /// Add an output row to the key. If key doesn't exist it will be created.\n    void add_output(const short_hash &key, const chain::output_point &outpoint,\n                    uint32_t output_height, uint64_t value);\n\n    /// Add an input to the key. If key doesn't exist it will be created.\n    void add_input(const short_hash &key, const chain::output_point &inpoint,\n                   uint32_t input_height, const chain::input_point &previous);\n\n    /// Delete the last row that was added to key.\n    void delete_last_row(const short_hash &key);\n\n    /// Get the output and input points associated with the address hash.\n    chain::history_compact::list get(const short_hash &key, size_t limit,\n                                     size_t from_height) const;\n\n    /// Synchonise with disk.\n    void sync();\n\n    /// Return statistical info about the database.\n    history_statinfo statinfo() const;\n\n  private:\n    typedef record_hash_table<short_hash> record_map;\n    typedef record_multimap<short_hash> record_multiple_map;\n\n    /// Hash table used for start index lookup for linked list by address hash.\n    memory_map lookup_file_;\n    record_hash_table_header lookup_header_;\n    record_manager lookup_manager_;\n    record_map lookup_map_;\n\n    /// List of history rows.\n    memory_map rows_file_;\n    record_manager rows_manager_;\n    record_list rows_list_;\n    record_multiple_map rows_multimap_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/databases/spend_db.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_SPEND_DATABASE_HPP\n#define UC_DATABASE_SPEND_DATABASE_HPP\n\n#include <cstddef>\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/primitives/record_hash_table.hpp>\n#include <UChain/database/memory/memory_map.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nstruct BCD_API spend_statinfo\n{\n    /// Number of buckets used in the hashtable.\n    /// load factor = rows / buckets\n    const size_t buckets;\n\n    /// Total number of spend rows.\n    const size_t rows;\n};\n\n/// This enables you to lookup the spend of an output point, returning\n/// the input point. It is a simple map.\nclass BCD_API spend_database\n{\n  public:\n    /// Construct the database.\n    spend_database(const boost::filesystem::path &filename,\n                   std::shared_ptr<shared_mutex> mutex = nullptr);\n\n    /// Close the database (all threads must first be stopped).\n    ~spend_database();\n\n    /// Initialize a new spend database.\n    bool create();\n\n    /// Call before using the database.\n    bool start();\n\n    /// Call to signal a stop of current operations.\n    bool stop();\n\n    /// Call to unload the memory map.\n    bool close();\n\n    /// Get input spend of an output point.\n    chain::spend get(const chain::output_point &outpoint) const;\n\n    /// Store a spend in the database.\n    void store(const chain::output_point &outpoint,\n               const chain::input_point &spend);\n\n    /// Delete outpoint spend item from database.\n    void remove(const chain::output_point &outpoint);\n\n    /// Synchronise storage with disk so things are consistent.\n    /// Should be done at the end of every block write.\n    void sync();\n\n    /// Return statistical info about the database.\n    spend_statinfo statinfo() const;\n\n  private:\n    typedef record_hash_table<chain::point> record_map;\n\n    // Hash table used for looking up inpoint spends by outpoint.\n    memory_map lookup_file_;\n    record_hash_table_header lookup_header_;\n    record_manager lookup_manager_;\n    record_map lookup_map_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/databases/stealth_db.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_STEALTH_DATABASE_HPP\n#define UC_DATABASE_STEALTH_DATABASE_HPP\n\n#include <cstdint>\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory.hpp>\n#include <UChain/database/memory/memory_map.hpp>\n#include <UChain/database/primitives/record_manager.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nclass BCD_API stealth_database\n{\n  public:\n    typedef std::function<void(memory_ptr)> write_function;\n\n    /// Construct the database.\n    stealth_database(const boost::filesystem::path &rows_filename,\n                     std::shared_ptr<shared_mutex> mutex = nullptr);\n\n    /// Close the database (all threads must first be stopped).\n    ~stealth_database();\n\n    /// Initialize a new stealth database.\n    bool create();\n\n    /// Call before using the database.\n    bool start();\n\n    /// Call to signal a stop of current operations.\n    bool stop();\n\n    /// Call to unload the memory map.\n    bool close();\n\n    /// Linearly scan all entries, discarding those after from_height.\n    chain::stealth_compact::list scan(const binary &filter,\n                                      size_t from_height) const;\n\n    /// Add a stealth row to the database.\n    void store(uint32_t prefix, uint32_t height,\n               const chain::stealth_compact &row);\n\n    /// Delete all rows after and including from_height (no implemented).\n    void unlink(size_t from_height);\n\n    /// Synchronise storage with disk so things are consistent.\n    /// Should be done at the end of every block write.\n    void sync();\n\n  private:\n    void write_index();\n    array_index read_index(size_t from_height) const;\n\n    // Row entries containing stealth tx data.\n    memory_map rows_file_;\n    record_manager rows_manager_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/databases/tx_db.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_tx_database_HPP\n#define UC_DATABASE_tx_database_HPP\n\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory_map.hpp>\n#include <UChain/database/result/tx_result.hpp>\n#include <UChain/database/primitives/slab_hash_table.hpp>\n#include <UChain/database/primitives/slab_manager.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n/// This enables lookups of transactions by hash.\n/// An alternative and faster method is lookup from a unique index\n/// that is assigned upon storage.\n/// This is so we can quickly reconstruct blocks given a list of tx indexes\n/// belonging to that block. These are stored with the block.\nclass BCD_API tx_database\n{\n  public:\n    /// Construct the database.\n    tx_database(const boost::filesystem::path &map_filename,\n                         std::shared_ptr<shared_mutex> mutex = nullptr);\n\n    /// Close the database (all threads must first be stopped).\n    ~tx_database();\n\n    /// Initialize a new transaction database.\n    bool create();\n\n    /// Call before using the database.\n    bool start();\n\n    /// Call to signal a stop of current operations.\n    bool stop();\n\n    /// Call to unload the memory map.\n    bool close();\n\n    /// Fetch transaction from its hash.\n    tx_result get(const hash_digest &hash) const;\n\n    /// Store a transaction in the database. Returns a unique index\n    /// which can be used to reference the transaction.\n    void store(size_t height, size_t index, const chain::transaction &tx);\n\n    /// Delete a transaction from database.\n    void remove(const hash_digest &hash);\n\n    /// Synchronise storage with disk so things are consistent.\n    /// Should be done at the end of every block write.\n    void sync();\n\n  private:\n    typedef slab_hash_table<hash_digest> slab_map;\n\n    // Hash table used for looking up txs by hash.\n    memory_map lookup_file_;\n    slab_hash_table_header lookup_header_;\n    slab_manager lookup_manager_;\n    slab_map lookup_map_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/define.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_DEFINE_HPP\n#define UC_DATABASE_DEFINE_HPP\n\n#include <cstdint>\n#include <vector>\n#include <UChain/coin.hpp>\n\n// Now we use the generic helper definitions in libbitcoin to\n// define BCD_API and BCD_INTERNAL.\n// BCD_API is used for the public API symbols. It either DLL imports or\n// DLL exports (or does nothing for static build)\n// BCD_INTERNAL is used for non-api symbols.\n\n#if defined BCD_STATIC\n#define BCD_API\n#define BCD_INTERNAL\n#elif defined BCD_DLL\n#define BCD_API BC_HELPER_DLL_EXPORT\n#define BCD_INTERNAL BC_HELPER_DLL_LOCAL\n#else\n#define BCD_API BC_HELPER_DLL_IMPORT\n#define BCD_INTERNAL BC_HELPER_DLL_LOCAL\n#endif\n\n// Log name.\n#define LOG_DATABASE \"database\"\n\n// Remap safety is required if the mmap file is not fully preallocated.\n#define REMAP_SAFETY\n\n// Allocate safety is required for support of concurrent write operations.\n#define ALLOCATE_SAFETY\n\ntypedef uint32_t array_index;\ntypedef uint64_t file_offset;\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/impl/hash_table_header.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_HASH_TABLE_HEADER_IPP\n#define UC_DATABASE_HASH_TABLE_HEADER_IPP\n\n#include <cstring>\n#include <stdexcept>\n#include <UChain/coin.hpp>\n#include <UChain/database/memory/memory.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n// This VC++ workaround is OK because ValueType must be unsigned.\n//static constexpr ValueType empty = std::numeric_limits<ValueType>::max();\ntemplate <typename IndexType, typename ValueType>\nconst ValueType hash_table_header<IndexType, ValueType>::empty =\n    (ValueType)bc::max_uint64;\n\ntemplate <typename IndexType, typename ValueType>\nhash_table_header<IndexType, ValueType>::hash_table_header(memory_map &file,\n                                                           IndexType buckets)\n    : file_(file), buckets_(buckets)\n{\n    BITCOIN_ASSERT_MSG(empty == (ValueType)0xffffffffffffffff,\n                       \"Unexpected value for empty sentinel.\");\n\n    static_assert(std::is_unsigned<ValueType>::value,\n                  \"Hash table header requires unsigned type.\");\n}\n\ntemplate <typename IndexType, typename ValueType>\nbool hash_table_header<IndexType, ValueType>::create()\n{\n    // Cannot create zero-sized hash table.\n    // If buckets_ == 0 we trust what is read from the file.\n    if (buckets_ == 0)\n        return false;\n\n    // Calculate the minimum file size.\n    const auto minimum_file_size = item_position(buckets_);\n\n    // The accessor must remain in scope until the end of the block.\n    const auto memory = file_.resize(minimum_file_size);\n    const auto buckets_address = REMAP_ADDRESS(memory);\n    auto serial = make_serializer(buckets_address);\n    serial.write_little_endian(buckets_);\n\n    // optimized fill implementation\n    // This optimization makes it possible to debug full size headers.\n    const auto start = buckets_address + sizeof(IndexType);\n    memset(start, 0xff, buckets_ * sizeof(ValueType));\n\n    // rationalized fill implementation\n    ////for (IndexType index = 0; index < buckets_; ++index)\n    ////    serial.write_little_endian(empty);\n    return true;\n}\n\n// If false header file indicates incorrect size.\ntemplate <typename IndexType, typename ValueType>\nbool hash_table_header<IndexType, ValueType>::start()\n{\n    const auto minimum_file_size = item_position(buckets_);\n\n    // Header file is too small.\n    if (minimum_file_size > file_.size())\n        return false;\n\n    // The accessor must remain in scope until the end of the block.\n    const auto memory = file_.access();\n    const auto buckets_address = REMAP_ADDRESS(memory);\n\n    // Does not require atomicity (no concurrency during start).\n    const auto buckets = from_little_endian_unsafe<IndexType>(buckets_address);\n\n    // If buckets_ == 0 we trust what is read from the file.\n    return buckets_ == 0 || buckets == buckets_;\n}\n\ntemplate <typename IndexType, typename ValueType>\nValueType hash_table_header<IndexType, ValueType>::read(IndexType index) const\n{\n    // This is not runtime safe but test is avoided as an optimization.\n    BITCOIN_ASSERT(index < buckets_);\n\n    // The accessor must remain in scope until the end of the block.\n    const auto memory = file_.access();\n    const auto value_address = REMAP_ADDRESS(memory) + item_position(index);\n\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    shared_lock lock(mutex_);\n    return from_little_endian_unsafe<ValueType>(value_address);\n    ///////////////////////////////////////////////////////////////////////////\n}\n\ntemplate <typename IndexType, typename ValueType>\nvoid hash_table_header<IndexType, ValueType>::write(IndexType index,\n                                                    ValueType value)\n{\n    // This is not runtime safe but test is avoided as an optimization.\n    BITCOIN_ASSERT(index < buckets_);\n\n    // The accessor must remain in scope until the end of the block.\n    const auto memory = file_.access();\n    const auto value_address = REMAP_ADDRESS(memory) + item_position(index);\n    auto serial = make_serializer(value_address);\n\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    unique_lock lock(mutex_);\n    serial.template write_little_endian<ValueType>(value);\n    ///////////////////////////////////////////////////////////////////////////\n}\n\ntemplate <typename IndexType, typename ValueType>\nIndexType hash_table_header<IndexType, ValueType>::size() const\n{\n    return buckets_;\n}\n\ntemplate <typename IndexType, typename ValueType>\nfile_offset hash_table_header<IndexType, ValueType>::item_position(\n    IndexType index) const\n{\n    return sizeof(IndexType) + index * sizeof(ValueType);\n}\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/impl/record_hash_table.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_RECORD_HASH_TABLE_IPP\n#define UC_DATABASE_RECORD_HASH_TABLE_IPP\n\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/database/memory/memory.hpp>\n#include \"record_row.ipp\"\n#include \"remainder.ipp\"\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\ntemplate <typename KeyType>\nrecord_hash_table<KeyType>::record_hash_table(\n    record_hash_table_header &header, record_manager &manager)\n    : header_(header), manager_(manager)\n{\n}\n\n// This is not limited to storing unique key values. If duplicate keyed values\n// are store then retrieval and unlinking will fail as these multiples cannot\n// be differentiated.\ntemplate <typename KeyType>\nvoid record_hash_table<KeyType>::store(const KeyType &key,\n                                       const write_function write)\n{\n    mutex_.lock();\n    // Store current bucket value.\n    const auto old_begin = read_bucket_value(key);\n    record_row<KeyType> item(manager_, 0);\n    const auto new_begin = item.create(key, old_begin);\n    write(item.data());\n\n    // Link record to header.\n    link(key, new_begin);\n    mutex_.unlock();\n}\n\n// This is limited to returning the first of multiple matching key values.\ntemplate <typename KeyType>\nconst memory_ptr record_hash_table<KeyType>::find(const KeyType &key) const\n{\n    // Find start item...\n    auto current = read_bucket_value(key);\n\n    // Iterate through list...\n    while (current != header_.empty)\n    {\n        const record_row<KeyType> item(manager_, current);\n\n        // Found, return data.\n        if (item.compare(key))\n            return item.data();\n\n        const auto previous = current;\n        current = item.next_index();\n\n        // This may otherwise produce an infinite loop here.\n        // It indicates that a write operation has interceded.\n        // So we must return gracefully vs. looping forever.\n        if (previous == current)\n            return nullptr;\n    }\n\n    return nullptr;\n}\n\n// This is limited to returning all the item in the special index.\ntemplate <typename KeyType>\nstd::shared_ptr<std::vector<memory_ptr>> record_hash_table<KeyType>::find(array_index index) const\n{\n    auto vec_memo = std::make_shared<std::vector<memory_ptr>>();\n    // find first item\n    auto current = header_.read(index);\n    static_assert(sizeof(current) == sizeof(array_index), \"Invalid size\");\n\n    // Iterate through list...\n    while (current != header_.empty)\n    {\n        const record_row<KeyType> item(manager_, current);\n\n        // Found.\n        vec_memo->push_back(item.data());\n\n        const auto previous = current;\n        current = item.next_index();\n\n        // This may otherwise produce an infinite loop here.\n        // It indicates that a write operation has interceded.\n        // So we must return gracefully vs. looping forever.\n        if (previous == current)\n            break;\n    }\n\n    return vec_memo;\n}\n\n// This is limited to unlinking the first of multiple matching key values.\ntemplate <typename KeyType>\nbool record_hash_table<KeyType>::unlink(const KeyType &key)\n{\n    // Find start item...\n    const auto begin = read_bucket_value(key);\n    const record_row<KeyType> begin_item(manager_, begin);\n\n    // If start item has the key then unlink from buckets.\n    if (begin_item.compare(key))\n    {\n        link(key, begin_item.next_index());\n        return true;\n    }\n\n    // Continue on...\n    auto previous = begin;\n    auto current = begin_item.next_index();\n\n    // Iterate through list...\n    while (current != header_.empty)\n    {\n        const record_row<KeyType> item(manager_, current);\n\n        // Found, unlink current item from previous.\n        if (item.compare(key))\n        {\n            release(item, previous);\n            return true;\n        }\n\n        previous = current;\n        current = item.next_index();\n\n        // This may otherwise produce an infinite loop here.\n        // It indicates that a write operation has interceded.\n        // So we must return gracefully vs. looping forever.\n        if (previous == current)\n            return false;\n    }\n\n    return false;\n}\n\ntemplate <typename KeyType>\narray_index record_hash_table<KeyType>::bucket_index(\n    const KeyType &key) const\n{\n    const auto bucket = remainder(key, header_.size());\n    BITCOIN_ASSERT(bucket < header_.size());\n    return bucket;\n}\n\ntemplate <typename KeyType>\narray_index record_hash_table<KeyType>::read_bucket_value(\n    const KeyType &key) const\n{\n    auto value = header_.read(bucket_index(key));\n    static_assert(sizeof(value) == sizeof(array_index), \"Invalid size\");\n    return value;\n}\n\ntemplate <typename KeyType>\nvoid record_hash_table<KeyType>::link(const KeyType &key,\n                                      const array_index begin)\n{\n    header_.write(bucket_index(key), begin);\n}\n\ntemplate <typename KeyType>\ntemplate <typename ListItem>\nvoid record_hash_table<KeyType>::release(const ListItem &item,\n                                         const file_offset previous)\n{\n    ListItem previous_item(manager_, previous);\n    previous_item.write_next_index(item.next_index());\n}\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/impl/record_multimap.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_RECORD_MULTIMAP_IPP\n#define UC_DATABASE_RECORD_MULTIMAP_IPP\n\n#include <string>\n#include <UChain/database/memory/memory.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\ntemplate <typename KeyType>\nrecord_multimap<KeyType>::record_multimap(record_hash_table_type &map,\n                                          record_list &records)\n    : map_(map), records_(records)\n{\n}\n\ntemplate <typename KeyType>\narray_index record_multimap<KeyType>::lookup(const KeyType &key) const\n{\n    const auto start_info = map_.find(key);\n\n    if (!start_info)\n        return records_.empty;\n\n    const auto address = REMAP_ADDRESS(start_info);\n\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    unique_lock lock(mutex_);\n    return from_little_endian_unsafe<array_index>(address);\n    ///////////////////////////////////////////////////////////////////////////\n}\n\ntemplate <typename KeyType>\nstd::shared_ptr<std::vector<array_index>> record_multimap<KeyType>::lookup(array_index index) const\n{\n    auto sh_ret_vec = std::make_shared<std::vector<array_index>>();\n    auto sh_vec = map_.find(index);\n\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    unique_lock lock(mutex_);\n    for (auto each : *sh_vec)\n    {\n        const auto address = REMAP_ADDRESS(each);\n        sh_ret_vec->push_back(from_little_endian_unsafe<array_index>(address));\n    }\n    ///////////////////////////////////////////////////////////////////////////\n    return sh_ret_vec;\n}\n\ntemplate <typename KeyType>\nvoid record_multimap<KeyType>::add_row(const KeyType &key,\n                                       write_function write)\n{\n    const auto start_info = map_.find(key);\n\n    if (!start_info)\n    {\n        create_new(key, write);\n        return;\n    }\n\n    // This forwards a memory object.\n    add_to_list(start_info, write);\n}\n\ntemplate <typename KeyType>\nvoid record_multimap<KeyType>::add_to_list(memory_ptr start_info,\n                                           write_function write)\n{\n    const auto address = REMAP_ADDRESS(start_info);\n\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    mutex_.lock_shared();\n    const auto old_begin = from_little_endian_unsafe<array_index>(address);\n    mutex_.unlock_shared();\n    ///////////////////////////////////////////////////////////////////////////\n\n    const auto new_begin = records_.insert(old_begin);\n\n    // The records_ and start_info remap safe pointers are in distinct files.\n    write(records_.get(new_begin));\n\n    auto serial = make_serializer(address);\n\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    unique_lock lock(mutex_);\n    serial.template write_little_endian<array_index>(new_begin);\n    ///////////////////////////////////////////////////////////////////////////\n}\n\ntemplate <typename KeyType>\nvoid record_multimap<KeyType>::delete_last_row(const KeyType &key)\n{\n    const auto start_info = map_.find(key);\n    if (!start_info)\n    {\n        return;\n    }\n    BITCOIN_ASSERT_MSG(start_info, \"The row to delete was not found.\");\n\n    auto address = REMAP_ADDRESS(start_info);\n\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    mutex_.lock_shared();\n    const auto old_begin = from_little_endian_unsafe<array_index>(address);\n    mutex_.unlock_shared();\n    ///////////////////////////////////////////////////////////////////////////\n\n    BITCOIN_ASSERT(old_begin != records_.empty);\n    const auto new_begin = records_.next(old_begin);\n\n    if (new_begin == records_.empty)\n    {\n        // Free existing remap pointer to prevent deadlock in map_.unlink.\n        address = nullptr;\n\n        DEBUG_ONLY(bool success =)\n        map_.unlink(key);\n        BITCOIN_ASSERT(success);\n        return;\n    }\n\n    auto serial = make_serializer(address);\n\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    unique_lock lock(mutex_);\n    serial.template write_little_endian<array_index>(new_begin);\n    ///////////////////////////////////////////////////////////////////////////\n}\n\ntemplate <typename KeyType>\nvoid record_multimap<KeyType>::create_new(const KeyType &key,\n                                          write_function write)\n{\n    const auto first = records_.create();\n    write(records_.get(first));\n\n    const auto write_start_info = [this, first](memory_ptr data) {\n        auto serial = make_serializer(REMAP_ADDRESS(data));\n\n        // Critical Section\n        ///////////////////////////////////////////////////////////////////////////\n        unique_lock lock(mutex_);\n        serial.template write_little_endian<array_index>(first);\n        ///////////////////////////////////////////////////////////////////////////\n    };\n    map_.store(key, write_start_info);\n}\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/impl/record_row.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_RECORD_ROW_IPP\n#define UC_DATABASE_RECORD_ROW_IPP\n\n#include <UChain/database/memory/memory.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n/**\n * Item for record_hash_table. A chained list with the key included.\n *\n * Stores the key, next index and user data.\n * With the starting item, we can iterate until the end using the\n * next_index() method.\n */\ntemplate <typename KeyType>\nclass record_row\n{\n  public:\n    static BC_CONSTEXPR size_t index_size = sizeof(array_index);\n    static BC_CONSTEXPR size_t key_size = std::tuple_size<KeyType>::value;\n    static BC_CONSTEXPR file_offset value_begin = key_size + index_size;\n\n    record_row(record_manager &manager, array_index index);\n\n    array_index create(const KeyType &key, const array_index next);\n\n    /// Does this match?\n    bool compare(const KeyType &key) const;\n\n    /// The actual user data.\n    const memory_ptr data() const;\n\n    /// Position of next item in the chained list.\n    array_index next_index() const;\n\n    /// Write a new next index.\n    void write_next_index(array_index next);\n\n  private:\n    const memory_ptr raw_next_data() const;\n    const memory_ptr raw_data(file_offset offset) const;\n\n    array_index index_;\n    record_manager &manager_;\n    mutable shared_mutex mutex_;\n};\n\ntemplate <typename KeyType>\nrecord_row<KeyType>::record_row(record_manager &manager,\n                                const array_index index)\n    : manager_(manager), index_(index)\n{\n    static_assert(index_size == 4, \"Invalid array_index size.\");\n}\n\ntemplate <typename KeyType>\narray_index record_row<KeyType>::create(const KeyType &key,\n                                        const array_index next)\n{\n    // Create new record.\n    //   [ KeyType  ]\n    //   [ next:4   ]\n    //   [ value... ]\n    index_ = manager_.new_records(1);\n\n    // Write record.\n    const auto memory = raw_data(0);\n    const auto record = REMAP_ADDRESS(memory);\n    auto serial = make_serializer(record);\n    serial.write_data(key);\n\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    unique_lock lock(mutex_);\n    serial.template write_little_endian<array_index>(next);\n\n    return index_;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\ntemplate <typename KeyType>\nbool record_row<KeyType>::compare(const KeyType &key) const\n{\n    // Key data is at the start.\n    const auto memory = raw_data(0);\n    return std::equal(key.begin(), key.end(), REMAP_ADDRESS(memory));\n}\n\ntemplate <typename KeyType>\nconst memory_ptr record_row<KeyType>::data() const\n{\n    // Value data is at the end.\n    return raw_data(value_begin);\n}\n\ntemplate <typename KeyType>\narray_index record_row<KeyType>::next_index() const\n{\n    const auto memory = raw_next_data();\n    const auto next_address = REMAP_ADDRESS(memory);\n\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    shared_lock lock(mutex_);\n    return from_little_endian_unsafe<array_index>(next_address);\n    ///////////////////////////////////////////////////////////////////////////\n}\n\ntemplate <typename KeyType>\nvoid record_row<KeyType>::write_next_index(array_index next)\n{\n    const auto memory = raw_next_data();\n    auto serial = make_serializer(REMAP_ADDRESS(memory));\n\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    unique_lock lock(mutex_);\n    serial.template write_little_endian<array_index>(next);\n    ///////////////////////////////////////////////////////////////////////////\n}\n\ntemplate <typename KeyType>\nconst memory_ptr record_row<KeyType>::raw_data(file_offset offset) const\n{\n    auto memory = manager_.get(index_);\n    REMAP_INCREMENT(memory, offset);\n    return memory;\n}\n\ntemplate <typename KeyType>\nconst memory_ptr record_row<KeyType>::raw_next_data() const\n{\n    // Next position is after key data.\n    return raw_data(key_size);\n}\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/impl/remainder.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_REMAINDER_IPP\n#define UC_DATABASE_REMAINDER_IPP\n\n#include <cstdint>\n#include <functional>\n#include <UChain/coin.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n/// Return a hash of the key reduced to the domain of the divisor.\ntemplate <typename KeyType, typename Divisor>\nDivisor remainder(const KeyType &key, const Divisor divisor)\n{\n    return divisor == 0 ? 0 : std::hash<KeyType>()(key) % divisor;\n}\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/impl/slab_hash_table.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_SLAB_HASH_TABLE_IPP\n#define UC_DATABASE_SLAB_HASH_TABLE_IPP\n\n#include <UChain/coin.hpp>\n#include <UChain/database/memory/memory.hpp>\n#include \"remainder.ipp\"\n#include \"slab_row.ipp\"\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\ntemplate <typename KeyType>\nslab_hash_table<KeyType>::slab_hash_table(slab_hash_table_header &header,\n                                          slab_manager &manager)\n    : header_(header), manager_(manager)\n{\n}\n\n// This is not limited to storing unique key values. If duplicate keyed values\n// are store then retrieval and unlinking will fail as these multiples cannot\n// be differentiated. Therefore the database is not currently able to support\n// multiple transactions with the same hash, as required by BIP30.\ntemplate <typename KeyType>\nfile_offset slab_hash_table<KeyType>::store(const KeyType &key,\n                                            write_function write, const size_t value_size)\n{\n    mutex_.lock();\n    // Store current bucket value.\n    const auto old_begin = read_bucket_value(key);\n    slab_row<KeyType> item(manager_, 0);\n    const auto new_begin = item.create(key, value_size, old_begin);\n    write(item.data());\n\n    // Link record to header.\n    link(key, new_begin);\n\n    mutex_.unlock();\n\n    // Return position,\n    return new_begin + item.value_begin;\n}\n\n// This is not limited to store unique key values. If duplicate keyed values\n// are store then retrieval and unlinking will fail as these multiples cannot\n// be differentiated. Therefore the database is not currently able to support\n// multiple transactions with the same hash, as required by BIP30.\ntemplate <typename KeyType>\nfile_offset slab_hash_table<KeyType>::restore(const KeyType &key,\n                                              write_function write, const size_t value_size)\n{\n    mutex_.lock();\n    // Store current bucket value.\n    const auto old_begin = read_bucket_value(key);\n    slab_row<KeyType> item(manager_, old_begin);\n    //const auto new_begin = item.create(key, value_size, old_begin);\n    write(item.data());\n\n    // Link record to header.\n    //link(key, new_begin);\n\n    mutex_.unlock();\n\n    // Return position,\n    return old_begin + item.value_begin;\n}\n\n// This is limited to returning the first of multiple matching key values.\ntemplate <typename KeyType>\nconst memory_ptr slab_hash_table<KeyType>::find(const KeyType &key) const\n{\n    // Find start item...\n    auto current = read_bucket_value(key);\n\n    // Iterate through list...\n    while (current != header_.empty)\n    {\n        const slab_row<KeyType> item(manager_, current);\n\n        if (item.out_of_memory())\n            break;\n\n        // Found.\n        if (item.compare(key))\n            return item.data();\n\n        const auto previous = current;\n        current = item.next_position();\n\n        // This may otherwise produce an infinite loop here.\n        // It indicates that a write operation has interceded.\n        // So we must return gracefully vs. looping forever.\n        if (previous == current)\n            return nullptr;\n    }\n\n    return nullptr;\n}\n\n// This is limited to returning the last of multiple matching key values.\ntemplate <typename KeyType>\nconst memory_ptr slab_hash_table<KeyType>::rfind(const KeyType &key) const\n{\n    memory_ptr ret;\n    // Find start item...\n    auto current = read_bucket_value(key);\n\n    // Iterate through list...\n    while (current != header_.empty)\n    {\n        const slab_row<KeyType> item(manager_, current);\n\n        if (item.out_of_memory())\n            return nullptr;\n\n        // Found.\n        if (item.compare(key))\n            ret = item.data();\n\n        const auto previous = current;\n        current = item.next_position();\n\n        // This may otherwise produce an infinite loop here.\n        // It indicates that a write operation has interceded.\n        // So we must return gracefully vs. looping forever.\n        if (previous == current)\n            break;\n    }\n\n    return ret;\n}\n\n// This is returning all of multiple matching key values.\ntemplate <typename KeyType>\nstd::vector<memory_ptr> slab_hash_table<KeyType>::finds(const KeyType &key) const\n{\n    std::vector<memory_ptr> ret;\n    // Find start item...\n    auto current = read_bucket_value(key);\n\n    // Iterate through list...\n    while (current != header_.empty)\n    {\n        const slab_row<KeyType> item(manager_, current);\n\n        if (item.out_of_memory())\n            break;\n\n        // Found.\n        if (item.compare(key))\n            ret.push_back(item.data());\n\n        const auto previous = current;\n        current = item.next_position();\n\n        // This may otherwise produce an infinite loop here.\n        // It indicates that a write operation has interceded.\n        // So we must return gracefully vs. looping forever.\n        if (previous == current)\n            break;\n    }\n\n    return ret;\n}\n\n// This is limited to returning all the item in the special index.\ntemplate <typename KeyType>\nstd::shared_ptr<std::vector<memory_ptr>> slab_hash_table<KeyType>::find(uint64_t index) const\n{\n    auto vec_memo = std::make_shared<std::vector<memory_ptr>>();\n    // find first item\n    auto current = header_.read(index);\n    static_assert(sizeof(current) == sizeof(file_offset), \"Invalid size\");\n\n    // Iterate through list...\n    while (current != header_.empty)\n    {\n        const slab_row<KeyType> item(manager_, current);\n\n        if (item.out_of_memory())\n            break;\n\n        // Found.\n        vec_memo->push_back(item.data());\n\n        const auto previous = current;\n        current = item.next_position();\n\n        // This may otherwise produce an infinite loop here.\n        // It indicates that a write operation has interceded.\n        // So we must return gracefully vs. looping forever.\n        if (previous == current)\n            break;\n    }\n\n    return vec_memo;\n}\n\n// This is limited to unlinking the first of multiple matching key values.\ntemplate <typename KeyType>\nbool slab_hash_table<KeyType>::unlink(const KeyType &key)\n{\n    // Find start item...\n    const auto begin = read_bucket_value(key);\n    const slab_row<KeyType> begin_item(manager_, begin);\n\n    if (begin_item.out_of_memory())\n        return false;\n\n    // If start item has the key then unlink from buckets.\n    if (begin_item.compare(key))\n    {\n        link(key, begin_item.next_position());\n        return true;\n    }\n\n    // Continue on...\n    auto previous = begin;\n    auto current = begin_item.next_position();\n\n    // Iterate through list...\n    while (current != header_.empty)\n    {\n        const slab_row<KeyType> item(manager_, current);\n\n        if (item.out_of_memory())\n            return false;\n\n        // Found, unlink current item from previous.\n        if (item.compare(key))\n        {\n            release(item, previous);\n            return true;\n        }\n\n        previous = current;\n        current = item.next_position();\n\n        // This may otherwise produce an infinite loop here.\n        // It indicates that a write operation has interceded.\n        // So we must return gracefully vs. looping forever.\n        if (previous == current)\n            return false;\n    }\n\n    return false;\n}\n\ntemplate <typename KeyType>\narray_index slab_hash_table<KeyType>::bucket_index(const KeyType &key) const\n{\n    const auto bucket = remainder(key, header_.size());\n    BITCOIN_ASSERT(bucket < header_.size());\n    return bucket;\n}\n\ntemplate <typename KeyType>\nfile_offset slab_hash_table<KeyType>::read_bucket_value(\n    const KeyType &key) const\n{\n    const auto value = header_.read(bucket_index(key));\n    static_assert(sizeof(value) == sizeof(file_offset), \"Invalid size\");\n    return value;\n}\n\ntemplate <typename KeyType>\nvoid slab_hash_table<KeyType>::link(const KeyType &key,\n                                    const file_offset begin)\n{\n    header_.write(bucket_index(key), begin);\n}\n\ntemplate <typename KeyType>\ntemplate <typename ListItem>\nvoid slab_hash_table<KeyType>::release(const ListItem &item,\n                                       const file_offset previous)\n{\n    ListItem previous_item(manager_, previous);\n    previous_item.write_next_position(item.next_position());\n}\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/impl/slab_row.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_SLAB_LIST_IPP\n#define UC_DATABASE_SLAB_LIST_IPP\n\n#include <UChain/database/memory/memory.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n/**\n * Item for slab_hash_table. A chained list with the key included.\n *\n * Stores the key, next position and user data.\n * With the starting item, we can iterate until the end using the\n * next_position() method.\n */\ntemplate <typename KeyType>\nclass slab_row\n{\n  public:\n    static BC_CONSTEXPR size_t position_size = sizeof(file_offset);\n    static BC_CONSTEXPR size_t key_size = std::tuple_size<KeyType>::value;\n    static BC_CONSTEXPR file_offset value_begin = key_size + position_size;\n\n    slab_row(slab_manager &manager, file_offset position);\n\n    file_offset create(const KeyType &key, const size_t value_size,\n                       const file_offset next);\n\n    /// Does this match?\n    bool compare(const KeyType &key) const;\n\n    /// The actual user data.\n    const memory_ptr data() const;\n\n    /// Position of next item in the chained list.\n    file_offset next_position() const;\n\n    /// Write a new next position.\n    void write_next_position(file_offset next);\n\n    //whether cross the memory\n    bool out_of_memory() const;\n\n  private:\n    const memory_ptr raw_next_data() const;\n    const memory_ptr raw_data(file_offset offset) const;\n\n    file_offset position_;\n    slab_manager &manager_;\n    mutable shared_mutex mutex_;\n};\n\ntemplate <typename KeyType>\nslab_row<KeyType>::slab_row(slab_manager &manager,\n                            const file_offset position)\n    : manager_(manager), position_(position)\n{\n    static_assert(position_size == 8, \"Invalid file_offset size.\");\n}\n\ntemplate <typename KeyType>\nfile_offset slab_row<KeyType>::create(const KeyType &key,\n                                      const size_t value_size, const file_offset next)\n{\n    const file_offset info_size = key.size() + position_size;\n\n    // Create new slab.\n    //   [ KeyType  ]\n    //   [ next:8   ]\n    //   [ value... ]\n    const size_t slab_size = info_size + value_size;\n    position_ = manager_.new_slab(slab_size);\n\n    // Write to slab.\n    const auto memory = raw_data(0);\n    const auto key_data = REMAP_ADDRESS(memory);\n    auto serial = make_serializer(key_data);\n    serial.write_data(key);\n\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    unique_lock lock(mutex_);\n    serial.template write_little_endian<file_offset>(next);\n\n    return position_;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\ntemplate <typename KeyType>\nbool slab_row<KeyType>::compare(const KeyType &key) const\n{\n    // Key data is at the start.\n    const auto memory = raw_data(0);\n    return std::equal(key.begin(), key.end(), REMAP_ADDRESS(memory));\n}\n\ntemplate <typename KeyType>\nconst memory_ptr slab_row<KeyType>::data() const\n{\n    // Value data is at the end.\n    return raw_data(value_begin);\n}\n\ntemplate <typename KeyType>\nfile_offset slab_row<KeyType>::next_position() const\n{\n    const auto memory = raw_next_data();\n    const auto next_address = REMAP_ADDRESS(memory);\n\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    shared_lock lock(mutex_);\n    return from_little_endian_unsafe<file_offset>(next_address);\n    ///////////////////////////////////////////////////////////////////////////\n}\n\ntemplate <typename KeyType>\nvoid slab_row<KeyType>::write_next_position(file_offset next)\n{\n    const auto memory = raw_next_data();\n    auto serial = make_serializer(REMAP_ADDRESS(memory));\n\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    unique_lock lock(mutex_);\n    serial.template write_little_endian<file_offset>(next);\n    ///////////////////////////////////////////////////////////////////////////\n}\n\ntemplate <typename KeyType>\nconst memory_ptr slab_row<KeyType>::raw_data(file_offset offset) const\n{\n    auto memory = manager_.get(position_);\n    REMAP_INCREMENT(memory, offset);\n    return memory;\n}\n\ntemplate <typename KeyType>\nconst memory_ptr slab_row<KeyType>::raw_next_data() const\n{\n    // Next position is after key data.\n    return raw_data(key_size);\n}\n\ntemplate <typename KeyType>\nbool slab_row<KeyType>::out_of_memory() const\n{\n    return position_ > manager_.payload_size();\n}\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/memory/accessor.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_ACCESSOR_HPP\n#define UC_DATABASE_ACCESSOR_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n#ifdef REMAP_SAFETY\n\n/// This class provides shared remap safe access to file-mapped memory.\n/// The memory size is unprotected and unmanaged.\nclass BCD_API accessor\n    : public memory\n{\n  public:\n    accessor(shared_mutex &mutex, uint8_t *&data);\n    ~accessor();\n\n    /// This class is not copyable.\n    accessor(const accessor &other) = delete;\n\n    /// Get the address indicated by the pointer.\n    uint8_t *buffer();\n\n    /// Increment the pointer the specified number of bytes.\n    void increment(size_t value);\n\n  private:\n    shared_mutex &mutex_;\n    uint8_t *data_;\n};\n\n#endif // REMAP_SAFETY\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/memory/allocator.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_ALLOCATOR_HPP\n#define UC_DATABASE_ALLOCATOR_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n#ifdef REMAP_SAFETY\n\n/// This class provides downgradable remap safe access to file-mapped memory.\n/// The memory size is unprotected and unmanaged.\nclass BCD_API allocator\n    : public memory\n{\n  public:\n    allocator(shared_mutex &mutex);\n    ~allocator();\n\n    /// This class is not copyable.\n    allocator(const allocator &other) = delete;\n\n    /// Get the address indicated by the pointer.\n    uint8_t *buffer();\n\n    /// Increment the pointer the specified number of bytes.\n    void increment(size_t value);\n\n  protected:\n    friend class memory_map;\n\n    /// Set the data member and downgrade the lock.\n    void downgrade(uint8_t *data);\n\n  private:\n    shared_mutex &mutex_;\n    uint8_t *data_;\n};\n\n#endif // REMAP_SAFETY\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/memory/memory.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_MEMORY_HPP\n#define UC_DATABASE_MEMORY_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <memory>\n#include <boost/thread.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n#ifdef REMAP_SAFETY\n\n/// This interface defines remap safe unrestricted access to a memory map.\nclass BCD_API memory\n{\n  public:\n    typedef std::shared_ptr<memory> ptr;\n\n    /// Get the address indicated by the pointer.\n    virtual uint8_t *buffer() = 0;\n\n    /// Increment the pointer the specified number of bytes within the record.\n    virtual void increment(size_t value) = 0;\n};\n\n#endif // REMAP_SAFETY\n\n#ifdef REMAP_SAFETY\ntypedef memory::ptr memory_ptr;\n#define REMAP_ADDRESS(ptr) (ptr)->buffer()\n#define REMAP_DOWNGRADE(ptr, data) (ptr)->downgrade(data)\n#define REMAP_INCREMENT(ptr, offset) (ptr)->increment(offset)\n#define REMAP_ACCESSOR(ptr, mutex) std::make_shared<accessor>(mutex, ptr)\n#define REMAP_ALLOCATOR(mutex) std::make_shared<allocator>(mutex)\n#define REMAP_READ(mutex) shared_lock lock(mutex)\n#define REMAP_WRITE(mutex) unique_lock lock(mutex)\n#else\ntypedef uint8_t *memory_ptr;\n#define REMAP_ADDRESS(ptr) ptr\n#define REMAP_DOWNGRADE(ptr, data)\n#define REMAP_INCREMENT(ptr, offset) ptr += (offset)\n#define REMAP_ACCESSOR(ptr, mutex)\n#define REMAP_ALLOCATOR(mutex)\n#define REMAP_READ(mutex)\n#define REMAP_WRITE(mutex)\n#endif // REMAP_SAFETY\n\n#ifdef ALLOCATE_SAFETY\n#define ALLOCATE_READ(mutex) shared_lock lock(mutex)\n#define ALLOCATE_WRITE(mutex) unique_lock lock(mutex)\n#else\n#define ALLOCATE_READ(mutex)\n#define ALLOCATE_WRITE(mutex)\n#endif // ALLOCATE_SAFETY\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/memory/memory_map.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_MEMORY_MAP_HPP\n#define UC_DATABASE_MEMORY_MAP_HPP\n\n#ifndef _WIN32\n#include <sys/mman.h>\n#endif\n#include <atomic>\n#include <cstddef>\n#include <cstdint>\n#include <memory>\n#include <string>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n/// This class is thread safe, allowing concurent read and write.\n/// A change to the size of the memory map waits on and locks read and write.\nclass BCD_API memory_map\n{\n  public:\n    typedef std::shared_ptr<shared_mutex> mutex_ptr;\n\n    /// Construct a database (start is currently called, may throw).\n    memory_map(const boost::filesystem::path &filename);\n    memory_map(const boost::filesystem::path &filename, mutex_ptr mutex);\n\n    /// Close the database.\n    ~memory_map();\n\n    /// This class is not copyable.\n    memory_map(const memory_map &) = delete;\n    void operator=(const memory_map &) = delete;\n\n    /// Start or restart the database, mapping database files.\n    bool start();\n\n    /// Stop current work (optional, speeds shutdown with multiple threads).\n    bool stop();\n\n    /// Unmap database files, can be restarted.\n    bool close();\n\n    /// True if stop has signaled the end of work.\n    bool stopped() const;\n\n    size_t size() const;\n    memory_ptr access();\n    memory_ptr resize(size_t size);\n    memory_ptr reserve(size_t size);\n    memory_ptr reserve(size_t size, size_t growth_ratio);\n\n  private:\n    static size_t file_size(int file_handle);\n    static int open_file(const boost::filesystem::path &filename);\n    static bool handle_error(const std::string &context,\n                             const boost::filesystem::path &filename);\n\n    size_t page();\n    bool unmap();\n    bool map(size_t size);\n    bool remap(size_t size);\n    bool truncate(size_t size);\n    bool truncate_mapped(size_t size);\n    bool validate(size_t size);\n\n    void log_mapping();\n    void log_resizing(size_t size);\n    void log_unmapped();\n\n    // Optionally guard against concurrent remap.\n    mutex_ptr remap_mutex_;\n\n    // File system.\n    const int file_handle_;\n    const boost::filesystem::path filename_;\n\n    // Protected by internal mutex.\n    uint8_t *data_;\n    size_t file_size_;\n    size_t logical_size_;\n    std::atomic<bool> closed_;\n    std::atomic<bool> stopped_;\n    mutable upgrade_mutex mutex_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/primitives/hash_table_header.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_HASH_TABLE_HEADER_HPP\n#define UC_DATABASE_HASH_TABLE_HEADER_HPP\n\n#include <UChain/coin.hpp>\n#include <UChain/database/memory/memory_map.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n/**\n * Implements contigious memory array with a fixed size elements.\n *\n * File format looks like:\n *\n *  [   size:IndexType   ]\n *  [ [      ...       ] ]\n *  [ [ item:ValueType ] ]\n *  [ [      ...       ] ]\n *\n * Empty elements are represented by the value hash_table_header.empty\n */\ntemplate <typename IndexType, typename ValueType>\nclass hash_table_header\n{\n  public:\n    static const ValueType empty;\n\n    hash_table_header(memory_map &file, IndexType buckets);\n\n    // Copy.\n    hash_table_header(const hash_table_header &) = delete;\n    hash_table_header &operator=(const hash_table_header &) = delete;\n\n    // Move.\n    hash_table_header(hash_table_header &&) = delete;\n    hash_table_header &operator=(hash_table_header &&) = delete;\n\n    /// Allocate the hash table and populate with empty values.\n    bool create();\n\n    /// Must be called before use. Loads the size from the file.\n    bool start();\n\n    /// Read item's value.\n    ValueType read(IndexType index) const;\n\n    /// Write value to item.\n    void write(IndexType index, ValueType value);\n\n    /// The hash table size (bucket count).\n    IndexType size() const;\n\n  private:\n    // Locate the item in the memory map.\n    file_offset item_position(IndexType index) const;\n\n    memory_map &file_;\n    IndexType buckets_;\n    mutable shared_mutex mutex_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#include <UChain/database/impl/hash_table_header.ipp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/primitives/record_hash_table.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_RECORD_HASH_TABLE_HPP\n#define UC_DATABASE_RECORD_HASH_TABLE_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <tuple>\n#include <UChain/database/memory/memory.hpp>\n#include <UChain/database/primitives/hash_table_header.hpp>\n#include <UChain/database/primitives/record_manager.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\ntemplate <typename KeyType>\nBC_CONSTFUNC size_t hash_table_record_size(size_t value_size)\n{\n  return std::tuple_size<KeyType>::value + sizeof(array_index) + value_size;\n}\n\ntypedef hash_table_header<array_index, array_index> record_hash_table_header;\n\n/**\n * A hashtable mapping hashes to fixed sized values (records).\n * Uses a combination of the hash_table and record_manager.\n *\n * The hash_table is basically a bucket list containing the start\n * value for the record_row.\n *\n * The record_manager is used to create linked chains. A header\n * containing the hash of the item, and the next value is stored\n * with each record.\n *\n *   [ KeyType ]\n *   [ next:4  ]\n *   [ record  ]\n *\n * By using the record_manager instead of slabs, we can have smaller\n * indexes avoiding reading/writing extra bytes to the file.\n * Using fixed size records is therefore faster.\n */\ntemplate <typename KeyType>\nclass record_hash_table\n{\npublic:\n  typedef std::function<void(memory_ptr)> write_function;\n\n  record_hash_table(record_hash_table_header &header, record_manager &manager);\n\n  /// Store a value. The provided write() function must write the correct\n  /// number of bytes (record_size - key_size - sizeof(array_index)).\n  void store(const KeyType &key, write_function write);\n\n  /// Find the record for a given hash.\n  /// Returns a null pointer if not found.\n  const memory_ptr find(const KeyType &key) const;\n  std::shared_ptr<std::vector<memory_ptr>> find(array_index index) const;\n  /// Delete a key-value pair from the hashtable by unlinking the node.\n  bool unlink(const KeyType &key);\n\nprivate:\n  // What is the bucket given a hash.\n  array_index bucket_index(const KeyType &key) const;\n\n  // What is the record start index for a chain.\n  array_index read_bucket_value(const KeyType &key) const;\n\n  // Link a new chain into the bucket header.\n  void link(const KeyType &key, const array_index begin);\n\n  // Release node from linked chain.\n  template <typename ListItem>\n  void release(const ListItem &item, const file_offset previous);\n\n  record_hash_table_header &header_;\n  record_manager &manager_;\n  shared_mutex mutex_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#include <UChain/database/impl/record_hash_table.ipp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/primitives/record_list.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_RECORD_LIST_HPP\n#define UC_DATABASE_RECORD_LIST_HPP\n\n#include <cstdint>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory.hpp>\n#include <UChain/database/primitives/record_manager.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n// used by test and tools only.\nBC_CONSTEXPR size_t record_list_offset = sizeof(array_index);\n\n/// This is a one-way linked list with a next value containing the index of the\n/// subsequent record. Records can be dropped by forgetting an index, and\n/// updating to the next value. We can think of this as a LIFO queue.\nclass BCD_API record_list\n{\npublic:\n  static const array_index empty;\n\n  record_list(record_manager &manager);\n\n  /// Create new list with a single record.\n  array_index create();\n\n  /// Insert new record before index. Returns index of new record.\n  array_index insert(array_index index);\n\n  /// Read next index for record in list.\n  array_index next(array_index index) const;\n\n  /// Get underlying record data.\n  const memory_ptr get(array_index index) const;\n\nprivate:\n  record_manager &manager_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/primitives/record_manager.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_RECORD_MANAGER_HPP\n#define UC_DATABASE_RECORD_MANAGER_HPP\n\n#include <atomic>\n#include <cstddef>\n#include <cstdint>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory.hpp>\n#include <UChain/database/memory/memory_map.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nBC_CONSTEXPR size_t minimum_records_size = sizeof(array_index);\nBC_CONSTFUNC size_t record_hash_table_header_size(size_t buckets)\n{\n    return sizeof(array_index) + minimum_records_size * buckets;\n}\n\n/// The record manager represents a collection of fixed size chunks of\n/// data referenced by an index. The file will be resized accordingly\n/// and the total number of records updated so new chunks can be allocated.\n/// It also provides logical record mapping to the record memory address.\nclass BCD_API record_manager\n{\n  public:\n    record_manager(memory_map &file, file_offset header_size,\n                   size_t record_size);\n\n    /// Create record manager.\n    bool create();\n\n    /// Prepare manager for usage.\n    bool start();\n\n    /// Synchronise to disk.\n    void sync();\n\n    /// The number of records in this container.\n    array_index count() const;\n\n    /// Change the number of records of this container (truncation).\n    void set_count(const array_index value);\n\n    /// Allocate records and return first logical index, sync() after writing.\n    array_index new_records(size_t count);\n\n    /// Return memory object for the record at the specified index.\n    const memory_ptr get(array_index record) const;\n\n  private:\n    // The record index of a disk position.\n    array_index position_to_record(file_offset position) const;\n\n    // The disk position of a record index.\n    file_offset record_to_position(array_index record) const;\n\n    // Read the count of the records from the file.\n    void read_count();\n\n    // Write the count of the records from the file.\n    void write_count();\n\n    // This class is thread and remap safe.\n    memory_map &file_;\n    const file_offset header_size_;\n\n    // Payload size is protected by mutex.\n    array_index record_count_;\n    mutable shared_mutex mutex_;\n\n    // Records are fixed size.\n    const size_t record_size_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/primitives/record_multimap.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_RECORD_MULTIMAP_HPP\n#define UC_DATABASE_RECORD_MULTIMAP_HPP\n\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory.hpp>\n#include <UChain/database/primitives/record_list.hpp>\n#include <UChain/database/primitives/record_hash_table.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\ntemplate <typename KeyType>\nBC_CONSTEXPR size_t hash_table_multimap_record_size()\n{\n    return hash_table_record_size<KeyType>(sizeof(array_index));\n}\n\n/**\n * A multimap hashtable where each key maps to a set of fixed size\n * values.\n *\n * The database is abstracted on top of a record map, and linked records.\n * The map links keys to start indexes in the linked records.\n * The linked records are chains of records that can be iterated through\n * given a start index.\n */\ntemplate <typename KeyType>\nclass record_multimap\n{\n  public:\n    typedef record_hash_table<KeyType> record_hash_table_type;\n    typedef std::function<void(memory_ptr)> write_function;\n\n    record_multimap(record_hash_table_type &map, record_list &records);\n\n    /// Lookup a key, returning an iterable result with multiple values.\n    array_index lookup(const KeyType &key) const;\n    std::shared_ptr<std::vector<array_index>> lookup(array_index index) const;\n    /// Add a new row for a key. If the key doesn't exist, it will be created.\n    /// If it does exist, the value will be added at the start of the chain.\n    void add_row(const KeyType &key, write_function write);\n\n    /// Delete the last row entry that was added. This means when deleting\n    /// blocks we must walk backwards and delete in reverse order.\n    void delete_last_row(const KeyType &key);\n\n  private:\n    // Add new value to existing key.\n    void add_to_list(memory_ptr start_info, write_function write);\n\n    // Create new key with a single value.\n    void create_new(const KeyType &key, write_function write);\n\n    record_hash_table_type &map_;\n    record_list &records_;\n    mutable shared_mutex mutex_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#include <UChain/database/impl/record_multimap.ipp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/primitives/record_multimap_iterable.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_RECORD_MULTIMAP_ITERABLE_HPP\n#define UC_DATABASE_RECORD_MULTIMAP_ITERABLE_HPP\n\n#include <UChain/database/define.hpp>\n#include <UChain/database/primitives/record_list.hpp>\n#include <UChain/database/primitives/record_multimap_iterator.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n/// Result of a multimap database query. This is a container wrapper allowing\n/// the values to be iterated.\nclass BCD_API record_multimap_iterable\n{\n  public:\n    record_multimap_iterable(const record_list &records, array_index begin);\n\n    record_multimap_iterator begin() const;\n    record_multimap_iterator end() const;\n\n  private:\n    array_index begin_;\n    const record_list &records_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/primitives/record_multimap_iterator.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_RECORD_MULTIMAP_ITERATOR_HPP\n#define UC_DATABASE_RECORD_MULTIMAP_ITERATOR_HPP\n\n#include <UChain/database/define.hpp>\n#include <UChain/database/primitives/record_list.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n/// Forward iterator for multimap record values.\n/// After performing key lookup iterate the multiple values in a for loop.\nclass BCD_API record_multimap_iterator\n{\n  public:\n    record_multimap_iterator(const record_list &records, array_index index);\n\n    /// Next value in the chain.\n    void operator++();\n\n    /// The record index.\n    array_index operator*() const;\n\n    /// Comparison operators.\n    bool operator==(record_multimap_iterator other) const;\n    bool operator!=(record_multimap_iterator other) const;\n\n  private:\n    array_index index_;\n    const record_list &records_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/primitives/slab_hash_table.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_SLAB_HASH_TABLE_HPP\n#define UC_DATABASE_SLAB_HASH_TABLE_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <UChain/database/memory/memory.hpp>\n#include <UChain/database/primitives/hash_table_header.hpp>\n#include <UChain/database/primitives/slab_manager.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\ntypedef hash_table_header<array_index, file_offset> slab_hash_table_header;\n\n/**\n * A hashtable mapping hashes to variable sized values (slabs).\n * Uses a combination of the hash_table and slab_manager.\n *\n * The hash_table is basically a bucket list containing the start\n * value for the slab_row.\n *\n * The slab_manager is used to create linked chains. A header\n * containing the hash of the item, and the next value is stored\n * with each slab.\n *\n *   [ KeyType  ]\n *   [ next:8   ]\n *   [ value... ]\n *\n * If we run manager.sync() before the link() step then we ensure\n * data can be lost but the hashtable is never corrupted.\n * Instead we prefer speed and batch that operation. The user should\n * call allocator.sync() after a series of store() calls.\n */\ntemplate <typename KeyType>\nclass slab_hash_table\n{\n  public:\n    typedef std::function<void(memory_ptr)> write_function;\n\n    slab_hash_table(slab_hash_table_header &header, slab_manager &manager);\n\n    /// Store a value. value_size is the requested size for the value.\n    /// The provided write() function must write exactly value_size bytes.\n    /// Returns the position of the inserted value in the slab_manager.\n    file_offset store(const KeyType &key, write_function write,\n                      const size_t value_size);\n    file_offset restore(const KeyType &key,\n                        write_function write, const size_t value_size);\n    /// Find the slab for a given hash. Returns a null pointer if not found.\n    const memory_ptr find(const KeyType &key) const;\n    std::shared_ptr<std::vector<memory_ptr>> find(uint64_t index) const;\n    const memory_ptr rfind(const KeyType &key) const;\n    std::vector<memory_ptr> finds(const KeyType &key) const;\n\n    /// Delete a key-value pair from the hashtable by unlinking the node.\n    bool unlink(const KeyType &key);\n\n  private:\n    // What is the bucket given a hash.\n    array_index bucket_index(const KeyType &key) const;\n\n    // What is the slab start position for a chain.\n    file_offset read_bucket_value(const KeyType &key) const;\n\n    // Link a new chain into the bucket header.\n    void link(const KeyType &key, const file_offset begin);\n\n    // Release node from linked chain.\n    template <typename ListItem>\n    void release(const ListItem &item, const file_offset previous);\n\n    slab_hash_table_header &header_;\n    slab_manager &manager_;\n    shared_mutex mutex_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#include <UChain/database/impl/slab_hash_table.ipp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/primitives/slab_manager.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_SLAB_MANAGER_HPP\n#define UC_DATABASE_SLAB_MANAGER_HPP\n\n#include <cstddef>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory.hpp>\n#include <UChain/database/memory/memory_map.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nBC_CONSTEXPR size_t minimum_slabs_size = sizeof(file_offset);\nBC_CONSTFUNC size_t slab_hash_table_header_size(size_t buckets)\n{\n    return sizeof(file_offset) + minimum_slabs_size * buckets;\n}\n\n/// The slab manager represents a growing collection of various sized\n/// slabs of data on disk. It will resize the file accordingly and keep\n/// track of the current end pointer so new slabs can be allocated.\nclass BCD_API slab_manager\n{\n  public:\n    slab_manager(memory_map &file, file_offset header_size);\n\n    /// Create slab manager.\n    bool create();\n\n    /// Prepare manager for use.\n    bool start();\n\n    /// Synchronise the payload size to disk.\n    void sync() const;\n\n    /// Allocate a slab and return its position, sync() after writing.\n    file_offset new_slab(size_t size);\n\n    /// Return memory object for the slab at the specified position.\n    const memory_ptr get(file_offset position) const;\n\n    //protected:\n\n    /// Get the size of all slabs and size prefix (excludes header).\n    file_offset payload_size() const;\n\n  private:\n    // Read the size of the data from the file.\n    void read_size();\n\n    // Write the size of the data from the file.\n    void write_size() const;\n\n    // This class is thread and remap safe.\n    memory_map &file_;\n    const file_offset header_size_;\n\n    // Payload size is protected by mutex.\n    file_offset payload_size_;\n    mutable shared_mutex mutex_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/result/base_result.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_BASE_RESULT_HPP\n#define UC_DATABASE_BASE_RESULT_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n/// Deferred read base result.\nclass BCD_API base_result\n{\n  public:\n    base_result(const memory_ptr slab) : slab_(slab)\n    {\n    }\n\n    /// True if this base result is valid (found).\n    operator bool() const\n    {\n        return slab_ != nullptr;\n    }\n    memory_ptr get_slab() const\n    {\n        return slab_;\n    }\n\n  private:\n    const memory_ptr slab_;\n};\n#if 0\nbase_result::base_result(const memory_ptr slab)\n  : slab_(slab)\n{\n}\n\nbase_result::operator bool() const\n{\n    return slab_ != nullptr;\n}\n\nmemory_ptr base_result::get_slab() const\n{\n    return slab_;\n}\n#endif\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/result/block_result.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_BLOCK_RESULT_HPP\n#define UC_DATABASE_BLOCK_RESULT_HPP\n\n#include <cstdint>\n#include <cstddef>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n/// Deferred read block result.\nclass BCD_API block_result\n{\n  public:\n    block_result(const memory_ptr slab);\n\n    /// True if this block result is valid (found).\n    operator bool() const;\n\n    /// The block header.\n    chain::header header() const;\n\n    /// The height of this block in the chain.\n    size_t height() const;\n\n    /// The number of transactions in this block.\n    size_t transaction_count() const;\n\n    /// A transaction hash where index < transaction_count.\n    hash_digest transaction_hash(size_t index) const;\n\n  private:\n    const memory_ptr slab_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/result/token_result.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_TOKEN_RESULT_HPP\n#define UC_DATABASE_TOKEN_RESULT_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory.hpp>\n#include <UChain/database/result/base_result.hpp>\n#include <UChainService/txs/token/token_detail.hpp>\n\nusing namespace libbitcoin::chain;\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n/// read token detail information from token database.\nclass BCD_API token_result : public base_result\n{\n  public:\n    token_result(const memory_ptr slab);\n\n    /// The token.\n    std::shared_ptr<token_detail> get_token_detail() const;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/result/tx_result.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_tx_result_HPP\n#define UC_DATABASE_tx_result_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n/// Deferred read transaction result.\nclass BCD_API tx_result\n{\n  public:\n    tx_result(const memory_ptr slab);\n\n    /// True if this transaction result is valid (found).\n    operator bool() const;\n\n    /// The height of the block which includes the transaction.\n    size_t height() const;\n\n    /// The position of the transaction within its block.\n    size_t index() const;\n\n    /// The transaction.\n    chain::transaction transaction() const;\n\n  private:\n    const memory_ptr slab_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/result/wallet_address_result.hpp",
    "content": "\n/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_WALLET_ADDRESS_RESULT_HPP\n#define UC_DATABASE_WALLET_ADDRESS_RESULT_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory.hpp>\n#include <UChain/database/result/base_result.hpp>\n#include <UChainService/txs/wallet/wallet_address.hpp>\n\nusing namespace libbitcoin::chain;\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n/// read wallet_address detail information from wallet_address database.\nclass BCD_API wallet_address_result : public base_result\n{\n  public:\n    wallet_address_result(const memory_ptr slab);\n\n    /// The wallet_address.\n    std::shared_ptr<wallet_address> get_wallet_address_detail() const;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/result/wallet_result.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_WALLET_RESULT_HPP\n#define UC_DATABASE_WALLET_RESULT_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory.hpp>\n#include <UChain/database/result/base_result.hpp>\n#include <UChainService/txs/wallet/wallet.hpp>\n\nusing namespace libbitcoin::chain;\nusing namespace std;\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n/// read wallet detail information from wallet database.\nclass BCD_API wallet_result : public base_result\n{\n  public:\n    wallet_result(const memory_ptr slab);\n\n    /// The wallet.\n    //wallet get_wallet_detail() const;\n    std::shared_ptr<libbitcoin::chain::wallet> get_wallet_detail() const;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/result/wallet_token_result.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_WALLET_TOKEN_RESULT_HPP\n#define UC_DATABASE_WALLET_TOKEN_RESULT_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory.hpp>\n#include <UChain/database/result/base_result.hpp>\n#include <UChainService/txs/token/token_transfer.hpp>\n\nusing namespace libbitcoin::chain;\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n/// read token detail information from token database.\nclass BCD_API wallet_token_result : public base_result\n{\n  public:\n    wallet_token_result(const memory_ptr slab);\n\n    /// The token wallet relationship.\n    token_transfer get_wallet_token_transfer() const;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/settings.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-database.\n *\n * UChain-database is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_SETTINGS_HPP\n#define UC_DATABASE_SETTINGS_HPP\n\n#include <cstdint>\n#include <boost/filesystem.hpp>\n#include <UChain/database/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n/// Common database configuration settings, properties not thread safe.\nclass BCD_API settings\n{\n  public:\n    settings();\n    settings(bc::settings context);\n\n    /// Properties.\n    uint32_t history_start_height;\n    uint32_t stealth_start_height;\n    boost::filesystem::path directory;\n    boost::filesystem::path default_directory;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/database/version.hpp",
    "content": "///////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 2014-2018 libbitcoin-database developers (see COPYING).\n//\n//        GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY\n//\n///////////////////////////////////////////////////////////////////////////////\n#ifndef UC_DATABASE_VERSION_HPP\n#define UC_DATABASE_VERSION_HPP\n\n/**\n * The semantic version of this repository as: [major].[minor].[patch]\n * For interpretation of the versioning scheme see: http://semver.org\n */\n\n#define UC_DATABASE_VERSION \"0.0.6\"\n\n#define UC_DATABASE_MAJOR_VERSION 0\n#define UC_DATABASE_MINOR_VERSION 0\n#define UC_DATABASE_PATCH_VERSION 6\n\n#define UC_DATABASE_VERSION_NUMBER (((UC_DATABASE_MAJOR_VERSION)*100) + ((UC_DATABASE_MINOR_VERSION)*10) + (UC_DATABASE_PATCH_VERSION))\n\n#endif\n"
  },
  {
    "path": "include/UChain/database.hpp",
    "content": "///////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 2014-2018 libbitcoin-database developers (see COPYING).\n//\n//        GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY\n//\n///////////////////////////////////////////////////////////////////////////////\n#ifndef UC_DATABASE_HPP\n#define UC_DATABASE_HPP\n\n/**\n * API Users: Include only this header. Direct use of other headers is fragile\n * and unsupported as header organization is subject to change.\n *\n * Maintainers: Do not include this header internal to this library.\n */\n\n#include <UChain/coin.hpp>\n#include <UChain/database/data_base.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/settings.hpp>\n#include <UChain/database/version.hpp>\n#include <UChain/database/databases/block_db.hpp>\n#include <UChain/database/databases/history_db.hpp>\n#include <UChain/database/databases/spend_db.hpp>\n#include <UChain/database/databases/stealth_db.hpp>\n#include <UChain/database/databases/tx_db.hpp>\n#include <UChain/database/memory/accessor.hpp>\n#include <UChain/database/memory/allocator.hpp>\n#include <UChain/database/memory/memory.hpp>\n#include <UChain/database/memory/memory_map.hpp>\n#include <UChain/database/primitives/hash_table_header.hpp>\n#include <UChain/database/primitives/record_hash_table.hpp>\n#include <UChain/database/primitives/record_list.hpp>\n#include <UChain/database/primitives/record_manager.hpp>\n#include <UChain/database/primitives/record_multimap.hpp>\n#include <UChain/database/primitives/record_multimap_iterable.hpp>\n#include <UChain/database/primitives/record_multimap_iterator.hpp>\n#include <UChain/database/primitives/slab_hash_table.hpp>\n#include <UChain/database/primitives/slab_manager.hpp>\n#include <UChain/database/result/block_result.hpp>\n#include <UChain/database/result/tx_result.hpp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/callback_state.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_CALLBACK_STATE_HPP\n#define BX_CALLBACK_STATE_HPP\n\n#include <iostream>\n#include <cstdint>\n#include <string>\n#include <boost/format.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/config/encoding.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\n\n/**\n * Shared state wrapper to manage non-global shared call state.\n */\nclass callback_state\n{\n  public:\n    /**\n     * Construct an instance of the callback_state class. The class is\n     * initialized with a reference count of zero (0). If the streams\n     * references passed here are used elsewhere or in another instance\n     * on another thread then stream interleaving cannot be prevented.\n     * @param[in]  error   The error stream for the callback handler.\n     * @param[in]  output  The output stream for the callback handler.\n     * @param[in]  engine  The desired output format.\n     */\n    BCX_API callback_state(std::ostream &error, std::ostream &output,\n                           const encoding_engine engine);\n\n    /**\n     * Construct an instance of the callback_state class with native encoding.\n     * @param[in]  error   The error stream for the callback handler.\n     * @param[in]  output  The output stream for the callback handler.\n     */\n    BCX_API callback_state(std::ostream &error, std::ostream &output);\n\n    /**\n     * Serialize a property tree to output. The stream must be flushed before\n     * returning in order to prevent interleaving on the shared stream.\n     * @param[in]  tree  The property tree to write to output.\n     */\n    BCX_API virtual void error(const Json::Value &tree);\n\n    /**\n     * Write a line to the error stream. The stream must be flushed before\n     * returning in order to prevent interleaving on the shared stream.\n     * @param[in]  message  The unterminated error message to write.\n     */\n    BCX_API virtual void error(const format &message);\n\n    /**\n     * Write a line to the error stream. The stream must be flushed before\n     * returning in order to prevent interleaving on the shared stream.\n     * @param[in]  message  The unterminated error message to write.\n     */\n    BCX_API virtual void error(const std::string &message);\n\n    /**\n     * Serialize a property tree to output. The stream must be flushed before\n     * returning in order to prevent interleaving on the shared stream.\n     * @param[in]  tree  The property tree to write to output.\n     */\n    BCX_API virtual void output(const Json::Value &tree);\n\n    /**\n     * Write a line to the output stream. The stream must be flushed before\n     * returning in order to prevent interleaving on the shared stream.\n     * @param[in]  message  The unterminated output message to write.\n     */\n    BCX_API virtual void output(const format &message);\n\n    /**\n     * Write a line to the output stream. The stream must be flushed before\n     * returning in order to prevent interleaving on the shared stream.\n     * @param[in]  message  The unterminated output message to write.\n     */\n    BCX_API virtual void output(const std::string &message);\n\n    /**\n     * Write a number to the output stream. The stream must be flushed before\n     * returning in order to prevent interleaving on the shared stream.\n     * @param[in]  value  The numeric value to write.\n     */\n    BCX_API virtual void output(uint64_t value);\n\n    /**\n     * Set the callback refcount to one and reset result to okay.\n     */\n    BCX_API virtual void start();\n\n    /**\n     * Set the callback refcount to zero and assign the result.\n     * This overrides any outstanding callback references.\n     * @param[in]  result  The desired callback result code, defaults to okay.\n     */\n    BCX_API virtual void stop(console_result result = console_result::okay);\n\n    /**\n     * Get a value indicating whether the callback reference count is zero.\n     * @return  True if the reference count is zero.\n     */\n    BCX_API virtual bool &stopped();\n\n    /**\n     * Handle the callback error with standard behavior.\n     * @param[in]  ec      The callback error result.\n     * @param[in]  format  A single parameter format string or empty/default.\n     * @return             True if no error.\n     */\n    BCX_API virtual bool succeeded(const std::error_code &ec,\n                                   const std::string &format = \"%1%\");\n\n    /**\n     * Get the engine enumeration value.\n     */\n    BCX_API virtual encoding_engine get_engine();\n\n    /**\n     * Get the callback result code.\n     */\n    BCX_API virtual console_result get_result();\n\n    /**\n     * Set the callback result code.\n     */\n    BCX_API virtual void set_result(console_result result);\n\n    /**\n     * Increment the callback synchronization reference count.\n     * @return  The callback synchronization counter value.\n     */\n    BCX_API virtual size_t increment();\n\n    /**\n     * Decrement the callback synchronization reference count.\n     * @return  The callback synchronization counter value.\n     */\n    BCX_API virtual size_t decrement();\n\n    /**\n     * Overload numeric cast to return the reference count.\n     */\n    BCX_API virtual operator size_t() const;\n\n    /**\n     * Overload ++ operator to increment the reference count.\n     */\n    BCX_API virtual callback_state &operator++();\n\n    /**\n     * Overload ++ operator to decrement the reference count.\n     */\n    BCX_API virtual callback_state &operator--();\n\n  private:\n    bool stopped_;\n    size_t refcount_;\n    console_result result_;\n    encoding_engine engine_;\n    std::ostream &error_;\n    std::ostream &output_;\n};\n\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/command.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_COMMAND_HPP\n#define BX_COMMAND_HPP\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <boost/filesystem.hpp>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/config/address.hpp>\n#include <UChain/explorer/config/algorithm.hpp>\n#include <UChain/explorer/config/btc.hpp>\n#include <UChain/explorer/config/byte.hpp>\n#include <UChain/explorer/config/cert_key.hpp>\n#include <UChain/explorer/config/ec_private.hpp>\n#include <UChain/explorer/config/encoding.hpp>\n#include <UChain/explorer/config/endorsement.hpp>\n#include <UChain/explorer/config/hashtype.hpp>\n#include <UChain/explorer/config/hd_key.hpp>\n#include <UChain/explorer/config/header.hpp>\n#include <UChain/explorer/config/input.hpp>\n#include <UChain/explorer/config/language.hpp>\n#include <UChain/explorer/config/output.hpp>\n#include <UChain/explorer/config/raw.hpp>\n#include <UChain/explorer/config/script.hpp>\n#include <UChain/explorer/config/signature.hpp>\n#include <UChain/explorer/config/transaction.hpp>\n#include <UChain/explorer/config/wrapper.hpp>\n#include <UChain/explorer/utility.hpp>\n\n/********* GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY **********/\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\n\n#define BX_HELP_VARIABLE \"help\"\n#define BX_CONFIG_VARIABLE \"config\"\n#define LOG_COMMAND \"commands\"\nBC_DECLARE_CONFIG_DEFAULT_PATH(\".UChain\" / \"uc.conf\")\n\n/**\n * Suppported command category.\n */\nenum : int\n{\n    ctgy_extension = 1 << 0,\n    ctgy_online = 1 << 1,\n    ctgy_admin_required = 1 << 2,\n    ctgy_wallet_required = 1 << 3,\n\n    ex_online = ctgy_extension | ctgy_online,\n    ex_admin = ctgy_extension | ctgy_admin_required,\n    ex_wallet = ctgy_extension | ctgy_wallet_required,\n    ex_on_admin = ctgy_extension | ctgy_online | ctgy_admin_required,\n    ex_on_wallet = ctgy_extension | ctgy_online | ctgy_wallet_required\n};\n\n/**\n * Base class for definition of each Bitcoin Explorer command.\n */\nclass BCX_API command\n{\n  public:\n    /**\n     * The symbolic (not localizable) command name, lower case.\n     */\n    static const char *symbol()\n    {\n        return \"not-implemented\";\n    }\n\n    /**\n     * The symbolic (not localizable) command name, lower case.\n     * @return  Example: \"fetch-transaction\"\n     */\n    virtual const char *name()\n    {\n        return symbol();\n    }\n\n    /**\n     * The localizable command category name, upper case.\n     * @return  Example: \"ONLINE\"\n     */\n    virtual const char *category()\n    {\n        return \"not-implemented\";\n    }\n\n    /**\n     * The localizable command category type.\n     * @param   Example: cgty_extension | cgty_online\n     * @return  Example: true | false\n     */\n\n    virtual bool category(int bs)\n    {\n        return false;\n    }\n\n    /**\n     * The localizable command description.\n     * @return  Example: \"Get transactions by hash.\"\n     */\n    virtual const char *description()\n    {\n        return \"not-implemented\";\n    }\n\n    /**\n     * Declare whether the command has been obsoleted.\n     * @return  True if the command is obsolete\n     */\n    virtual bool obsolete()\n    {\n        return false;\n    }\n\n    virtual bool is_block_height_fullfilled(uint64_t height)\n    {\n        return true;\n    }\n\n    virtual uint64_t minimum_block_height()\n    {\n        return 0;\n    }\n\n    /**\n     * Determines if STDIN is required to be raw.\n     * @return  True if the type of the STDIN argument is primitive::raw.\n     */\n    virtual bool requires_raw_input()\n    {\n        return false;\n    }\n\n    /**\n     * Determines if STDOUT is required to be raw.\n     * @return  True if the type of the STDOUT argument is primitive::raw.\n     */\n    virtual bool requires_raw_output()\n    {\n        return false;\n    }\n\n    /**\n     * Invoke the command.\n     * @param[out]  output  The input stream for the command execution.\n     * @param[out]  error   The input stream for the command execution.\n     * @return              The appropriate console return code { -1, 0, 1 }.\n     */\n    virtual console_result invoke(std::ostream &output,\n                                  std::ostream &error)\n    {\n        return console_result::failure;\n    }\n\n    /**\n     * Load command argument definitions.\n     * A value of -1 indicates that the number of instances is unlimited.\n     * @return  The loaded argument definitions.\n     */\n    virtual arguments_metadata &load_arguments()\n    {\n        return argument_metadata_;\n    }\n\n    /**\n     * Load environment variable definitions.\n     * @param[out] definitions  The defined program argument definitions.\n     */\n    virtual void load_environment(options_metadata &definitions)\n    {\n        using namespace po;\n        definitions.add_options()(\n            /* This composes with the command line options. */\n            BX_CONFIG_VARIABLE,\n            value<boost::filesystem::path>()\n                ->composing()\n                ->default_value(config_default_path()),\n            \"The path to the configuration settings file.\");\n    }\n\n    /**\n     * Load parameter fallbacks from file or input as appropriate.\n     * @param[in]  input      The input stream for loading the parameters.\n     * @param[in]  variables  The loaded variables.\n     */\n    BCX_API virtual void load_fallbacks(std::istream &input,\n                                        po::variables_map &variables)\n    {\n    }\n\n    /**\n     * Load command option definitions.\n     * BUGBUG: see boost bug/fix: svn.boost.org/trac/boost/ticket/8009\n     * @return  The loaded option definitions.\n     */\n    virtual options_metadata &load_options()\n    {\n        return option_metadata_;\n    }\n\n    /**\n     * Load configuration setting definitions.\n     * @param[out] definitions  The defined program argument definitions.\n     */\n    virtual void load_settings(options_metadata &definitions)\n    {\n        using namespace po;\n        definitions.add_options()(\n            \"wallet.wif_version\",\n            value<explorer::config::byte>(&setting_.wallet.wif_version)->default_value(128),\n            \"The wallet import format (WIF) key version, defaults to 128.\")(\n            \"wallet.hd_public_version\",\n            value<uint32_t>(&setting_.wallet.hd_public_version)->default_value(76067358),\n            \"The hierarchical deterministic (HD) public key version, defaults to 76067358.\")(\n            \"wallet.hd_secret_version\",\n            value<uint32_t>(&setting_.wallet.hd_secret_version)->default_value(76066276),\n            \"The hierarchical deterministic (HD) private key version, defaults to 76066276.\")(\n            \"wallet.pay_to_public_key_hash_version\",\n            value<explorer::config::byte>(&setting_.wallet.pay_to_public_key_hash_version)->default_value(0),\n            \"The pay-to-public-key-hash address version, defaults to 0.\")(\n            \"wallet.pay_to_script_hash_version\",\n            value<explorer::config::byte>(&setting_.wallet.pay_to_script_hash_version)->default_value(5),\n            \"The pay-to-script-hash address version, defaults to 5.\")(\n            \"wallet.transaction_version\",\n            value<uint32_t>(&setting_.wallet.transaction_version)->default_value(1),\n            \"The transaction version, defaults to 1.\")(\n            \"network.identifier\",\n            value<uint32_t>(&setting_.network.identifier)->default_value(3652501241),\n            \"The magic number for message headers, defaults to 3652501241.\")(\n            \"network.connect_retries\",\n            value<explorer::config::byte>(&setting_.network.connect_retries)->default_value(0),\n            \"The number of times to retry contacting a node, defaults to 0.\")(\n            \"network.connect_timeout_seconds\",\n            value<uint32_t>(&setting_.network.connect_timeout_seconds)->default_value(5),\n            \"The time limit for connection establishment, defaults to 5.\")(\n            \"network.channel_handshake_seconds\",\n            value<uint32_t>(&setting_.network.channel_handshake_seconds)->default_value(30),\n            \"The time limit to complete the connection handshake, defaults to 30.\")(\n            \"network.hosts_file\",\n            value<boost::filesystem::path>(&setting_.network.hosts_file)->default_value(\"hosts.cache\"),\n            \"The peer hosts cache file path, defaults to 'hosts.cache'.\")(\n            \"network.debug_file\",\n            value<boost::filesystem::path>(&setting_.network.debug_file)->default_value(\"debug.log\"),\n            \"The debug log file path, defaults to 'debug.log'.\")(\n            \"network.error_file\",\n            value<boost::filesystem::path>(&setting_.network.error_file)->default_value(\"error.log\"),\n            \"The error log file path, defaults to 'error.log'.\")(\n            \"network.seed\",\n            value<std::vector<bc::config::endpoint>>(&setting_.network.seeds),\n            \"A seed node for initializing the host pool, multiple entries allowed.\")(\n            \"server.url\",\n            value<bc::config::endpoint>(&setting_.server.url)->default_value({\"tcp://127.0.0.1:18707\"}),\n            \"The URL of the Libbitcoin/Obelisk server.\")(\n            \"server.connect_retries\",\n            value<explorer::config::byte>(&setting_.server.connect_retries)->default_value(0),\n            \"The number of times to retry contacting a server, defaults to 0.\")(\n            \"server.connect_timeout_seconds\",\n            value<uint16_t>(&setting_.server.connect_timeout_seconds)->default_value(5),\n            \"The time limit for connection establishment, defaults to 5.\")(\n            \"server.server_public_key\",\n            value<bc::config::sodium>(&setting_.server.server_public_key),\n            \"The Z85-encoded public key of the server.\")(\n            \"server.client_private_key\",\n            value<bc::config::sodium>(&setting_.server.client_private_key),\n            \"The Z85-encoded private key of the client.\");\n    }\n\n    /**\n     * Load streamed value as parameter fallback.\n     * @param[in]  input      The input stream for loading the parameter.\n     * @param[in]  variables  The loaded variables.\n     */\n    virtual void load_stream(std::istream &input, po::variables_map &variables)\n    {\n    }\n\n    /**\n     * Set variable defaults from configuration variable values.\n     * @param[in]  variables  The loaded variables.\n     */\n    virtual void set_defaults_from_config(po::variables_map &variables)\n    {\n    }\n\n    /**\n     * Write the help for this command to the specified stream.\n     * @param[out] output  The output stream.\n     */\n    virtual void write_help(std::ostream &output)\n    {\n        const auto &options = get_option_metadata();\n        const auto &arguments = get_argument_metadata();\n        bc::config::printer help(options, arguments, BX_PROGRAM_NAME,\n                                 description(), name());\n        help.initialize();\n        help.commandline(output);\n    }\n\n    /* Properties */\n\n    /**\n     * Get command line argument metadata.\n     */\n    virtual arguments_metadata &get_argument_metadata()\n    {\n        return argument_metadata_;\n    }\n\n    /**\n     * Get command line option metadata.\n     */\n    virtual options_metadata &get_option_metadata()\n    {\n        return option_metadata_;\n    }\n\n    /**\n     * Get the value of the wallet.wif_version setting.\n     */\n    virtual explorer::config::byte get_wallet_wif_version_setting() const\n    {\n        return setting_.wallet.wif_version;\n    }\n\n    /**\n     * Set the value of the wallet.wif_version setting.\n     */\n    virtual void set_wallet_wif_version_setting(explorer::config::byte value)\n    {\n        setting_.wallet.wif_version = value;\n    }\n\n    /**\n     * Get the value of the wallet.hd_public_version setting.\n     */\n    virtual uint32_t get_wallet_hd_public_version_setting() const\n    {\n        return setting_.wallet.hd_public_version;\n    }\n\n    /**\n     * Set the value of the wallet.hd_public_version setting.\n     */\n    virtual void set_wallet_hd_public_version_setting(uint32_t value)\n    {\n        setting_.wallet.hd_public_version = value;\n    }\n\n    /**\n     * Get the value of the wallet.hd_secret_version setting.\n     */\n    virtual uint32_t get_wallet_hd_secret_version_setting() const\n    {\n        return setting_.wallet.hd_secret_version;\n    }\n\n    /**\n     * Set the value of the wallet.hd_secret_version setting.\n     */\n    virtual void set_wallet_hd_secret_version_setting(uint32_t value)\n    {\n        setting_.wallet.hd_secret_version = value;\n    }\n\n    /**\n     * Get the value of the wallet.pay_to_public_key_hash_version setting.\n     */\n    virtual explorer::config::byte get_wallet_pay_to_public_key_hash_version_setting() const\n    {\n        return setting_.wallet.pay_to_public_key_hash_version;\n    }\n\n    /**\n     * Set the value of the wallet.pay_to_public_key_hash_version setting.\n     */\n    virtual void set_wallet_pay_to_public_key_hash_version_setting(explorer::config::byte value)\n    {\n        setting_.wallet.pay_to_public_key_hash_version = value;\n    }\n\n    /**\n     * Get the value of the wallet.pay_to_script_hash_version setting.\n     */\n    virtual explorer::config::byte get_wallet_pay_to_script_hash_version_setting() const\n    {\n        return setting_.wallet.pay_to_script_hash_version;\n    }\n\n    /**\n     * Set the value of the wallet.pay_to_script_hash_version setting.\n     */\n    virtual void set_wallet_pay_to_script_hash_version_setting(explorer::config::byte value)\n    {\n        setting_.wallet.pay_to_script_hash_version = value;\n    }\n\n    /**\n     * Get the value of the wallet.transaction_version setting.\n     */\n    virtual uint32_t get_wallet_transaction_version_setting() const\n    {\n        return setting_.wallet.transaction_version;\n    }\n\n    /**\n     * Set the value of the wallet.transaction_version setting.\n     */\n    virtual void set_wallet_transaction_version_setting(uint32_t value)\n    {\n        setting_.wallet.transaction_version = value;\n    }\n\n    /**\n     * Get the value of the network.identifier setting.\n     */\n    virtual uint32_t get_network_identifier_setting() const\n    {\n        return setting_.network.identifier;\n    }\n\n    /**\n     * Set the value of the network.identifier setting.\n     */\n    virtual void set_network_identifier_setting(uint32_t value)\n    {\n        setting_.network.identifier = value;\n    }\n\n    /**\n     * Get the value of the network.connect_retries setting.\n     */\n    virtual explorer::config::byte get_network_connect_retries_setting() const\n    {\n        return setting_.network.connect_retries;\n    }\n\n    /**\n     * Set the value of the network.connect_retries setting.\n     */\n    virtual void set_network_connect_retries_setting(explorer::config::byte value)\n    {\n        setting_.network.connect_retries = value;\n    }\n\n    /**\n     * Get the value of the network.connect_timeout_seconds setting.\n     */\n    virtual uint32_t get_network_connect_timeout_seconds_setting() const\n    {\n        return setting_.network.connect_timeout_seconds;\n    }\n\n    /**\n     * Set the value of the network.connect_timeout_seconds setting.\n     */\n    virtual void set_network_connect_timeout_seconds_setting(uint32_t value)\n    {\n        setting_.network.connect_timeout_seconds = value;\n    }\n\n    /**\n     * Get the value of the network.channel_handshake_seconds setting.\n     */\n    virtual uint32_t get_network_channel_handshake_seconds_setting() const\n    {\n        return setting_.network.channel_handshake_seconds;\n    }\n\n    /**\n     * Set the value of the network.channel_handshake_seconds setting.\n     */\n    virtual void set_network_channel_handshake_seconds_setting(uint32_t value)\n    {\n        setting_.network.channel_handshake_seconds = value;\n    }\n\n    /**\n     * Get the value of the network.hosts_file setting.\n     */\n    virtual boost::filesystem::path get_network_hosts_file_setting() const\n    {\n        return setting_.network.hosts_file;\n    }\n\n    /**\n     * Set the value of the network.hosts_file setting.\n     */\n    virtual void set_network_hosts_file_setting(boost::filesystem::path value)\n    {\n        setting_.network.hosts_file = value;\n    }\n\n    /**\n     * Get the value of the network.debug_file setting.\n     */\n    virtual boost::filesystem::path get_network_debug_file_setting() const\n    {\n        return setting_.network.debug_file;\n    }\n\n    /**\n     * Set the value of the network.debug_file setting.\n     */\n    virtual void set_network_debug_file_setting(boost::filesystem::path value)\n    {\n        setting_.network.debug_file = value;\n    }\n\n    /**\n     * Get the value of the network.error_file setting.\n     */\n    virtual boost::filesystem::path get_network_error_file_setting() const\n    {\n        return setting_.network.error_file;\n    }\n\n    /**\n     * Set the value of the network.error_file setting.\n     */\n    virtual void set_network_error_file_setting(boost::filesystem::path value)\n    {\n        setting_.network.error_file = value;\n    }\n\n    /**\n     * Get the value of the network.seed settings.\n     */\n    virtual std::vector<bc::config::endpoint> get_network_seeds_setting() const\n    {\n        return setting_.network.seeds;\n    }\n\n    /**\n     * Set the value of the network.seed settings.\n     */\n    virtual void set_network_seeds_setting(std::vector<bc::config::endpoint> value)\n    {\n        setting_.network.seeds = value;\n    }\n\n    /**\n     * Get the value of the server.url setting.\n     */\n    virtual bc::config::endpoint get_server_url_setting() const\n    {\n        return setting_.server.url;\n    }\n\n    /**\n     * Set the value of the server.url setting.\n     */\n    virtual void set_server_url_setting(bc::config::endpoint value)\n    {\n        setting_.server.url = value;\n    }\n\n    /**\n     * Get the value of the server.connect_retries setting.\n     */\n    virtual explorer::config::byte get_server_connect_retries_setting() const\n    {\n        return setting_.server.connect_retries;\n    }\n\n    /**\n     * Set the value of the server.connect_retries setting.\n     */\n    virtual void set_server_connect_retries_setting(explorer::config::byte value)\n    {\n        setting_.server.connect_retries = value;\n    }\n\n    /**\n     * Get the value of the server.connect_timeout_seconds setting.\n     */\n    virtual uint16_t get_server_connect_timeout_seconds_setting() const\n    {\n        return setting_.server.connect_timeout_seconds;\n    }\n\n    /**\n     * Set the value of the server.connect_timeout_seconds setting.\n     */\n    virtual void set_server_connect_timeout_seconds_setting(uint16_t value)\n    {\n        setting_.server.connect_timeout_seconds = value;\n    }\n\n    /**\n     * Get the value of the server.server_public_key setting.\n     */\n    virtual bc::config::sodium get_server_server_public_key_setting() const\n    {\n        return setting_.server.server_public_key;\n    }\n\n    /**\n     * Set the value of the server.server_public_key setting.\n     */\n    virtual void set_server_server_public_key_setting(bc::config::sodium value)\n    {\n        setting_.server.server_public_key = value;\n    }\n\n    /**\n     * Get the value of the server.client_private_key setting.\n     */\n    virtual bc::config::sodium get_server_client_private_key_setting() const\n    {\n        return setting_.server.client_private_key;\n    }\n\n    /**\n     * Set the value of the server.client_private_key setting.\n     */\n    virtual void set_server_client_private_key_setting(bc::config::sodium value)\n    {\n        setting_.server.client_private_key = value;\n    }\n\n    virtual void set_api_version(uint8_t ver)\n    {\n        setting_.server.api_version = ver;\n    }\n\n    virtual uint8_t get_api_version()\n    {\n        return setting_.server.api_version;\n    }\n\n  protected:\n    /**\n     * This base class is abstract but not pure virtual, so prevent direct\n     * construction here.\n     */\n    command()\n    {\n    }\n\n  private:\n    /**\n     * Command line argument metadata.\n     */\n    arguments_metadata argument_metadata_;\n\n    /**\n     * Command line option metadata.\n     */\n    options_metadata option_metadata_;\n\n    /**\n     * Environment variable bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct environment\n    {\n        environment()\n        {\n        }\n\n    } environment_;\n\n    /**\n     * Configuration setting file bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct setting\n    {\n        struct wallet\n        {\n            wallet()\n                : wif_version(),\n                  hd_public_version(),\n                  hd_secret_version(),\n                  pay_to_public_key_hash_version(),\n                  pay_to_script_hash_version(),\n                  transaction_version()\n            {\n            }\n\n            explorer::config::byte wif_version;\n            uint32_t hd_public_version;\n            uint32_t hd_secret_version;\n            explorer::config::byte pay_to_public_key_hash_version;\n            explorer::config::byte pay_to_script_hash_version;\n            uint32_t transaction_version;\n        } wallet;\n\n        struct network\n        {\n            network()\n                : identifier(),\n                  connect_retries(),\n                  connect_timeout_seconds(),\n                  channel_handshake_seconds(),\n                  hosts_file(),\n                  debug_file(),\n                  error_file(),\n                  seeds()\n            {\n            }\n\n            uint32_t identifier;\n            explorer::config::byte connect_retries;\n            uint32_t connect_timeout_seconds;\n            uint32_t channel_handshake_seconds;\n            boost::filesystem::path hosts_file;\n            boost::filesystem::path debug_file;\n            boost::filesystem::path error_file;\n            std::vector<bc::config::endpoint> seeds;\n        } network;\n\n        struct server\n        {\n            server()\n                : url(),\n                  connect_retries(),\n                  connect_timeout_seconds(),\n                  server_public_key(),\n                  client_private_key(),\n                  api_version(0) // defaults to v1, else v2. init as 0.\n            {\n            }\n\n            bc::config::endpoint url;\n            explorer::config::byte connect_retries;\n            uint16_t connect_timeout_seconds;\n            bc::config::sodium server_public_key;\n            bc::config::sodium client_private_key;\n            uint8_t api_version;\n        } server;\n\n        setting()\n            : wallet(),\n              network(),\n              server()\n        {\n        }\n    } setting_;\n};\n\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/commands/fetch-history.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_FETCH_HISTORY_HPP\n#define BX_FETCH_HISTORY_HPP\n\n#include <cstdint>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/command.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/generated.hpp>\n#include <UChain/explorer/config/address.hpp>\n#include <UChain/explorer/config/algorithm.hpp>\n#include <UChain/explorer/config/btc.hpp>\n#include <UChain/explorer/config/byte.hpp>\n#include <UChain/explorer/config/cert_key.hpp>\n#include <UChain/explorer/config/ec_private.hpp>\n#include <UChain/explorer/config/encoding.hpp>\n#include <UChain/explorer/config/endorsement.hpp>\n#include <UChain/explorer/config/hashtype.hpp>\n#include <UChain/explorer/config/hd_key.hpp>\n#include <UChain/explorer/config/header.hpp>\n#include <UChain/explorer/config/input.hpp>\n#include <UChain/explorer/config/language.hpp>\n#include <UChain/explorer/config/output.hpp>\n#include <UChain/explorer/config/raw.hpp>\n#include <UChain/explorer/config/script.hpp>\n#include <UChain/explorer/config/signature.hpp>\n#include <UChain/explorer/config/transaction.hpp>\n#include <UChain/explorer/config/wrapper.hpp>\n#include <UChain/explorer/utility.hpp>\n\n/********* GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY **********/\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/**\n * Class to implement the fetch-history command.\n */\nclass BCX_API fetch_history\n    : public command\n{\n  public:\n    /**\n     * The symbolic (not localizable) command name, lower case.\n     */\n    static const char *symbol()\n    {\n        return \"fetch-history\";\n    }\n\n    /**\n     * The member symbolic (not localizable) command name, lower case.\n     */\n    virtual const char *name()\n    {\n        return fetch_history::symbol();\n    }\n\n    /**\n     * The localizable command category name, upper case.\n     */\n    virtual const char *category()\n    {\n        return \"ONLINE\";\n    }\n\n    /**\n     * The localizable command description.\n     */\n    virtual const char *description()\n    {\n        return \"Get list of output points, values, and spends for a payment address. Requires a Libbitcoin/Obelisk server connection.\";\n    }\n\n    /**\n     * Load program argument definitions.\n     * A value of -1 indicates that the number of instances is unlimited.\n     * @return  The loaded program argument definitions.\n     */\n    virtual arguments_metadata &load_arguments()\n    {\n        return get_argument_metadata()\n            .add(\"PAYMENT_ADDRESS\", 1);\n    }\n\n    /**\n     * Load parameter fallbacks from file or input as appropriate.\n     * @param[in]  input  The input stream for loading the parameters.\n     * @param[in]         The loaded variables.\n     */\n    virtual void load_fallbacks(std::istream &input,\n                                po::variables_map &variables)\n    {\n        const auto raw = requires_raw_input();\n        load_input(get_payment_address_argument(), \"PAYMENT_ADDRESS\", variables, input, raw);\n    }\n\n    /**\n     * Load program option definitions.\n     * BUGBUG: see boost bug/fix: svn.boost.org/trac/boost/ticket/8009\n     * @return  The loaded program option definitions.\n     */\n    virtual options_metadata &load_options()\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            BX_CONFIG_VARIABLE \",c\",\n            value<boost::filesystem::path>(),\n            \"The path to the configuration settings file.\")(\n            \"format,f\",\n            value<explorer::config::encoding>(&option_.format),\n            \"The output format. Options are 'info', 'json' and 'xml', defaults to 'info'.\")(\n            \"PAYMENT_ADDRESS\",\n            value<bc::wallet::payment_address>(&argument_.payment_address),\n            \"The payment address. If not specified the address is read from STDIN.\");\n\n        return options;\n    }\n\n    /**\n     * Set variable defaults from configuration variable values.\n     * @param[in]  variables  The loaded variables.\n     */\n    virtual void set_defaults_from_config(po::variables_map &variables)\n    {\n    }\n\n    /**\n     * Invoke the command.\n     * @param[out]  output  The input stream for the command execution.\n     * @param[out]  error   The input stream for the command execution.\n     * @return              The appropriate console return code { -1, 0, 1 }.\n     */\n    virtual console_result invoke(std::ostream &output,\n                                  std::ostream &cerr);\n\n    /* Properties */\n\n    /**\n     * Get the value of the PAYMENT_ADDRESS argument.\n     */\n    virtual bc::wallet::payment_address &get_payment_address_argument()\n    {\n        return argument_.payment_address;\n    }\n\n    /**\n     * Set the value of the PAYMENT_ADDRESS argument.\n     */\n    virtual void set_payment_address_argument(\n        const bc::wallet::payment_address &value)\n    {\n        argument_.payment_address = value;\n    }\n\n    /**\n     * Get the value of the format option.\n     */\n    virtual explorer::config::encoding &get_format_option()\n    {\n        return option_.format;\n    }\n\n    /**\n     * Set the value of the format option.\n     */\n    virtual void set_format_option(\n        const explorer::config::encoding &value)\n    {\n        option_.format = value;\n    }\n\n  private:\n    /**\n     * Command line argument bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct argument\n    {\n        argument()\n            : payment_address()\n        {\n        }\n\n        bc::wallet::payment_address payment_address;\n    } argument_;\n\n    /**\n     * Command line option bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct option\n    {\n        option()\n            : format()\n        {\n        }\n\n        explorer::config::encoding format;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/commands/fetch-stealth.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_FETCH_STEALTH_HPP\n#define BX_FETCH_STEALTH_HPP\n\n#include <cstdint>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/command.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/generated.hpp>\n#include <UChain/explorer/config/address.hpp>\n#include <UChain/explorer/config/algorithm.hpp>\n#include <UChain/explorer/config/btc.hpp>\n#include <UChain/explorer/config/byte.hpp>\n#include <UChain/explorer/config/cert_key.hpp>\n#include <UChain/explorer/config/ec_private.hpp>\n#include <UChain/explorer/config/encoding.hpp>\n#include <UChain/explorer/config/endorsement.hpp>\n#include <UChain/explorer/config/hashtype.hpp>\n#include <UChain/explorer/config/hd_key.hpp>\n#include <UChain/explorer/config/header.hpp>\n#include <UChain/explorer/config/input.hpp>\n#include <UChain/explorer/config/language.hpp>\n#include <UChain/explorer/config/output.hpp>\n#include <UChain/explorer/config/raw.hpp>\n#include <UChain/explorer/config/script.hpp>\n#include <UChain/explorer/config/signature.hpp>\n#include <UChain/explorer/config/transaction.hpp>\n#include <UChain/explorer/config/wrapper.hpp>\n#include <UChain/explorer/utility.hpp>\n\n/********* GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY **********/\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/**\n * Various localizable strings.\n */\n#define BX_FETCH_STEALTH_FILTER_TOO_LONG \\\n    \"Stealth prefix filter is limited to 32 bits.\"\n\n/**\n * Class to implement the fetch-stealth command.\n */\nclass BCX_API fetch_stealth\n    : public command\n{\n  public:\n    /**\n     * The symbolic (not localizable) command name, lower case.\n     */\n    static const char *symbol()\n    {\n        return \"fetch-stealth\";\n    }\n\n    /**\n     * The member symbolic (not localizable) command name, lower case.\n     */\n    virtual const char *name()\n    {\n        return fetch_stealth::symbol();\n    }\n\n    /**\n     * The localizable command category name, upper case.\n     */\n    virtual const char *category()\n    {\n        return \"ONLINE\";\n    }\n\n    /**\n     * The localizable command description.\n     */\n    virtual const char *description()\n    {\n        return \"Get metadata on potential payment transactions by stealth prefix filter. Requires a Libbitcoin server connection.\";\n    }\n\n    /**\n     * Load program argument definitions.\n     * A value of -1 indicates that the number of instances is unlimited.\n     * @return  The loaded program argument definitions.\n     */\n    virtual arguments_metadata &load_arguments()\n    {\n        return get_argument_metadata()\n            .add(\"FILTER\", 1);\n    }\n\n    /**\n     * Load parameter fallbacks from file or input as appropriate.\n     * @param[in]  input  The input stream for loading the parameters.\n     * @param[in]         The loaded variables.\n     */\n    virtual void load_fallbacks(std::istream &input,\n                                po::variables_map &variables)\n    {\n    }\n\n    /**\n     * Load program option definitions.\n     * BUGBUG: see boost bug/fix: svn.boost.org/trac/boost/ticket/8009\n     * @return  The loaded program option definitions.\n     */\n    virtual options_metadata &load_options()\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            BX_CONFIG_VARIABLE \",c\",\n            value<boost::filesystem::path>(),\n            \"The path to the configuration settings file.\")(\n            \"format,f\",\n            value<explorer::config::encoding>(&option_.format),\n            \"The output format. Options are 'info', 'json' and 'xml', defaults to 'info'.\")(\n            \"height,t\",\n            value<uint32_t>(&option_.height),\n            \"The minimum block height of transactions to include.\")(\n            \"FILTER\",\n            value<bc::config::base2>(&argument_.filter),\n            \"The Base2 stealth prefix filter used to locate transactions. Defaults to all stealth transactions.\");\n\n        return options;\n    }\n\n    /**\n     * Set variable defaults from configuration variable values.\n     * @param[in]  variables  The loaded variables.\n     */\n    virtual void set_defaults_from_config(po::variables_map &variables)\n    {\n    }\n\n    /**\n     * Invoke the command.\n     * @param[out]  output  The input stream for the command execution.\n     * @param[out]  error   The input stream for the command execution.\n     * @return              The appropriate console return code { -1, 0, 1 }.\n     */\n    virtual console_result invoke(std::ostream &output,\n                                  std::ostream &cerr);\n\n    /* Properties */\n\n    /**\n     * Get the value of the FILTER argument.\n     */\n    virtual bc::config::base2 &get_filter_argument()\n    {\n        return argument_.filter;\n    }\n\n    /**\n     * Set the value of the FILTER argument.\n     */\n    virtual void set_filter_argument(\n        const bc::config::base2 &value)\n    {\n        argument_.filter = value;\n    }\n\n    /**\n     * Get the value of the format option.\n     */\n    virtual explorer::config::encoding &get_format_option()\n    {\n        return option_.format;\n    }\n\n    /**\n     * Set the value of the format option.\n     */\n    virtual void set_format_option(\n        const explorer::config::encoding &value)\n    {\n        option_.format = value;\n    }\n\n    /**\n     * Get the value of the height option.\n     */\n    virtual uint32_t &get_height_option()\n    {\n        return option_.height;\n    }\n\n    /**\n     * Set the value of the height option.\n     */\n    virtual void set_height_option(\n        const uint32_t &value)\n    {\n        option_.height = value;\n    }\n\n  private:\n    /**\n     * Command line argument bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct argument\n    {\n        argument()\n            : filter()\n        {\n        }\n\n        bc::config::base2 filter;\n    } argument_;\n\n    /**\n     * Command line option bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct option\n    {\n        option()\n            : format(),\n              height()\n        {\n        }\n\n        explorer::config::encoding format;\n        uint32_t height;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/commands/help.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_HELP_HPP\n#define BX_HELP_HPP\n\n#include <cstdint>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/command.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/generated.hpp>\n#include <UChain/explorer/config/address.hpp>\n#include <UChain/explorer/config/algorithm.hpp>\n#include <UChain/explorer/config/btc.hpp>\n#include <UChain/explorer/config/byte.hpp>\n#include <UChain/explorer/config/cert_key.hpp>\n#include <UChain/explorer/config/ec_private.hpp>\n#include <UChain/explorer/config/encoding.hpp>\n#include <UChain/explorer/config/endorsement.hpp>\n#include <UChain/explorer/config/hashtype.hpp>\n#include <UChain/explorer/config/hd_key.hpp>\n#include <UChain/explorer/config/header.hpp>\n#include <UChain/explorer/config/input.hpp>\n#include <UChain/explorer/config/language.hpp>\n#include <UChain/explorer/config/output.hpp>\n#include <UChain/explorer/config/raw.hpp>\n#include <UChain/explorer/config/script.hpp>\n#include <UChain/explorer/config/signature.hpp>\n#include <UChain/explorer/config/transaction.hpp>\n#include <UChain/explorer/config/wrapper.hpp>\n#include <UChain/explorer/utility.hpp>\n\n/********* GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY **********/\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/**\n * Class to implement the help command.\n */\nclass BCX_API help\n    : public command\n{\n  public:\n    /**\n     * The symbolic (not localizable) command name, lower case.\n     */\n    static const char *symbol()\n    {\n        return \"help\";\n    }\n\n    /**\n     * The member symbolic (not localizable) command name, lower case.\n     */\n    virtual const char *name()\n    {\n        return help::symbol();\n    }\n\n    /**\n     * The localizable command category name, upper case.\n     */\n    virtual const char *category()\n    {\n        return \"META\";\n    }\n\n    /**\n     * The localizable command description.\n     */\n    virtual const char *description()\n    {\n        return \"Get the list of commands.\";\n    }\n\n    /**\n     * Load program argument definitions.\n     * A value of -1 indicates that the number of instances is unlimited.\n     * @return  The loaded program argument definitions.\n     */\n    virtual arguments_metadata &load_arguments()\n    {\n        return get_argument_metadata()\n            .add(\"COMMAND\", 1);\n    }\n\n    /**\n     * Load parameter fallbacks from file or input as appropriate.\n     * @param[in]  input  The input stream for loading the parameters.\n     * @param[in]         The loaded variables.\n     */\n    virtual void load_fallbacks(std::istream &input,\n                                po::variables_map &variables)\n    {\n    }\n\n    /**\n     * Load program option definitions.\n     * BUGBUG: see boost bug/fix: svn.boost.org/trac/boost/ticket/8009\n     * @return  The loaded program option definitions.\n     */\n    virtual options_metadata &load_options()\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"COMMAND\",\n            value<std::string>(&argument_.command),\n            \"The command for which help is requested.\");\n\n        return options;\n    }\n\n    /**\n     * Set variable defaults from configuration variable values.\n     * @param[in]  variables  The loaded variables.\n     */\n    virtual void set_defaults_from_config(po::variables_map &variables)\n    {\n    }\n\n    /**\n     * Invoke the command.\n     * @param[out]  output  The input stream for the command execution.\n     * @param[out]  error   The input stream for the command execution.\n     * @return              The appropriate console return code { -1, 0, 1 }.\n     */\n    virtual console_result invoke(std::ostream &output,\n                                  std::ostream &cerr);\n\n    /* Properties */\n\n    /**\n     * Get the value of the COMMAND argument.\n     */\n    virtual std::string &get_command_argument()\n    {\n        return argument_.command;\n    }\n\n    /**\n     * Set the value of the COMMAND argument.\n     */\n    virtual void set_command_argument(\n        const std::string &value)\n    {\n        argument_.command = value;\n    }\n\n  private:\n    /**\n     * Command line argument bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct argument\n    {\n        argument()\n            : command()\n        {\n        }\n\n        std::string command;\n    } argument_;\n\n    /**\n     * Command line option bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct option\n    {\n        option()\n        {\n        }\n\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/commands/offline_commands_impl.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/utility.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nnamespace bw = bc::wallet;\nnamespace bconfig = bc::config;\n\n// -------------------------------------------------------------------\n// macro for version\nconst uint32_t hd_default_secret_version = 76066276;\nconst uint32_t hd_default_public_version = 76067358;\n\n// -------------------------------------------------------------------\n// macro for error message\n#define UCCLI_SEED_BIT_LENGTH_UNSUPPORTED \\\n    \"The seed size is not supported.\"\n#define UCCLI_EC_MNEMONIC_NEW_INVALID_ENTROPY \\\n    \"The seed length in bytes is not evenly divisible by 32 bits.\"\n#define UCCLI_EC_MNEMONIC_TO_SEED_LENGTH_INVALID_SENTENCE \\\n    \"The number of words must be divisible by 3.\"\n#define UCCLI_EC_MNEMONIC_TO_SEED_PASSPHRASE_UNSUPPORTED \\\n    \"The passphrase option requires an ICU build.\"\n#define UCCLI_EC_MNEMONIC_TO_SEED_INVALID_IN_LANGUAGE \\\n    \"The specified words are not a valid mnemonic in the specified dictionary.\"\n#define UCCLI_EC_MNEMONIC_TO_SEED_INVALID_IN_LANGUAGES \\\n    \"WARNING: The specified words are not a valid mnemonic in any supported dictionary.\"\n#define UCCLI_EC_MNEMONIC_TO_SEED_EMPTY_WORDS \\\n    \"The specified words are empty.\"\n#define UCCLI_EC_MNEMONIC_TO_SEED_WORD_NOT_IN_DICTIONARY \\\n    \"The specified words contain illegal word that is not included in the dictionary.\"\n#define UCCLI_HD_NEW_SHORT_SEED \\\n    \"The seed is less than 128 bits long.\"\n#define UCCLI_HD_NEW_INVALID_KEY \\\n    \"The seed produced an invalid key.\"\n\n// -------------------------------------------------------------------\n// decalration for functions\n\ndata_chunk get_seed(uint16_t bit_length = 256u);\n\nbw::word_list get_mnemonic_new(const bw::dictionary_list &language, const data_chunk &entropy);\n\ndata_chunk get_mnemonic_to_seed(const bw::dictionary_list &language,\n                                const bw::word_list &words,\n                                std::string passphrase = \"\");\n\nbw::hd_private get_hd_new(const data_chunk &seed, uint32_t version = hd_default_secret_version);\n\n} //namespace commands\n} //namespace explorer\n} //namespace libbitcoin\n"
  },
  {
    "path": "include/UChain/explorer/commands/send-tx.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_SEND_TX_HPP\n#define BX_SEND_TX_HPP\n\n#include <cstdint>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/command.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/generated.hpp>\n#include <UChain/explorer/config/address.hpp>\n#include <UChain/explorer/config/algorithm.hpp>\n#include <UChain/explorer/config/btc.hpp>\n#include <UChain/explorer/config/byte.hpp>\n#include <UChain/explorer/config/cert_key.hpp>\n#include <UChain/explorer/config/ec_private.hpp>\n#include <UChain/explorer/config/encoding.hpp>\n#include <UChain/explorer/config/endorsement.hpp>\n#include <UChain/explorer/config/hashtype.hpp>\n#include <UChain/explorer/config/hd_key.hpp>\n#include <UChain/explorer/config/header.hpp>\n#include <UChain/explorer/config/input.hpp>\n#include <UChain/explorer/config/language.hpp>\n#include <UChain/explorer/config/output.hpp>\n#include <UChain/explorer/config/raw.hpp>\n#include <UChain/explorer/config/script.hpp>\n#include <UChain/explorer/config/signature.hpp>\n#include <UChain/explorer/config/transaction.hpp>\n#include <UChain/explorer/config/wrapper.hpp>\n#include <UChain/explorer/utility.hpp>\n\n/********* GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY **********/\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/**\n * Various localizable strings.\n */\n#define BX_SEND_TX_OUTPUT \\\n    \"Sent transaction.\"\n\n/**\n * Class to implement the send-tx command.\n */\nclass BCX_API send_tx\n    : public command\n{\n  public:\n    /**\n     * The symbolic (not localizable) command name, lower case.\n     */\n    static const char *symbol()\n    {\n        return \"send-tx\";\n    }\n\n    /**\n     * The symbolic (not localizable) former command name, lower case.\n     */\n    static const char *formerly()\n    {\n        return \"sendtx-obelisk\";\n    }\n\n    /**\n     * The member symbolic (not localizable) command name, lower case.\n     */\n    virtual const char *name()\n    {\n        return send_tx::symbol();\n    }\n\n    /**\n     * The localizable command category name, upper case.\n     */\n    virtual const char *category()\n    {\n        return \"ONLINE\";\n    }\n\n    /**\n     * The localizable command description.\n     */\n    virtual const char *description()\n    {\n        return \"Broadcast a transaction to the Bitcoin network via an UChain/Obelisk server.\";\n    }\n\n    /**\n     * Load program argument definitions.\n     * A value of -1 indicates that the number of instances is unlimited.\n     * @return  The loaded program argument definitions.\n     */\n    virtual arguments_metadata &load_arguments()\n    {\n        return get_argument_metadata()\n            .add(\"TRANSACTION\", 1);\n    }\n\n    /**\n     * Load parameter fallbacks from file or input as appropriate.\n     * @param[in]  input  The input stream for loading the parameters.\n     * @param[in]         The loaded variables.\n     */\n    virtual void load_fallbacks(std::istream &input,\n                                po::variables_map &variables)\n    {\n        const auto raw = requires_raw_input();\n        load_input(get_transaction_argument(), \"TRANSACTION\", variables, input, raw);\n    }\n\n    /**\n     * Load program option definitions.\n     * BUGBUG: see boost bug/fix: svn.boost.org/trac/boost/ticket/8009\n     * @return  The loaded program option definitions.\n     */\n    virtual options_metadata &load_options()\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            BX_CONFIG_VARIABLE \",c\",\n            value<boost::filesystem::path>(),\n            \"The path to the configuration settings file.\")(\n            \"TRANSACTION\",\n            value<explorer::config::transaction>(&argument_.transaction),\n            \"The Base16 transaction to send. If not specified the transaction is read from STDIN.\");\n\n        return options;\n    }\n\n    /**\n     * Set variable defaults from configuration variable values.\n     * @param[in]  variables  The loaded variables.\n     */\n    virtual void set_defaults_from_config(po::variables_map &variables)\n    {\n    }\n\n    /**\n     * Invoke the command.\n     * @param[out]  output  The input stream for the command execution.\n     * @param[out]  error   The input stream for the command execution.\n     * @return              The appropriate console return code { -1, 0, 1 }.\n     */\n    virtual console_result invoke(std::ostream &output,\n                                  std::ostream &cerr);\n\n    /* Properties */\n\n    /**\n     * Get the value of the TRANSACTION argument.\n     */\n    virtual explorer::config::transaction &get_transaction_argument()\n    {\n        return argument_.transaction;\n    }\n\n    /**\n     * Set the value of the TRANSACTION argument.\n     */\n    virtual void set_transaction_argument(\n        const explorer::config::transaction &value)\n    {\n        argument_.transaction = value;\n    }\n\n  private:\n    /**\n     * Command line argument bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct argument\n    {\n        argument()\n            : transaction()\n        {\n        }\n\n        explorer::config::transaction transaction;\n    } argument_;\n\n    /**\n     * Command line option bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct option\n    {\n        option()\n        {\n        }\n\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/commands/settings.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_SETTINGS_HPP\n#define BX_SETTINGS_HPP\n\n#include <cstdint>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/command.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/generated.hpp>\n#include <UChain/explorer/config/address.hpp>\n#include <UChain/explorer/config/algorithm.hpp>\n#include <UChain/explorer/config/btc.hpp>\n#include <UChain/explorer/config/byte.hpp>\n#include <UChain/explorer/config/cert_key.hpp>\n#include <UChain/explorer/config/ec_private.hpp>\n#include <UChain/explorer/config/encoding.hpp>\n#include <UChain/explorer/config/endorsement.hpp>\n#include <UChain/explorer/config/hashtype.hpp>\n#include <UChain/explorer/config/hd_key.hpp>\n#include <UChain/explorer/config/header.hpp>\n#include <UChain/explorer/config/input.hpp>\n#include <UChain/explorer/config/language.hpp>\n#include <UChain/explorer/config/output.hpp>\n#include <UChain/explorer/config/raw.hpp>\n#include <UChain/explorer/config/script.hpp>\n#include <UChain/explorer/config/signature.hpp>\n#include <UChain/explorer/config/transaction.hpp>\n#include <UChain/explorer/config/wrapper.hpp>\n#include <UChain/explorer/utility.hpp>\n\n/********* GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY **********/\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/**\n * Class to implement the settings command.\n */\nclass BCX_API settings\n    : public command\n{\n  public:\n    /**\n     * The symbolic (not localizable) command name, lower case.\n     */\n    static const char *symbol()\n    {\n        return \"settings\";\n    }\n\n    /**\n     * The member symbolic (not localizable) command name, lower case.\n     */\n    virtual const char *name()\n    {\n        return settings::symbol();\n    }\n\n    /**\n     * The localizable command category name, upper case.\n     */\n    virtual const char *category()\n    {\n        return \"META\";\n    }\n\n    /**\n     * The localizable command description.\n     */\n    virtual const char *description()\n    {\n        return \"Display the loaded configuration settings.\";\n    }\n\n    /**\n     * Load program argument definitions.\n     * A value of -1 indicates that the number of instances is unlimited.\n     * @return  The loaded program argument definitions.\n     */\n    virtual arguments_metadata &load_arguments()\n    {\n        return get_argument_metadata();\n    }\n\n    /**\n     * Load parameter fallbacks from file or input as appropriate.\n     * @param[in]  input  The input stream for loading the parameters.\n     * @param[in]         The loaded variables.\n     */\n    virtual void load_fallbacks(std::istream &input,\n                                po::variables_map &variables)\n    {\n    }\n\n    /**\n     * Load program option definitions.\n     * BUGBUG: see boost bug/fix: svn.boost.org/trac/boost/ticket/8009\n     * @return  The loaded program option definitions.\n     */\n    virtual options_metadata &load_options()\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            BX_CONFIG_VARIABLE \",c\",\n            value<boost::filesystem::path>(),\n            \"The path to the configuration settings file.\")(\n            \"format,f\",\n            value<explorer::config::encoding>(&option_.format),\n            \"The output format. Options are 'info', 'json' and 'xml', defaults to 'info'.\");\n\n        return options;\n    }\n\n    /**\n     * Set variable defaults from configuration variable values.\n     * @param[in]  variables  The loaded variables.\n     */\n    virtual void set_defaults_from_config(po::variables_map &variables)\n    {\n    }\n\n    /**\n     * Invoke the command.\n     * @param[out]  output  The input stream for the command execution.\n     * @param[out]  error   The input stream for the command execution.\n     * @return              The appropriate console return code { -1, 0, 1 }.\n     */\n    virtual console_result invoke(std::ostream &output,\n                                  std::ostream &cerr);\n\n    /* Properties */\n\n    /**\n     * Get the value of the format option.\n     */\n    virtual explorer::config::encoding &get_format_option()\n    {\n        return option_.format;\n    }\n\n    /**\n     * Set the value of the format option.\n     */\n    virtual void set_format_option(\n        const explorer::config::encoding &value)\n    {\n        option_.format = value;\n    }\n\n  private:\n    /**\n     * Command line argument bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct argument\n    {\n        argument()\n        {\n        }\n\n    } argument_;\n\n    /**\n     * Command line option bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct option\n    {\n        option()\n            : format()\n        {\n        }\n\n        explorer::config::encoding format;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/commands/stealth-decode.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_STEALTH_DECODE_HPP\n#define BX_STEALTH_DECODE_HPP\n\n#include <cstdint>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/command.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/generated.hpp>\n#include <UChain/explorer/config/address.hpp>\n#include <UChain/explorer/config/algorithm.hpp>\n#include <UChain/explorer/config/btc.hpp>\n#include <UChain/explorer/config/byte.hpp>\n#include <UChain/explorer/config/cert_key.hpp>\n#include <UChain/explorer/config/ec_private.hpp>\n#include <UChain/explorer/config/encoding.hpp>\n#include <UChain/explorer/config/endorsement.hpp>\n#include <UChain/explorer/config/hashtype.hpp>\n#include <UChain/explorer/config/hd_key.hpp>\n#include <UChain/explorer/config/header.hpp>\n#include <UChain/explorer/config/input.hpp>\n#include <UChain/explorer/config/language.hpp>\n#include <UChain/explorer/config/output.hpp>\n#include <UChain/explorer/config/raw.hpp>\n#include <UChain/explorer/config/script.hpp>\n#include <UChain/explorer/config/signature.hpp>\n#include <UChain/explorer/config/transaction.hpp>\n#include <UChain/explorer/config/wrapper.hpp>\n#include <UChain/explorer/utility.hpp>\n\n/********* GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY **********/\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/**\n * Class to implement the stealth-decode command.\n */\nclass BCX_API stealth_decode\n    : public command\n{\n  public:\n    /**\n     * The symbolic (not localizable) command name, lower case.\n     */\n    static const char *symbol()\n    {\n        return \"stealth-decode\";\n    }\n\n    /**\n     * The symbolic (not localizable) former command name, lower case.\n     */\n    static const char *formerly()\n    {\n        return \"stealth-show-addr\";\n    }\n\n    /**\n     * The member symbolic (not localizable) command name, lower case.\n     */\n    virtual const char *name()\n    {\n        return stealth_decode::symbol();\n    }\n\n    /**\n     * The localizable command category name, upper case.\n     */\n    virtual const char *category()\n    {\n        return \"STEALTH\";\n    }\n\n    /**\n     * The localizable command description.\n     */\n    virtual const char *description()\n    {\n        return \"Decode a stealth address.\";\n    }\n\n    /**\n     * Load program argument definitions.\n     * A value of -1 indicates that the number of instances is unlimited.\n     * @return  The loaded program argument definitions.\n     */\n    virtual arguments_metadata &load_arguments()\n    {\n        return get_argument_metadata()\n            .add(\"STEALTH_ADDRESS\", 1);\n    }\n\n    /**\n     * Load parameter fallbacks from file or input as appropriate.\n     * @param[in]  input  The input stream for loading the parameters.\n     * @param[in]         The loaded variables.\n     */\n    virtual void load_fallbacks(std::istream &input,\n                                po::variables_map &variables)\n    {\n        const auto raw = requires_raw_input();\n        load_input(get_stealth_address_argument(), \"STEALTH_ADDRESS\", variables, input, raw);\n    }\n\n    /**\n     * Load program option definitions.\n     * BUGBUG: see boost bug/fix: svn.boost.org/trac/boost/ticket/8009\n     * @return  The loaded program option definitions.\n     */\n    virtual options_metadata &load_options()\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            BX_CONFIG_VARIABLE \",c\",\n            value<boost::filesystem::path>(),\n            \"The path to the configuration settings file.\")(\n            \"format,f\",\n            value<explorer::config::encoding>(&option_.format),\n            \"The output format. Options are 'info', 'json' and 'xml', defaults to 'info'.\")(\n            \"STEALTH_ADDRESS\",\n            value<bc::wallet::stealth_address>(&argument_.stealth_address),\n            \"The stealth payment address. If not specified the address is read from STDIN.\");\n\n        return options;\n    }\n\n    /**\n     * Set variable defaults from configuration variable values.\n     * @param[in]  variables  The loaded variables.\n     */\n    virtual void set_defaults_from_config(po::variables_map &variables)\n    {\n    }\n\n    /**\n     * Invoke the command.\n     * @param[out]  output  The input stream for the command execution.\n     * @param[out]  error   The input stream for the command execution.\n     * @return              The appropriate console return code { -1, 0, 1 }.\n     */\n    virtual console_result invoke(std::ostream &output,\n                                  std::ostream &cerr);\n\n    /* Properties */\n\n    /**\n     * Get the value of the STEALTH_ADDRESS argument.\n     */\n    virtual bc::wallet::stealth_address &get_stealth_address_argument()\n    {\n        return argument_.stealth_address;\n    }\n\n    /**\n     * Set the value of the STEALTH_ADDRESS argument.\n     */\n    virtual void set_stealth_address_argument(\n        const bc::wallet::stealth_address &value)\n    {\n        argument_.stealth_address = value;\n    }\n\n    /**\n     * Get the value of the format option.\n     */\n    virtual explorer::config::encoding &get_format_option()\n    {\n        return option_.format;\n    }\n\n    /**\n     * Set the value of the format option.\n     */\n    virtual void set_format_option(\n        const explorer::config::encoding &value)\n    {\n        option_.format = value;\n    }\n\n  private:\n    /**\n     * Command line argument bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct argument\n    {\n        argument()\n            : stealth_address()\n        {\n        }\n\n        bc::wallet::stealth_address stealth_address;\n    } argument_;\n\n    /**\n     * Command line option bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct option\n    {\n        option()\n            : format()\n        {\n        }\n\n        explorer::config::encoding format;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/commands/stealth-encode.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_STEALTH_ENCODE_HPP\n#define BX_STEALTH_ENCODE_HPP\n\n#include <cstdint>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/command.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/generated.hpp>\n#include <UChain/explorer/config/address.hpp>\n#include <UChain/explorer/config/algorithm.hpp>\n#include <UChain/explorer/config/btc.hpp>\n#include <UChain/explorer/config/byte.hpp>\n#include <UChain/explorer/config/cert_key.hpp>\n#include <UChain/explorer/config/ec_private.hpp>\n#include <UChain/explorer/config/encoding.hpp>\n#include <UChain/explorer/config/endorsement.hpp>\n#include <UChain/explorer/config/hashtype.hpp>\n#include <UChain/explorer/config/hd_key.hpp>\n#include <UChain/explorer/config/header.hpp>\n#include <UChain/explorer/config/input.hpp>\n#include <UChain/explorer/config/language.hpp>\n#include <UChain/explorer/config/output.hpp>\n#include <UChain/explorer/config/raw.hpp>\n#include <UChain/explorer/config/script.hpp>\n#include <UChain/explorer/config/signature.hpp>\n#include <UChain/explorer/config/transaction.hpp>\n#include <UChain/explorer/config/wrapper.hpp>\n#include <UChain/explorer/utility.hpp>\n\n/********* GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY **********/\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/**\n * Various localizable strings.\n */\n#define BX_STEALTH_ENCODE_FILTER_TOO_LONG \\\n    \"The filter is limited to 32 bits.\"\n#define BX_STEALTH_ENCODE_SIGNATURES_OVERFLOW \\\n    \"The number of signatures is greater than the number of SPEND_PUBKEYs.\"\n#define BX_STEALTH_ENCODE_MULTISIG_NOT_SUPPORTED \\\n    \"WARNING: multiple signature stealth transactions are not yet fully supported.\"\n\n/**\n * Class to implement the stealth-encode command.\n */\nclass BCX_API stealth_encode\n    : public command\n{\n  public:\n    /**\n     * The symbolic (not localizable) command name, lower case.\n     */\n    static const char *symbol()\n    {\n        return \"stealth-encode\";\n    }\n\n    /**\n     * The member symbolic (not localizable) command name, lower case.\n     */\n    virtual const char *name()\n    {\n        return stealth_encode::symbol();\n    }\n\n    /**\n     * The localizable command category name, upper case.\n     */\n    virtual const char *category()\n    {\n        return \"STEALTH\";\n    }\n\n    /**\n     * The localizable command description.\n     */\n    virtual const char *description()\n    {\n        return \"Encode a stealth payment address.\";\n    }\n\n    /**\n     * Load program argument definitions.\n     * A value of -1 indicates that the number of instances is unlimited.\n     * @return  The loaded program argument definitions.\n     */\n    virtual arguments_metadata &load_arguments()\n    {\n        return get_argument_metadata()\n            .add(\"SCAN_PUBKEY\", 1)\n            .add(\"SPEND_PUBKEY\", -1);\n    }\n\n    /**\n     * Load parameter fallbacks from file or input as appropriate.\n     * @param[in]  input  The input stream for loading the parameters.\n     * @param[in]         The loaded variables.\n     */\n    virtual void load_fallbacks(std::istream &input,\n                                po::variables_map &variables)\n    {\n    }\n\n    /**\n     * Load program option definitions.\n     * BUGBUG: see boost bug/fix: svn.boost.org/trac/boost/ticket/8009\n     * @return  The loaded program option definitions.\n     */\n    virtual options_metadata &load_options()\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            BX_CONFIG_VARIABLE \",c\",\n            value<boost::filesystem::path>(),\n            \"The path to the configuration settings file.\")(\n            \"filter,f\",\n            value<bc::config::base2>(&option_.filter),\n            \"The Base2 stealth prefix filter that will be used to locate payments.\")(\n            \"signatures,s\",\n            value<explorer::config::byte>(&option_.signatures),\n            \"The number of signatures required to spend a payment to the stealth address. Defaults to the number of SPEND_PUBKEYs.\")(\n            \"version,v\",\n            value<explorer::config::byte>(&option_.version)->default_value(0),\n            \"The desired payment address version, defaults to 0.\")(\n            \"SCAN_PUBKEY\",\n            value<bc::wallet::ec_public>(&argument_.scan_pubkey)->required(),\n            \"The Base16 EC public key required to create a payment.\")(\n            \"SPEND_PUBKEY\",\n            value<std::vector<bc::wallet::ec_public>>(&argument_.spend_pubkeys),\n            \"The set of Base16 EC public keys corresponding to private keys that will be able to spend payments to the address. Defaults to the value of SCAN_PUBKEY.\");\n\n        return options;\n    }\n\n    /**\n     * Set variable defaults from configuration variable values.\n     * @param[in]  variables  The loaded variables.\n     */\n    virtual void set_defaults_from_config(po::variables_map &variables)\n    {\n        const auto &option_version = variables[\"version\"];\n        const auto &option_version_config = variables[\"wallet.pay_to_public_key_hash_version\"];\n        if (option_version.defaulted() && !option_version_config.defaulted())\n        {\n            option_.version = option_version_config.as<explorer::config::byte>();\n        }\n    }\n\n    /**\n     * Invoke the command.\n     * @param[out]  output  The input stream for the command execution.\n     * @param[out]  error   The input stream for the command execution.\n     * @return              The appropriate console return code { -1, 0, 1 }.\n     */\n    virtual console_result invoke(std::ostream &output,\n                                  std::ostream &cerr);\n\n    /* Properties */\n\n    /**\n     * Get the value of the SCAN_PUBKEY argument.\n     */\n    virtual bc::wallet::ec_public &get_scan_pubkey_argument()\n    {\n        return argument_.scan_pubkey;\n    }\n\n    /**\n     * Set the value of the SCAN_PUBKEY argument.\n     */\n    virtual void set_scan_pubkey_argument(\n        const bc::wallet::ec_public &value)\n    {\n        argument_.scan_pubkey = value;\n    }\n\n    /**\n     * Get the value of the SPEND_PUBKEY arguments.\n     */\n    virtual std::vector<bc::wallet::ec_public> &get_spend_pubkeys_argument()\n    {\n        return argument_.spend_pubkeys;\n    }\n\n    /**\n     * Set the value of the SPEND_PUBKEY arguments.\n     */\n    virtual void set_spend_pubkeys_argument(\n        const std::vector<bc::wallet::ec_public> &value)\n    {\n        argument_.spend_pubkeys = value;\n    }\n\n    /**\n     * Get the value of the filter option.\n     */\n    virtual bc::config::base2 &get_filter_option()\n    {\n        return option_.filter;\n    }\n\n    /**\n     * Set the value of the filter option.\n     */\n    virtual void set_filter_option(\n        const bc::config::base2 &value)\n    {\n        option_.filter = value;\n    }\n\n    /**\n     * Get the value of the signatures option.\n     */\n    virtual explorer::config::byte &get_signatures_option()\n    {\n        return option_.signatures;\n    }\n\n    /**\n     * Set the value of the signatures option.\n     */\n    virtual void set_signatures_option(\n        const explorer::config::byte &value)\n    {\n        option_.signatures = value;\n    }\n\n    /**\n     * Get the value of the version option.\n     */\n    virtual explorer::config::byte &get_version_option()\n    {\n        return option_.version;\n    }\n\n    /**\n     * Set the value of the version option.\n     */\n    virtual void set_version_option(\n        const explorer::config::byte &value)\n    {\n        option_.version = value;\n    }\n\n  private:\n    /**\n     * Command line argument bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct argument\n    {\n        argument()\n            : scan_pubkey(),\n              spend_pubkeys()\n        {\n        }\n\n        bc::wallet::ec_public scan_pubkey;\n        std::vector<bc::wallet::ec_public> spend_pubkeys;\n    } argument_;\n\n    /**\n     * Command line option bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct option\n    {\n        option()\n            : filter(),\n              signatures(),\n              version()\n        {\n        }\n\n        bc::config::base2 filter;\n        explorer::config::byte signatures;\n        explorer::config::byte version;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/commands/stealth-public.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_STEALTH_PUBLIC_HPP\n#define BX_STEALTH_PUBLIC_HPP\n\n#include <cstdint>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/command.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/generated.hpp>\n#include <UChain/explorer/config/address.hpp>\n#include <UChain/explorer/config/algorithm.hpp>\n#include <UChain/explorer/config/btc.hpp>\n#include <UChain/explorer/config/byte.hpp>\n#include <UChain/explorer/config/cert_key.hpp>\n#include <UChain/explorer/config/ec_private.hpp>\n#include <UChain/explorer/config/encoding.hpp>\n#include <UChain/explorer/config/endorsement.hpp>\n#include <UChain/explorer/config/hashtype.hpp>\n#include <UChain/explorer/config/hd_key.hpp>\n#include <UChain/explorer/config/header.hpp>\n#include <UChain/explorer/config/input.hpp>\n#include <UChain/explorer/config/language.hpp>\n#include <UChain/explorer/config/output.hpp>\n#include <UChain/explorer/config/raw.hpp>\n#include <UChain/explorer/config/script.hpp>\n#include <UChain/explorer/config/signature.hpp>\n#include <UChain/explorer/config/transaction.hpp>\n#include <UChain/explorer/config/wrapper.hpp>\n#include <UChain/explorer/utility.hpp>\n\n/********* GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY **********/\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/**\n * Various localizable strings.\n */\n#define BX_STEALTH_PUBLIC_OUT_OF_RANGE \\\n    \"Function exceeds valid range.\"\n\n/**\n * Class to implement the stealth-public command.\n */\nclass BCX_API stealth_public\n    : public command\n{\n  public:\n    /**\n     * The symbolic (not localizable) command name, lower case.\n     */\n    static const char *symbol()\n    {\n        return \"stealth-public\";\n    }\n\n    /**\n     * The symbolic (not localizable) former command name, lower case.\n     */\n    static const char *formerly()\n    {\n        return \"stealth-uncover\";\n    }\n\n    /**\n     * The member symbolic (not localizable) command name, lower case.\n     */\n    virtual const char *name()\n    {\n        return stealth_public::symbol();\n    }\n\n    /**\n     * The localizable command category name, upper case.\n     */\n    virtual const char *category()\n    {\n        return \"STEALTH\";\n    }\n\n    /**\n     * The localizable command description.\n     */\n    virtual const char *description()\n    {\n        return \"Derive the stealth public key necessary to address and to identify a stealth payment.\";\n    }\n\n    /**\n     * Load program argument definitions.\n     * A value of -1 indicates that the number of instances is unlimited.\n     * @return  The loaded program argument definitions.\n     */\n    virtual arguments_metadata &load_arguments()\n    {\n        return get_argument_metadata()\n            .add(\"SPEND_PUBKEY\", 1)\n            .add(\"SHARED_SECRET\", 1);\n    }\n\n    /**\n     * Load parameter fallbacks from file or input as appropriate.\n     * @param[in]  input  The input stream for loading the parameters.\n     * @param[in]         The loaded variables.\n     */\n    virtual void load_fallbacks(std::istream &input,\n                                po::variables_map &variables)\n    {\n        const auto raw = requires_raw_input();\n        load_input(get_shared_secret_argument(), \"SHARED_SECRET\", variables, input, raw);\n    }\n\n    /**\n     * Load program option definitions.\n     * BUGBUG: see boost bug/fix: svn.boost.org/trac/boost/ticket/8009\n     * @return  The loaded program option definitions.\n     */\n    virtual options_metadata &load_options()\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            BX_CONFIG_VARIABLE \",c\",\n            value<boost::filesystem::path>(),\n            \"The path to the configuration settings file.\")(\n            \"SPEND_PUBKEY\",\n            value<bc::wallet::ec_public>(&argument_.spend_pubkey)->required(),\n            \"The Base16 EC spend public key of a stealth address.\")(\n            \"SHARED_SECRET\",\n            value<explorer::config::ec_private>(&argument_.shared_secret),\n            \"The Base16 EC shared secret corresponding to the SPEND_PUBKEY. If not specified the key is read from STDIN.\");\n\n        return options;\n    }\n\n    /**\n     * Set variable defaults from configuration variable values.\n     * @param[in]  variables  The loaded variables.\n     */\n    virtual void set_defaults_from_config(po::variables_map &variables)\n    {\n    }\n\n    /**\n     * Invoke the command.\n     * @param[out]  output  The input stream for the command execution.\n     * @param[out]  error   The input stream for the command execution.\n     * @return              The appropriate console return code { -1, 0, 1 }.\n     */\n    virtual console_result invoke(std::ostream &output,\n                                  std::ostream &cerr);\n\n    /* Properties */\n\n    /**\n     * Get the value of the SPEND_PUBKEY argument.\n     */\n    virtual bc::wallet::ec_public &get_spend_pubkey_argument()\n    {\n        return argument_.spend_pubkey;\n    }\n\n    /**\n     * Set the value of the SPEND_PUBKEY argument.\n     */\n    virtual void set_spend_pubkey_argument(\n        const bc::wallet::ec_public &value)\n    {\n        argument_.spend_pubkey = value;\n    }\n\n    /**\n     * Get the value of the SHARED_SECRET argument.\n     */\n    virtual explorer::config::ec_private &get_shared_secret_argument()\n    {\n        return argument_.shared_secret;\n    }\n\n    /**\n     * Set the value of the SHARED_SECRET argument.\n     */\n    virtual void set_shared_secret_argument(\n        const explorer::config::ec_private &value)\n    {\n        argument_.shared_secret = value;\n    }\n\n  private:\n    /**\n     * Command line argument bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct argument\n    {\n        argument()\n            : spend_pubkey(),\n              shared_secret()\n        {\n        }\n\n        bc::wallet::ec_public spend_pubkey;\n        explorer::config::ec_private shared_secret;\n    } argument_;\n\n    /**\n     * Command line option bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct option\n    {\n        option()\n        {\n        }\n\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/commands/stealth-secret.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_STEALTH_SECRET_HPP\n#define BX_STEALTH_SECRET_HPP\n\n#include <cstdint>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/command.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/generated.hpp>\n#include <UChain/explorer/config/address.hpp>\n#include <UChain/explorer/config/algorithm.hpp>\n#include <UChain/explorer/config/btc.hpp>\n#include <UChain/explorer/config/byte.hpp>\n#include <UChain/explorer/config/cert_key.hpp>\n#include <UChain/explorer/config/ec_private.hpp>\n#include <UChain/explorer/config/encoding.hpp>\n#include <UChain/explorer/config/endorsement.hpp>\n#include <UChain/explorer/config/hashtype.hpp>\n#include <UChain/explorer/config/hd_key.hpp>\n#include <UChain/explorer/config/header.hpp>\n#include <UChain/explorer/config/input.hpp>\n#include <UChain/explorer/config/language.hpp>\n#include <UChain/explorer/config/output.hpp>\n#include <UChain/explorer/config/raw.hpp>\n#include <UChain/explorer/config/script.hpp>\n#include <UChain/explorer/config/signature.hpp>\n#include <UChain/explorer/config/transaction.hpp>\n#include <UChain/explorer/config/wrapper.hpp>\n#include <UChain/explorer/utility.hpp>\n\n/********* GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY **********/\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/**\n * Various localizable strings.\n */\n#define BX_STEALTH_SECRET_OUT_OF_RANGE \\\n    \"Sum exceeds valid range.\"\n\n/**\n * Class to implement the stealth-secret command.\n */\nclass BCX_API stealth_secret\n    : public command\n{\n  public:\n    /**\n     * The symbolic (not localizable) command name, lower case.\n     */\n    static const char *symbol()\n    {\n        return \"stealth-secret\";\n    }\n\n    /**\n     * The symbolic (not localizable) former command name, lower case.\n     */\n    static const char *formerly()\n    {\n        return \"stealth-uncover-secret\";\n    }\n\n    /**\n     * The member symbolic (not localizable) command name, lower case.\n     */\n    virtual const char *name()\n    {\n        return stealth_secret::symbol();\n    }\n\n    /**\n     * The localizable command category name, upper case.\n     */\n    virtual const char *category()\n    {\n        return \"STEALTH\";\n    }\n\n    /**\n     * The localizable command description.\n     */\n    virtual const char *description()\n    {\n        return \"Derive the stealth private key necessary to spend a stealth payment.\";\n    }\n\n    /**\n     * Load program argument definitions.\n     * A value of -1 indicates that the number of instances is unlimited.\n     * @return  The loaded program argument definitions.\n     */\n    virtual arguments_metadata &load_arguments()\n    {\n        return get_argument_metadata()\n            .add(\"SPEND_SECRET\", 1)\n            .add(\"SHARED_SECRET\", 1);\n    }\n\n    /**\n     * Load parameter fallbacks from file or input as appropriate.\n     * @param[in]  input  The input stream for loading the parameters.\n     * @param[in]         The loaded variables.\n     */\n    virtual void load_fallbacks(std::istream &input,\n                                po::variables_map &variables)\n    {\n        const auto raw = requires_raw_input();\n        load_input(get_shared_secret_argument(), \"SHARED_SECRET\", variables, input, raw);\n    }\n\n    /**\n     * Load program option definitions.\n     * BUGBUG: see boost bug/fix: svn.boost.org/trac/boost/ticket/8009\n     * @return  The loaded program option definitions.\n     */\n    virtual options_metadata &load_options()\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            BX_CONFIG_VARIABLE \",c\",\n            value<boost::filesystem::path>(),\n            \"The path to the configuration settings file.\")(\n            \"SPEND_SECRET\",\n            value<explorer::config::ec_private>(&argument_.spend_secret)->required(),\n            \"The Base16 EC spend secret for spending a stealth payment.\")(\n            \"SHARED_SECRET\",\n            value<explorer::config::ec_private>(&argument_.shared_secret),\n            \"The Base16 EC shared secret corresponding to the SPEND_PUBKEY. If not specified the key is read from STDIN.\");\n\n        return options;\n    }\n\n    /**\n     * Set variable defaults from configuration variable values.\n     * @param[in]  variables  The loaded variables.\n     */\n    virtual void set_defaults_from_config(po::variables_map &variables)\n    {\n    }\n\n    /**\n     * Invoke the command.\n     * @param[out]  output  The input stream for the command execution.\n     * @param[out]  error   The input stream for the command execution.\n     * @return              The appropriate console return code { -1, 0, 1 }.\n     */\n    virtual console_result invoke(std::ostream &output,\n                                  std::ostream &cerr);\n\n    /* Properties */\n\n    /**\n     * Get the value of the SPEND_SECRET argument.\n     */\n    virtual explorer::config::ec_private &get_spend_secret_argument()\n    {\n        return argument_.spend_secret;\n    }\n\n    /**\n     * Set the value of the SPEND_SECRET argument.\n     */\n    virtual void set_spend_secret_argument(\n        const explorer::config::ec_private &value)\n    {\n        argument_.spend_secret = value;\n    }\n\n    /**\n     * Get the value of the SHARED_SECRET argument.\n     */\n    virtual explorer::config::ec_private &get_shared_secret_argument()\n    {\n        return argument_.shared_secret;\n    }\n\n    /**\n     * Set the value of the SHARED_SECRET argument.\n     */\n    virtual void set_shared_secret_argument(\n        const explorer::config::ec_private &value)\n    {\n        argument_.shared_secret = value;\n    }\n\n  private:\n    /**\n     * Command line argument bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct argument\n    {\n        argument()\n            : spend_secret(),\n              shared_secret()\n        {\n        }\n\n        explorer::config::ec_private spend_secret;\n        explorer::config::ec_private shared_secret;\n    } argument_;\n\n    /**\n     * Command line option bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct option\n    {\n        option()\n        {\n        }\n\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/commands/stealth-shared.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_STEALTH_SHARED_HPP\n#define BX_STEALTH_SHARED_HPP\n\n#include <cstdint>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/command.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/generated.hpp>\n#include <UChain/explorer/config/address.hpp>\n#include <UChain/explorer/config/algorithm.hpp>\n#include <UChain/explorer/config/btc.hpp>\n#include <UChain/explorer/config/byte.hpp>\n#include <UChain/explorer/config/cert_key.hpp>\n#include <UChain/explorer/config/ec_private.hpp>\n#include <UChain/explorer/config/encoding.hpp>\n#include <UChain/explorer/config/endorsement.hpp>\n#include <UChain/explorer/config/hashtype.hpp>\n#include <UChain/explorer/config/hd_key.hpp>\n#include <UChain/explorer/config/header.hpp>\n#include <UChain/explorer/config/input.hpp>\n#include <UChain/explorer/config/language.hpp>\n#include <UChain/explorer/config/output.hpp>\n#include <UChain/explorer/config/raw.hpp>\n#include <UChain/explorer/config/script.hpp>\n#include <UChain/explorer/config/signature.hpp>\n#include <UChain/explorer/config/transaction.hpp>\n#include <UChain/explorer/config/wrapper.hpp>\n#include <UChain/explorer/utility.hpp>\n\n/********* GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY **********/\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/**\n * Various localizable strings.\n */\n#define BX_STEALTH_SHARED_OUT_OF_RANGE \\\n    \"Product exceeds valid range.\"\n\n/**\n * Class to implement the stealth-shared command.\n */\nclass BCX_API stealth_shared\n    : public command\n{\n  public:\n    /**\n     * The symbolic (not localizable) command name, lower case.\n     */\n    static const char *symbol()\n    {\n        return \"stealth-shared\";\n    }\n\n    /**\n     * The member symbolic (not localizable) command name, lower case.\n     */\n    virtual const char *name()\n    {\n        return stealth_shared::symbol();\n    }\n\n    /**\n     * The localizable command category name, upper case.\n     */\n    virtual const char *category()\n    {\n        return \"STEALTH\";\n    }\n\n    /**\n     * The localizable command description.\n     */\n    virtual const char *description()\n    {\n        return \"Derive the secret shared between an ephemeral key pair and a scan key pair. Provide scan SECRET and ephemeral PUBKEY, or ephemeral SECRET and scan PUBKEY.\";\n    }\n\n    /**\n     * Load program argument definitions.\n     * A value of -1 indicates that the number of instances is unlimited.\n     * @return  The loaded program argument definitions.\n     */\n    virtual arguments_metadata &load_arguments()\n    {\n        return get_argument_metadata()\n            .add(\"SECRET\", 1)\n            .add(\"PUBKEY\", 1);\n    }\n\n    /**\n     * Load parameter fallbacks from file or input as appropriate.\n     * @param[in]  input  The input stream for loading the parameters.\n     * @param[in]         The loaded variables.\n     */\n    virtual void load_fallbacks(std::istream &input,\n                                po::variables_map &variables)\n    {\n        const auto raw = requires_raw_input();\n        load_input(get_pubkey_argument(), \"PUBKEY\", variables, input, raw);\n    }\n\n    /**\n     * Load program option definitions.\n     * BUGBUG: see boost bug/fix: svn.boost.org/trac/boost/ticket/8009\n     * @return  The loaded program option definitions.\n     */\n    virtual options_metadata &load_options()\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            BX_CONFIG_VARIABLE \",c\",\n            value<boost::filesystem::path>(),\n            \"The path to the configuration settings file.\")(\n            \"SECRET\",\n            value<explorer::config::ec_private>(&argument_.secret)->required(),\n            \"A Base16 EC private key. Either the scan or ephemeral secret.\")(\n            \"PUBKEY\",\n            value<bc::wallet::ec_public>(&argument_.pubkey),\n            \"A Base16 EC public key. Either the scan or ephemeral public key. If not specified the key is read from STDIN.\");\n\n        return options;\n    }\n\n    /**\n     * Set variable defaults from configuration variable values.\n     * @param[in]  variables  The loaded variables.\n     */\n    virtual void set_defaults_from_config(po::variables_map &variables)\n    {\n    }\n\n    /**\n     * Invoke the command.\n     * @param[out]  output  The input stream for the command execution.\n     * @param[out]  error   The input stream for the command execution.\n     * @return              The appropriate console return code { -1, 0, 1 }.\n     */\n    virtual console_result invoke(std::ostream &output,\n                                  std::ostream &cerr);\n\n    /* Properties */\n\n    /**\n     * Get the value of the SECRET argument.\n     */\n    virtual explorer::config::ec_private &get_secret_argument()\n    {\n        return argument_.secret;\n    }\n\n    /**\n     * Set the value of the SECRET argument.\n     */\n    virtual void set_secret_argument(\n        const explorer::config::ec_private &value)\n    {\n        argument_.secret = value;\n    }\n\n    /**\n     * Get the value of the PUBKEY argument.\n     */\n    virtual bc::wallet::ec_public &get_pubkey_argument()\n    {\n        return argument_.pubkey;\n    }\n\n    /**\n     * Set the value of the PUBKEY argument.\n     */\n    virtual void set_pubkey_argument(\n        const bc::wallet::ec_public &value)\n    {\n        argument_.pubkey = value;\n    }\n\n  private:\n    /**\n     * Command line argument bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct argument\n    {\n        argument()\n            : secret(),\n              pubkey()\n        {\n        }\n\n        explorer::config::ec_private secret;\n        bc::wallet::ec_public pubkey;\n    } argument_;\n\n    /**\n     * Command line option bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct option\n    {\n        option()\n        {\n        }\n\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/commands/tx-decode.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_TX_DECODE_HPP\n#define BX_TX_DECODE_HPP\n\n#include <cstdint>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/command.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/generated.hpp>\n#include <UChain/explorer/config/address.hpp>\n#include <UChain/explorer/config/algorithm.hpp>\n#include <UChain/explorer/config/btc.hpp>\n#include <UChain/explorer/config/byte.hpp>\n#include <UChain/explorer/config/cert_key.hpp>\n#include <UChain/explorer/config/ec_private.hpp>\n#include <UChain/explorer/config/encoding.hpp>\n#include <UChain/explorer/config/endorsement.hpp>\n#include <UChain/explorer/config/hashtype.hpp>\n#include <UChain/explorer/config/hd_key.hpp>\n#include <UChain/explorer/config/header.hpp>\n#include <UChain/explorer/config/input.hpp>\n#include <UChain/explorer/config/language.hpp>\n#include <UChain/explorer/config/output.hpp>\n#include <UChain/explorer/config/raw.hpp>\n#include <UChain/explorer/config/script.hpp>\n#include <UChain/explorer/config/signature.hpp>\n#include <UChain/explorer/config/transaction.hpp>\n#include <UChain/explorer/config/wrapper.hpp>\n#include <UChain/explorer/utility.hpp>\n\n/********* GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY **********/\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/**\n * Class to implement the tx-decode command.\n */\nclass BCX_API tx_decode\n    : public command\n{\n  public:\n    /**\n     * The symbolic (not localizable) command name, lower case.\n     */\n    static const char *symbol()\n    {\n        return \"tx-decode\";\n    }\n\n    /**\n     * The member symbolic (not localizable) command name, lower case.\n     */\n    virtual const char *name()\n    {\n        return tx_decode::symbol();\n    }\n\n    /**\n     * The localizable command category name, upper case.\n     */\n    virtual const char *category()\n    {\n        return \"TRANSACTION\";\n    }\n\n    /**\n     * The localizable command description.\n     */\n    virtual const char *description()\n    {\n        return \"Decode a Base16 transaction.\";\n    }\n\n    /**\n     * Load program argument definitions.\n     * A value of -1 indicates that the number of instances is unlimited.\n     * @return  The loaded program argument definitions.\n     */\n    virtual arguments_metadata &load_arguments()\n    {\n        return get_argument_metadata()\n            .add(\"TRANSACTION\", 1);\n    }\n\n    /**\n     * Load parameter fallbacks from file or input as appropriate.\n     * @param[in]  input  The input stream for loading the parameters.\n     * @param[in]         The loaded variables.\n     */\n    virtual void load_fallbacks(std::istream &input,\n                                po::variables_map &variables)\n    {\n        const auto raw = requires_raw_input();\n        load_input(get_transaction_argument(), \"TRANSACTION\", variables, input, raw);\n    }\n\n    /**\n     * Load program option definitions.\n     * BUGBUG: see boost bug/fix: svn.boost.org/trac/boost/ticket/8009\n     * @return  The loaded program option definitions.\n     */\n    virtual options_metadata &load_options()\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            BX_CONFIG_VARIABLE \",c\",\n            value<boost::filesystem::path>(),\n            \"The path to the configuration settings file.\")(\n            \"format,f\",\n            value<explorer::config::encoding>(&option_.format),\n            \"The output format. Options are 'info', 'json' and 'xml', defaults to 'info'.\")(\n            \"TRANSACTION\",\n            value<explorer::config::transaction>(&argument_.transaction),\n            \"The Base16 transaction. If not specified the transaction is read from STDIN.\");\n\n        return options;\n    }\n\n    /**\n     * Set variable defaults from configuration variable values.\n     * @param[in]  variables  The loaded variables.\n     */\n    virtual void set_defaults_from_config(po::variables_map &variables)\n    {\n    }\n\n    /**\n     * Invoke the command.\n     * @param[out]  output  The input stream for the command execution.\n     * @param[out]  error   The input stream for the command execution.\n     * @return              The appropriate console return code { -1, 0, 1 }.\n     */\n    virtual console_result invoke(std::ostream &output,\n                                  std::ostream &cerr);\n\n    /* Properties */\n\n    /**\n     * Get the value of the TRANSACTION argument.\n     */\n    virtual explorer::config::transaction &get_transaction_argument()\n    {\n        return argument_.transaction;\n    }\n\n    /**\n     * Set the value of the TRANSACTION argument.\n     */\n    virtual void set_transaction_argument(\n        const explorer::config::transaction &value)\n    {\n        argument_.transaction = value;\n    }\n\n    /**\n     * Get the value of the format option.\n     */\n    virtual explorer::config::encoding &get_format_option()\n    {\n        return option_.format;\n    }\n\n    /**\n     * Set the value of the format option.\n     */\n    virtual void set_format_option(\n        const explorer::config::encoding &value)\n    {\n        option_.format = value;\n    }\n\n  private:\n    /**\n     * Command line argument bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct argument\n    {\n        argument()\n            : transaction()\n        {\n        }\n\n        explorer::config::transaction transaction;\n    } argument_;\n\n    /**\n     * Command line option bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct option\n    {\n        option()\n            : format()\n        {\n        }\n\n        explorer::config::encoding format;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/commands/validate-tx.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_VALIDATE_TX_HPP\n#define BX_VALIDATE_TX_HPP\n\n#include <cstdint>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/command.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/generated.hpp>\n#include <UChain/explorer/config/address.hpp>\n#include <UChain/explorer/config/algorithm.hpp>\n#include <UChain/explorer/config/btc.hpp>\n#include <UChain/explorer/config/byte.hpp>\n#include <UChain/explorer/config/cert_key.hpp>\n#include <UChain/explorer/config/ec_private.hpp>\n#include <UChain/explorer/config/encoding.hpp>\n#include <UChain/explorer/config/endorsement.hpp>\n#include <UChain/explorer/config/hashtype.hpp>\n#include <UChain/explorer/config/hd_key.hpp>\n#include <UChain/explorer/config/header.hpp>\n#include <UChain/explorer/config/input.hpp>\n#include <UChain/explorer/config/language.hpp>\n#include <UChain/explorer/config/output.hpp>\n#include <UChain/explorer/config/raw.hpp>\n#include <UChain/explorer/config/script.hpp>\n#include <UChain/explorer/config/signature.hpp>\n#include <UChain/explorer/config/transaction.hpp>\n#include <UChain/explorer/config/wrapper.hpp>\n#include <UChain/explorer/utility.hpp>\n\n/********* GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY **********/\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/**\n * Various localizable strings.\n */\n#define BX_VALIDATE_TX_VALID \\\n    \"The transaction is valid.\"\n#define BX_VALIDATE_TX_UNCONFIRMED_INPUTS \\\n    \"The transaction is valid, with unconfirmed inputs at index: %1%.\"\n\n/**\n * Class to implement the validate-tx command.\n */\nclass BCX_API validate_tx\n    : public command\n{\n  public:\n    /**\n     * The symbolic (not localizable) command name, lower case.\n     */\n    static const char *symbol()\n    {\n        return \"validate-tx\";\n    }\n\n    /**\n     * The symbolic (not localizable) former command name, lower case.\n     */\n    static const char *formerly()\n    {\n        return \"validtx\";\n    }\n\n    /**\n     * The member symbolic (not localizable) command name, lower case.\n     */\n    virtual const char *name()\n    {\n        return validate_tx::symbol();\n    }\n\n    /**\n     * The localizable command category name, upper case.\n     */\n    virtual const char *category()\n    {\n        return \"ONLINE\";\n    }\n\n    /**\n     * The localizable command description.\n     */\n    virtual const char *description()\n    {\n        return \"Determine if a transaction is valid for submission to the blockchain. Requires a Libbitcoin/Obelisk server connection.\";\n    }\n\n    /**\n     * Load program argument definitions.\n     * A value of -1 indicates that the number of instances is unlimited.\n     * @return  The loaded program argument definitions.\n     */\n    virtual arguments_metadata &load_arguments()\n    {\n        return get_argument_metadata()\n            .add(\"TRANSACTION\", 1);\n    }\n\n    /**\n     * Load parameter fallbacks from file or input as appropriate.\n     * @param[in]  input  The input stream for loading the parameters.\n     * @param[in]         The loaded variables.\n     */\n    virtual void load_fallbacks(std::istream &input,\n                                po::variables_map &variables)\n    {\n        const auto raw = requires_raw_input();\n        load_input(get_transaction_argument(), \"TRANSACTION\", variables, input, raw);\n    }\n\n    /**\n     * Load program option definitions.\n     * BUGBUG: see boost bug/fix: svn.boost.org/trac/boost/ticket/8009\n     * @return  The loaded program option definitions.\n     */\n    virtual options_metadata &load_options()\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            BX_CONFIG_VARIABLE \",c\",\n            value<boost::filesystem::path>(),\n            \"The path to the configuration settings file.\")(\n            \"TRANSACTION\",\n            value<explorer::config::transaction>(&argument_.transaction),\n            \"The Base16 transaction. If not specified the transaction is read from STDIN.\");\n\n        return options;\n    }\n\n    /**\n     * Set variable defaults from configuration variable values.\n     * @param[in]  variables  The loaded variables.\n     */\n    virtual void set_defaults_from_config(po::variables_map &variables)\n    {\n    }\n\n    /**\n     * Invoke the command.\n     * @param[out]  output  The input stream for the command execution.\n     * @param[out]  error   The input stream for the command execution.\n     * @return              The appropriate console return code { -1, 0, 1 }.\n     */\n    virtual console_result invoke(std::ostream &output,\n                                  std::ostream &cerr);\n\n    /* Properties */\n\n    /**\n     * Get the value of the TRANSACTION argument.\n     */\n    virtual explorer::config::transaction &get_transaction_argument()\n    {\n        return argument_.transaction;\n    }\n\n    /**\n     * Set the value of the TRANSACTION argument.\n     */\n    virtual void set_transaction_argument(\n        const explorer::config::transaction &value)\n    {\n        argument_.transaction = value;\n    }\n\n  private:\n    /**\n     * Command line argument bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct argument\n    {\n        argument()\n            : transaction()\n        {\n        }\n\n        explorer::config::transaction transaction;\n    } argument_;\n\n    /**\n     * Command line option bound variables.\n     * Uses cross-compiler safe constructor-based zeroize.\n     * Zeroize for unit test consistency with program_options initialization.\n     */\n    struct option\n    {\n        option()\n        {\n        }\n\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/config/address.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_ADDRESS_HPP\n#define BX_ADDRESS_HPP\n\n#include <iostream>\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n/**\n * Serialization helper to convert between base58 string and bitcoin payment\n * and stealth address.\n */\nclass BCX_API address\n{\n  public:\n    /**\n     * Default constructor.\n     */\n    address()\n    {\n    }\n\n    /**\n     * Initialization constructor.\n     * @param[in]  base58  The value to initialize with.\n     */\n    address(const std::string &base58);\n\n    /**\n     * Overload cast to internal type.\n     * @return  This object's value cast to internal type reference.\n     */\n    operator const std::string &() const;\n\n    /**\n     * Overload stream in. Throws if input is invalid.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    address &argument);\n\n  private:\n    /**\n     * The state of this object.\n     */\n    std::string value_;\n};\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/config/algorithm.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_ALGORITHM_HPP\n#define BX_ALGORITHM_HPP\n\n#include <iostream>\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n/**\n * Serialization helper to convert between algorithm and string.\n */\nclass BCX_API algorithm\n{\n  public:\n    /**\n     * Default constructor.\n     */\n    algorithm();\n\n    /**\n     * Initialization constructor.\n     * @param[in]  token  The value to initialize with.\n     */\n    algorithm(const std::string &token);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  algorithms  The value to initialize with.\n     */\n    algorithm(bc::wallet::select_outputs::algorithm &algorithm);\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    algorithm(const algorithm &other);\n\n    /**\n     * Overload cast to internal type.\n     * @return  This object's value cast to internal type.\n     */\n    operator const bc::wallet::select_outputs::algorithm() const;\n\n    /**\n     * Overload stream in. Throws if input is invalid.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    algorithm &argument);\n\n    /**\n     * Overload stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const algorithm &argument);\n\n  private:\n    /**\n     * The state of this object.\n     */\n    bc::wallet::select_outputs::algorithm value_;\n};\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/config/btc.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_BTC_HPP\n#define BX_BTC_HPP\n\n#include <cstdint>\n#include <iostream>\n#include <UChain/explorer/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n/**\n * Serialization helper to convert between btc and satoshi.\n */\nclass BCX_API btc\n{\n  public:\n    /**\n     * Default constructor.\n     */\n    btc();\n\n    /**\n     * Initialization constructor.\n     * @param[in]  btc  The number of btc to initialize with.\n     */\n    btc(const std::string &btc);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  satoshi  The number of satoshi to initialize with.\n     */\n    btc(uint64_t satoshi);\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    btc(const btc &other);\n\n    /**\n     * Return a reference to the data member cast as satoshi.\n     * @return  A reference to the object's internal data.\n     */\n    operator uint64_t() const;\n\n    /**\n     * Overload stream in. Throws if input is invalid.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    btc &argument);\n\n    /**\n     * Overload stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const btc &argument);\n\n  private:\n    /**\n     * The state of this object's number of satoshis.\n     */\n    uint64_t value_;\n};\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/config/byte.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_BYTE_HPP\n#define BX_BYTE_HPP\n\n#include <iostream>\n#include <string>\n#include <cstdint>\n#include <UChain/explorer/define.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n/**\n * Serialization helper to convert between decimal string and uint8_t.\n */\nclass BCX_API byte\n{\n  public:\n    /**\n     * Default constructor.\n     */\n    byte();\n\n    /**\n     * Initialization constructor.\n     * @param[in]  byte  The value to initialize with.\n     */\n    byte(uint8_t byte);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  decimal  The value to initialize with.\n     */\n    byte(const std::string &decimal);\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    byte(const byte &other);\n\n    /**\n     * Overload cast to internal type.\n     * @return  This object's value cast to internal type.\n     */\n    operator uint8_t() const;\n\n    /**\n     * Overload stream in. If input is invalid sets no bytes in argument.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    byte &argument);\n\n    /**\n     * Overload stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const byte &argument);\n\n  private:\n    /**\n     * The state of this object.\n     */\n    uint8_t value_;\n};\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/config/cert_key.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_CERTIFICATE_HPP\n#define BX_CERTIFICATE_HPP\n\n#include <iostream>\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n/**\n * Serialization helper to convert between data_chunk and Z85 cert key.\n */\nclass BCX_API cert_key\n{\n  public:\n    /**\n     * Default constructor.\n     */\n    cert_key();\n\n    /**\n     * Initialization constructor.\n     * @param[in]  base85  The value to initialize with.\n     */\n    cert_key(const std::string &base85);\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    cert_key(const cert_key &other);\n\n    /**\n     * Convert internal type to text string.\n     * Returns empty string if not initialized.\n     * @return  This object's value cast to a Z85 encoded string.\n     */\n    std::string get_base85() const;\n\n    /**\n     * Overload cast to internal type.\n     * @return  This object's value cast to internal type.\n     */\n    operator const data_chunk &() const;\n\n    /**\n     * Overload cast to generic data reference.\n     * @return  This object's value cast to a generic data reference.\n     */\n    operator data_slice() const;\n\n    /**\n     * Overload stream in. Throws if input is invalid.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    cert_key &argument);\n\n    /**\n     * Overload stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const cert_key &argument);\n\n  private:\n    /**\n     * The state of this object.\n     */\n    data_chunk value_;\n};\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/config/ec_private.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_EC_PRIVATE_HPP\n#define BX_EC_PRIVATE_HPP\n\n#include <iostream>\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n/**\n * Serialization helper to convert between base16 string and ec_secret.\n */\nclass BCX_API ec_private\n{\n  public:\n    /**\n     * Default constructor.\n     */\n    ec_private()\n    {\n    }\n\n    /**\n     * Initialization constructor.\n     * @param[in]  hexcode  The value to initialize with.\n     */\n    ec_private(const std::string &hexcode);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  secret  The value to initialize with.\n     */\n    ec_private(const ec_secret &secret);\n\n    /**\n     * Overload cast to internal type.\n     * @return  This object's value cast to internal type.\n     */\n    operator const ec_secret &() const;\n\n    /**\n     * Overload stream in. Throws if input is invalid.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    ec_private &argument);\n\n    /**\n     * Overload stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const ec_private &argument);\n\n  private:\n    /**\n     * The state of this object.\n     */\n    ec_secret value_;\n};\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/config/encoding.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_ENCODING_HPP\n#define BX_ENCODING_HPP\n\n#include <iostream>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n/**\n * Serialization helper to convert between text and encoding engine.\n */\nclass BCX_API encoding\n{\n  public:\n    /**\n     * Default constructor, sets encoding_engine::info.\n     */\n    encoding();\n\n    /**\n     * Initialization constructor.\n     * @param[in]  token  The value to initialize with.\n     */\n    encoding(const std::string &token);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  engine  The value to initialize with.\n     */\n    encoding(encoding_engine engine);\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    encoding(const encoding &other);\n\n    /**\n     * Return a reference to the data member.\n     * @return  A reference to the object's internal data.\n     */\n    operator encoding_engine() const;\n\n    /**\n     * Overload stream in. Throws if input is invalid.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    encoding &argument);\n\n    /**\n     * Overload stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const encoding &argument);\n\n  private:\n    /**\n     * The state of this object's encoding engine data.\n     */\n    encoding_engine value_;\n};\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/config/endorsement.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_ENDORSEMENT_HPP\n#define BX_ENDORSEMENT_HPP\n\n#include <array>\n#include <iostream>\n#include <string>\n#include <cstdint>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n/**\n * Serialization helper to convert between endorsement string and data_chunk.\n */\nclass BCX_API endorsement\n{\n  public:\n    /**\n     * Default constructor.\n     */\n    endorsement();\n\n    /**\n     * Initialization constructor.\n     * @param[in]  hexcode  The value to initialize with.\n     */\n    endorsement(const std::string &hexcode);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  value  The value to initialize with.\n     */\n    endorsement(const data_chunk &value);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  value  The value to initialize with.\n     */\n    template <size_t Size>\n    endorsement(const byte_array<Size> &value)\n        : value_(value.begin(), value.end())\n    {\n    }\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    endorsement(const endorsement &other);\n\n    /**\n     * Overload cast to internal type.\n     * @return  This object's value cast to internal type.\n     */\n    operator const data_chunk &() const;\n\n    /**\n     * Overload cast to generic data reference.\n     * @return  This object's value cast to a generic data reference.\n     */\n    operator data_slice() const;\n\n    /**\n     * Overload stream in. If input is invalid sets no bytes in argument.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    endorsement &argument);\n\n    /**\n     * Overload stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const endorsement &argument);\n\n  private:\n    /**\n     * The state of this object.\n     */\n    data_chunk value_;\n};\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/config/hashtype.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_HASHTYPE_HPP\n#define BX_HASHTYPE_HPP\n\n#include <iostream>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n/**\n * Serialization helper to convert between text and signature hash type.\n */\nclass BCX_API hashtype\n{\n  public:\n    /**\n     * Default constructor, sets sighash::single.\n     */\n    hashtype();\n\n    /**\n     * Initialization constructor.\n     * @param[in]  token  The value to initialize with.\n     */\n    hashtype(const std::string &token);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  value  The value to initialize with.\n     */\n    hashtype(const chain::signature_hash_algorithm &value);\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    hashtype(const hashtype &other);\n\n    /**\n     * Return a reference to the data member.\n     * @return  A reference to the object's internal data.\n     */\n    operator chain::signature_hash_algorithm() const;\n\n    /**\n     * Overload stream in. Throws if input is invalid.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    hashtype &argument);\n\n    /**\n     * Overload stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const hashtype &argument);\n\n  private:\n    /**\n     * The state of this object's sighash engine data.\n     */\n    chain::signature_hash_algorithm value_;\n};\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/config/hd_key.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_HD_KEY_HPP\n#define BX_HD_KEY_HPP\n\n#include <cstdint>\n#include <iostream>\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n/**\n * Serialization helper to serialize both public and private hd keys.\n */\nclass BCX_API hd_key\n{\n  public:\n    /**\n     * Default constructor.\n     */\n    hd_key()\n    {\n    }\n\n    /**\n     * Initialization constructor.\n     * @param[in]  base58  The value to initialize with.\n     */\n    hd_key(const std::string &base58);\n\n    /**\n     * Get the version/prefix of the key value.\n     * @return  The version of the key.\n     */\n    uint32_t version() const;\n\n    /**\n     * Overload cast to internal type.\n     * @return  This object's value cast to internal type.\n     */\n    operator const bc::wallet::hd_key &() const;\n\n    /**\n     * Overload stream in. Throws if input is invalid.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input, hd_key &argument);\n\n  private:\n    /**\n     * The private key state of this object.\n     */\n    bc::wallet::hd_key value_;\n};\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/config/header.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_HEADER_HPP\n#define BX_HEADER_HPP\n\n#include <iostream>\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n/**\n * Serialization helper to convert between serialized and deserialized satoshi\n * header.\n */\nclass BCX_API header\n{\n  public:\n    /**\n     * Default constructor.\n     */\n    header();\n\n    /**\n     * Initialization constructor.\n     * @param[in]  hexcode  The value to initialize with.\n     */\n    header(const std::string &hexcode);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  value  The value to initialize with.\n     */\n    header(const chain::header &value);\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    header(const header &other);\n\n    /**\n     * Overload cast to internal type.\n     * @return  This object's value cast to internal type.\n     */\n    operator const chain::header &() const;\n\n    /**\n     * Overload stream in. Throws if input is invalid.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    header &argument);\n\n    /**\n     * Overload stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const header &argument);\n\n  private:\n    /**\n     * The state of this object's header data.\n     */\n    chain::header value_;\n};\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/config/input.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_INPUT_HPP\n#define BX_INPUT_HPP\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n/**\n * Serialization helper stub for tx_input_type.\n */\nclass BCX_API input\n{\n  public:\n    /**\n     * Default constructor.\n     */\n    input();\n\n    /**\n     * Initialization constructor.\n     * @param[in]  tuple  The value to initialize with.\n     */\n    input(const std::string &tuple);\n\n    /**\n     * Initialization constructor. Only the point is retained.\n     * @param[in]  value  The value to initialize with.\n     */\n    input(const tx_input_type &value);\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    input(const input &other);\n\n    /**\n     * Initialization constructor. Aspects of the input other than the point\n     * are defaulted.\n     * @param[in]  value  The value to initialize with.\n     */\n    input(const chain::input_point &value);\n\n    /**\n     * Overload cast to internal type.\n     * @return  This object's value cast to internal type.\n     */\n    operator const tx_input_type &() const;\n\n    /**\n     * Overload stream in. Throws if input is invalid.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &stream,\n                                    input &argument);\n\n    /**\n     * Overload stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const input &argument);\n\n  private:\n    /**\n     * The state of this object.\n     */\n    tx_input_type value_;\n};\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/config/language.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_BIP39_LANGUAGE_HPP\n#define BX_BIP39_LANGUAGE_HPP\n\n#include <iostream>\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n/**\n * Serialization helper to convert between dictionary and string.\n */\nclass BCX_API language\n{\n  public:\n    /**\n     * Default constructor.\n     */\n    language();\n\n    /**\n     * Initialization constructor.\n     * @param[in]  token  The value to initialize with.\n     */\n    language(const std::string &token);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  languages  The value to initialize with.\n     */\n    language(bc::wallet::dictionary_list &languages);\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    language(const language &other);\n\n    /**\n     * Overload cast to internal type.\n     * @return  This object's value cast to internal type.\n     */\n    operator const bc::wallet::dictionary_list() const;\n\n    /**\n     * Overload stream in. Throws if input is invalid.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    language &argument);\n\n    /**\n     * Overload stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const language &argument);\n\n  private:\n    /**\n     * The state of this object.\n     */\n    bc::wallet::dictionary_list value_;\n};\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/config/output.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_OUTPUT_HPP\n#define BX_OUTPUT_HPP\n\n#include <iostream>\n#include <cstdint>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n/**\n * Serialization helper to convert between a base58-string:number and\n * a vector of tx_output_type.\n */\nclass BCX_API output\n{\n  public:\n    /**\n     * Default constructor.\n     */\n    output();\n\n    /**\n     * Initialization constructor.\n     * @param[in]  tuple  The value to initialize with.\n     */\n    output(const std::string &tuple);\n\n    /// Parsed properties\n    uint64_t amount() const;\n    uint8_t version() const;\n    const chain::script &script() const;\n    const short_hash &pay_to_hash() const;\n    const data_chunk &ephemeral_data() const;\n\n    /**\n     * Overload stream in. Throws if input is invalid.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    output &argument);\n\n  private:\n    /**\n     * The transaction output state of this object.\n     * This data is translated to an output given expected version information.\n     */\n    uint64_t amount_;\n    uint8_t version_;\n    chain::script script_;\n    short_hash pay_to_hash_;\n    data_chunk ephemeral_data_;\n};\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/config/point.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_POINT_HPP\n#define BX_POINT_HPP\n\n#include <iostream>\n#include <sstream>\n#include <cstdint>\n#include <string>\n#include <vector>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/utility.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n/**\n * Serialization helper to convert between text and an output_point.\n */\nclass BCX_API point\n{\n  public:\n    /**\n     * Default constructor.\n     */\n    point();\n\n    /**\n     * Initialization constructor.\n     * @param[in]  tuple  The value to initialize with.\n     */\n    point(const std::string &tuple);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  value  The value to initialize with.\n     */\n    point(const chain::output_point &value);\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    point(const point &other);\n\n    /**\n     * Overload cast to internal type.\n     * @return  This object's value cast to internal type.\n     */\n    operator const chain::output_point &() const;\n\n    /**\n     * Overload stream in. Throws if input is invalid.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    point &argument);\n\n    /**\n     * Overload stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const point &argument);\n\n  private:\n    /**\n     * The state of this object.\n     */\n    chain::output_point value_;\n};\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/config/raw.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_RAW_HPP\n#define BX_RAW_HPP\n\n#include <iostream>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n/**\n * Serialization helper to convert between a byte stream and data_chunk.\n */\nclass BCX_API raw\n{\n  public:\n    /**\n     * Default constructor.\n     */\n    raw();\n\n    /**\n     * Initialization constructor.\n     * @param[in]  text  The value to initialize with.\n     */\n    raw(const std::string &text);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  value  The value to initialize with.\n     */\n    raw(const data_chunk &value);\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    raw(const raw &other);\n\n    /**\n     * Overload cast to internal type.\n     * @return  This object's value cast to internal type.\n     */\n    operator const data_chunk &() const;\n\n    /**\n     * Overload cast to generic data reference.\n     * @return  This object's value cast to a generic data reference.\n     */\n    operator data_slice() const;\n\n    /**\n     * Overload stream in. Throws if input is invalid.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    raw &argument);\n\n    /**\n     * Overload stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const raw &argument);\n\n  private:\n    /**\n     * The state of this object's raw data.\n     */\n    data_chunk value_;\n};\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/config/script.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_SCRIPT_HPP\n#define BX_SCRIPT_HPP\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n/**\n * Serialization helper to convert between base16/raw script and script_type.\n */\nclass BCX_API script\n{\n  public:\n    /**\n     * Default constructor.\n     */\n    script();\n\n    /**\n     * Initialization constructor.\n     * @param[in]  mnemonic  The value to initialize with.\n     */\n    script(const std::string &mnemonic);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  value  The value to initialize with.\n     */\n    script(const chain::script &value);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  value  The value to initialize with.\n     */\n    script(const data_chunk &value);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  tokens  The mnemonic tokens to initialize with.\n     */\n    script(const std::vector<std::string> &tokens);\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    script(const script &other);\n\n    /**\n     * Serialize the script to bytes according to the wire protocol.\n     * @return  The byte serialized copy of the script.\n     */\n    const bc::data_chunk to_data() const;\n\n    /**\n     * Return a pretty-printed copy of the script.\n     * @return  A mnemonic-printed copy of the internal script.\n     */\n    const std::string to_string() const;\n\n    /**\n     * Overload cast to internal type.\n     * @return  This object's value cast to internal type.\n     */\n    operator const chain::script &() const;\n\n    /**\n     * Overload stream in. Throws if input is invalid.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    script &argument);\n\n    /**\n     * Overload stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const script &argument);\n\n  private:\n    /**\n     * The state of this object.\n     */\n    chain::script value_;\n};\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/config/signature.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_SIGNATURE_HPP\n#define BX_SIGNATURE_HPP\n\n#include <array>\n#include <iostream>\n#include <string>\n#include <cstdint>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n/**\n * Serialization helper to convert between string and message_signature.\n */\nclass BCX_API signature\n{\n  public:\n    /**\n     * Default constructor.\n     */\n    signature();\n\n    /**\n     * Initialization constructor.\n     * @param[in]  hexcode  The value to initialize with.\n     */\n    signature(const std::string &hexcode);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  value  The value to initialize with.\n     */\n    signature(const bc::wallet::message_signature &value);\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    signature(const signature &other);\n\n    /**\n     * Overload cast to internal type.\n     * @return  This object's value cast to internal type.\n     */\n    operator const bc::wallet::message_signature &() const;\n\n    /**\n     * Overload stream in. If input is invalid sets no bytes in argument.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    signature &argument);\n\n    /**\n     * Overload stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const signature &argument);\n\n  private:\n    /**\n     * The state of this object.\n     */\n    bc::wallet::message_signature value_;\n};\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/config/transaction.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_TRANSACTION_HPP\n#define BX_TRANSACTION_HPP\n\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n/**\n * Serialization helper to convert between serialized and deserialized satoshi\n * transaction.\n */\nclass BCX_API transaction\n{\n  public:\n    /**\n     * Default constructor.\n     */\n    transaction();\n\n    /**\n     * Initialization constructor.\n     * @param[in]  hexcode  The value to initialize with.\n     */\n    transaction(const std::string &hexcode);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  value  The value to initialize with.\n     */\n    transaction(const tx_type &value);\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    transaction(const transaction &other);\n\n    /**\n     * Return a reference to the data member.\n     * @return  A reference to the object's internal data.\n     */\n    tx_type &data();\n\n    /**\n     * Overload cast to internal type.\n     * @return  This object's value cast to internal type.\n     */\n    operator const tx_type &() const;\n\n    /**\n     * Overload stream in. Throws if input is invalid.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    transaction &argument);\n\n    /**\n     * Overload stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const transaction &argument);\n\n  private:\n    /**\n     * The state of this object's transaction data.\n     */\n    tx_type value_;\n};\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/config/wrapper.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_WRAPPER_HPP\n#define BX_WRAPPER_HPP\n\n#include <iostream>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n/**\n * Serialization helper to convert between a checksum'd wrapper and data_chunk.\n */\nclass BCX_API wrapper\n{\n  public:\n    /**\n     * Default constructor.\n     */\n    wrapper();\n\n    /**\n     * Initialization constructor.\n     *\n     * @param[in]  wrapped  The value to initialize with.\n     */\n    wrapper(const std::string &wrapped);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  wrapped  The wrapped value to initialize with.\n     */\n    wrapper(const data_chunk &wrapped);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  wrapped  The wrapped value to initialize with.\n     */\n    wrapper(const bc::wallet::wrapped_data &wrapped);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  address  The payment address to initialize with.\n     */\n    wrapper(const bc::wallet::payment_address &address);\n\n    /**\n     * Initialization constructor.\n     * @param[in]  version  The version for the new wrapped value.\n     * @param[in]  payload  The payload for the new wrapped value.\n     */\n    wrapper(uint8_t version, const data_chunk &payload);\n\n    /**\n     * Copy constructor.\n     * @param[in]  other  The object to copy into self on construct.\n     */\n    wrapper(const wrapper &other);\n\n    /**\n     * Serialize the wrapper to bytes according to the wire protocol.\n     * @return  The byte serialized copy of the wrapper.\n     */\n    const bc::data_chunk to_data() const;\n\n    /**\n     * Overload cast to internal type.\n     * @return  This object's value cast to internal type.\n     */\n    operator const bc::wallet::wrapped_data &() const;\n\n    /**\n     * Overload stream in. Throws if input is invalid.\n     * @param[in]   input     The input stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The input stream reference.\n     */\n    friend std::istream &operator>>(std::istream &input,\n                                    wrapper &argument);\n\n    /**\n     * Overload stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output,\n                                    const wrapper &argument);\n\n  private:\n    /**\n     * The state of this object's data.\n     */\n    bc::wallet::wrapped_data value_;\n};\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/define.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_DEFINE_HPP\n#define BX_DEFINE_HPP\n\n#include <cstdint>\n#include <cstddef>\n#include <boost/dynamic_bitset.hpp>\n#include <boost/format.hpp>\n#include <boost/program_options.hpp>\n#include <jsoncpp/json/json.h>\n#include <UChain/client.hpp>\n\n// We use the generic helper definitions in libbitcoin to define BCX_API\n// and BCX_INTERNAL. BCX_API is used for the public API symbols. It either DLL\n// imports or DLL exports (or does nothing for static build) BCX_INTERNAL is\n// used for non-api symbols.\n\n#if defined BCX_STATIC\n#define BCX_API\n#define BCX_INTERNAL\n#elif defined BCX_DLL\n#define BCX_API BC_HELPER_DLL_EXPORT\n#define BCX_INTERNAL BC_HELPER_DLL_LOCAL\n#else\n#define BCX_API BC_HELPER_DLL_IMPORT\n#define BCX_INTERNAL BC_HELPER_DLL_LOCAL\n#endif\n\n/**\n * The name of this program.\n */\n#define BX_PROGRAM_NAME \"uc-cli\"\n\n/**\n * Delimiter for use in word splitting serialized input and output points.\n */\n#define BX_TX_POINT_DELIMITER \":\"\n\n/**\n * Default delimiter for use in word splitting and joining operations.\n */\n#define BX_SENTENCE_DELIMITER \" \"\n\n/**\n * Environment variable prefix for integrated environment variables.\n */\n#define BX_ENVIRONMENT_VARIABLE_PREFIX \"UC_\"\n\n/**\n * Conventional command line argument sentinel for indicating that a file\n * should be read from STDIN or written to STDOUT.\n */\n#define BX_STDIO_PATH_SENTINEL \"-\"\n\n/**\n * Show in uncompleted commands.\n */\n#define IN_DEVELOPING \"The command is in develeping, replace it with original command.\"\n\n/**\n * Show Wallet messages.\n */\n#define BX_WALLET_NAME \"Wallet name just for local.\"\n#define BX_WALLET_AUTH \"Wallet password(authorization) just for local.\"\n\n/**\n * Show Wallet messages.\n */\n#define BX_ADMIN_NAME \"Administrator .(required when administrator_required is true)\"\n#define BX_ADMIN_AUTH \"Administrator password.\"\n\n#define BX_TOKEN_OFFERING_CURVE \"The token offering model by block height. \\\n    TYPE=1 - fixed quantity model; TYPE=2 - specify parameters; \\\n    LQ - Locked Quantity each period; \\\n    LP - Locked Period, numeber of how many blocks; \\\n    UN - Unlock Number, number of how many LPs; \\\n    eg: \\\n        TYPE=1;LQ=9000;LP=60000;UN=3  \\\n        TYPE=2;LQ=9000;LP=60000;UN=3;UC=20000,20000,20000;UQ=3000,3000,3000 \\\n    defaults to disable. \"\n\n/**\n * Space-saving namespaces.\n */\nnamespace ph = std::placeholders;\nnamespace po = boost::program_options;\n\n/**\n * Space-saving, clarifying and/or differentiating external type equivalents.\n */\ntypedef boost::format format;\ntypedef bc::chain::transaction tx_type;\ntypedef bc::chain::input tx_input_type;\ntypedef bc::chain::output tx_output_type;\n\n/**\n * The minimum safe length of a seed in bits (multiple of 8).\n */\nBC_CONSTEXPR size_t minimum_seed_bits = 128;\n\n/**\n * The minimum safe length of a seed in bytes (16).\n */\nBC_CONSTEXPR size_t minimum_seed_size = minimum_seed_bits / bc::byte_bits;\n\n/**\n * Suppported output encoding engines.\n */\nenum class encoding_engine\n{\n    info,\n    json,\n    xml\n};\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/dispatch.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_DISPATCH_HPP\n#define BX_DISPATCH_HPP\n\n#include <iostream>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChainApp/ucd/server_node.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\n\n/**\n * Dispatch the command with the raw arguments as provided on the command line.\n * @param[in]  argc    The number of elements in the argv array.\n * @param[in]  argv    The array of arguments, including the process.\n * @param[in]  input   The input stream (e.g. STDIO).\n * @param[in]  output  The output stream (e.g. STDOUT).\n * @param[in]  error   The error stream (e.g. STDERR).\n * @return             The appropriate console return code { -1, 0, 1 }.\n */\nBCX_API console_result dispatch(int argc, const char *argv[],\n                                std::istream &input, std::ostream &output, std::ostream &error);\n\n/**\n * Invoke the command identified by the specified arguments.\n * The first argument in the array is the command symbolic name.\n * @param[in]  argc   The number of elements in the argv parameter.\n * @param[in]  argv   Array of command line arguments excluding the process.\n * @param[in]  input   The input stream (e.g. STDIO).\n * @param[in]  output  The output stream (e.g. STDOUT).\n * @param[in]  error   The error stream (e.g. STDERR).\n * @return            The appropriate console return code { -1, 0, 1 }.\n */\nBCX_API console_result dispatch_command(int argc, const char *argv[],\n                                        std::istream &input, std::ostream &output, std::ostream &error);\n\n/**\n * Invoke the command identified by the specified arguments.\n * The first argument in the array is the command symbolic name.\n * @param[in]  argc   The number of elements in the argv parameter.\n * @param[in]  argv   Array of command line arguments excluding the process.\n * @param[in]  node server_node instance.\n * @param[in]  command version, defaults to v1.\n * @return            The appropriate console return code { -1, 0, 1 }.\n */\nBCX_API console_result dispatch_command(int argc, const char *argv[],\n                                        Json::Value &jv_output,\n                                        bc::server::server_node &node, uint8_t api_version = 1);\n\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/display.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_DISPLAY_HPP\n#define BX_DISPLAY_HPP\n\n#include <iostream>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/command.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\n\n/**\n * Write the list of all command names to a stream.\n * @param[in]  stream  The stream to write into.\n */\nBCX_API void display_command_names(std::ostream &stream);\n\n/**\n * Write an error message indicating that the client-server connection failed.\n * @param[in]  stream  The stream to write into.\n * @param[in]  url     The server url.\n */\nBCX_API void display_connection_failure(std::ostream &stream,\n                                        const bc::config::endpoint &url);\n\n/**\n * Write an error message to a stream that the specified explorer command\n * name has been deprecated in favor of another, or does not exist.\n * @param[in]  stream       The stream to write into.\n * @param[in]  command      The value that was attempted as a command.\n * @param[in]  superseding  The superseding command, defaults to empty.\n */\nBCX_API void display_invalid_command(std::ostream &stream,\n                                     const std::string &command, const std::string &superseding = \"\");\n\n/**\n * Write an error message to a stream that indicates what is wrong with\n * initialization in terms of command line, config settings file, environment.\n * @param[in]  stream   The stream to write into.\n * @param[in]  message  The message to write.\n */\nBCX_API void display_invalid_parameter(std::ostream &stream,\n                                       const std::string &message);\n\n/**\n * Write usage instructions (help) to a tream for the explorer command line.\n * @param[in]  stream   The stream to write into.\n */\nBCX_API void display_usage(std::ostream &stream);\n\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/generated.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_GENERATED_HPP\n#define BX_GENERATED_HPP\n\n#include <functional>\n#include <memory>\n#include <string>\n#include <UChain/explorer/command.hpp>\n#include <UChain/explorer/commands/fetch-history.hpp>\n#include <UChain/explorer/commands/fetch-stealth.hpp>\n#include <UChain/explorer/commands/help.hpp>\n#include <UChain/explorer/commands/send-tx.hpp>\n#include <UChain/explorer/commands/settings.hpp>\n#include <UChain/explorer/commands/stealth-decode.hpp>\n#include <UChain/explorer/commands/stealth-encode.hpp>\n#include <UChain/explorer/commands/stealth-public.hpp>\n#include <UChain/explorer/commands/stealth-secret.hpp>\n#include <UChain/explorer/commands/stealth-shared.hpp>\n#include <UChain/explorer/commands/tx-decode.hpp>\n#include <UChain/explorer/commands/validate-tx.hpp>\n#include <UChain/explorer/define.hpp>\n\n/********* GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY **********/\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\n\n/**\n * Various shared localizable strings.\n */\n#define BX_COMMANDS_HEADER \\\n    \"Info: The commands are:\"\n#define BX_COMMANDS_HOME_PAGE \\\n    \"UC home page:\"\n#define BX_COMMAND_USAGE \\\n    \"Usage: help COMMAND\"\n#define BX_CONFIG_DESCRIPTION \\\n    \"The path to the configuration settings file.\"\n#define BX_CONNECTION_FAILURE \\\n    \"Could not connect to server: %1%\"\n#define BX_DEPRECATED_COMMAND \\\n    \"The '%1%' command has been replaced by '%2%'.\"\n#define BX_HELP_DESCRIPTION \\\n    \"Get a description and instructions for this command.\"\n#define BX_INVALID_COMMAND \\\n    \"'%1%' is not a command. Enter 'help' for a list of commands.\"\n#define BX_INVALID_PARAMETER \\\n    \"%1%\"\n#define BX_PRINTER_ARGUMENT_TABLE_HEADER \\\n    \"Arguments (positional):\"\n#define BX_PRINTER_DESCRIPTION_FORMAT \\\n    \"Info: %1%\"\n#define BX_PRINTER_OPTION_TABLE_HEADER \\\n    \"Options (named):\"\n#define BX_PRINTER_USAGE_FORMAT \\\n    \"Usage: %1% %2% %3%\"\n#define BX_PRINTER_VALUE_TEXT \\\n    \"VALUE\"\n#define BX_VERSION_MESSAGE \\\n    \"Version: %1%\"\n\n/**\n * Invoke a specified function on all commands.\n * @param[in]  func  The function to invoke on all commands.\n */\nvoid broadcast(const std::function<void(std::shared_ptr<command>)> func, std::ostream &os);\n\n/**\n * Find the command identified by the specified symbolic command name.\n * @param[in]  symbol  The symbolic command name.\n * @return             An instance of the command or nullptr if not found.\n */\nstd::shared_ptr<command> find(const std::string &symbol);\n\n/**\n * Find the new name of the formerly-named command.\n * @param[in]  former  The former symbolic command name.\n * @return             The current name of the formerly-named command.\n */\nstd::string formerly(const std::string &former);\n\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/impl/json_helper.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_PROPERTY_TREE_IPP\n#define BX_PROPERTY_TREE_IPP\n\n#include <string>\n#include <UChain/explorer/define.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\ntemplate <typename Values>\nJson::Value json_helper::prop_tree_list(const std::string &name, const Values &values,\n                                        bool json)\n{\n    const auto denormalized_name = json ? \"\" : name;\n\n    Json::Value list;\n    for (const auto &value : values)\n        list.append(Json::Value()[denormalized_name] = prop_list(value));\n\n    if (list.isNull())\n        list.resize(0);\n    return list;\n}\n\ntemplate <typename Values>\nJson::Value json_helper::prop_tree_list_of_lists(const std::string &name,\n                                                 const Values &values, bool json)\n{\n    const auto denormalized_name = json ? \"\" : name;\n\n    Json::Value list;\n    for (const auto &value : values)\n        list.append(Json::Value()[denormalized_name] = prop_list(value, json));\n\n    if (list.isNull())\n        list.resize(0);\n\n    return list;\n}\n\ntemplate <typename Values>\nJson::Value json_helper::prop_value_list(const std::string &name, const Values &values,\n                                         bool json)\n{\n    const auto denormalized_name = json ? \"\" : name;\n\n    Json::Value list;\n    for (const auto &value : values)\n    {\n        list.append(Json::Value()[denormalized_name] += value);\n    }\n\n    if (list.isNull())\n        list.resize(0);\n\n    return list;\n}\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/impl/utility.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_UTILITY_IPP\n#define BX_UTILITY_IPP\n\n#ifdef _MSC_VER\n// Suppressing msvc warnings from boost that are heard to deal with\n// because boost/algorithm carelessly defines _SCL_SECURE_NO_WARNINGS\n// without sampling it first.\n#pragma warning(push)\n#pragma warning(disable : 4996)\n#endif\n#include <cstddef>\n#include <iostream>\n#include <cstdint>\n#include <string>\n#include <system_error>\n#include <tuple>\n#include <vector>\n#include <boost/algorithm/string.hpp>\n#include <boost/bind.hpp>\n#include <boost/program_options.hpp>\n#include <boost/dynamic_bitset/dynamic_bitset.hpp>\n#include <boost/range/algorithm/find_if.hpp>\n#include <boost/lexical_cast.hpp>\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\n\ntemplate <typename Value>\nvoid deserialize(Value &value, const std::string &text, bool trim)\n{\n    if (trim)\n        value = boost::lexical_cast<Value>(boost::trim_copy(text));\n    else\n        value = boost::lexical_cast<Value>(text);\n}\n\ntemplate <typename Value>\nvoid deserialize(Value &value, std::istream &input, bool trim)\n{\n    deserialize(value, read_stream(input), trim);\n}\n\ntemplate <typename Value>\nvoid deserialize(std::vector<Value> &collection, const std::string &text,\n                 bool trim)\n{\n    // This had problems with the inclusion of the ideographic (CJK) space\n    // (0xe3,0x80, 0x80). Need to infuse the local in bc::split().\n    const auto tokens = split(text, \" \\n\\r\\t\");\n    for (const auto &token : tokens)\n    {\n        Value value;\n        deserialize(value, token, true);\n        collection.push_back(value);\n    }\n}\n\ntemplate <typename Item>\nbool deserialize_satoshi_item(Item &item, const data_chunk &data)\n{\n    return item.from_data(data);\n}\n\ntemplate <typename Value>\nvoid load_input(Value &parameter, const std::string &name,\n                po::variables_map &variables, std::istream &input, bool raw)\n{\n    if (variables.find(name) == variables.end())\n        deserialize(parameter, input, !raw);\n}\n\ntemplate <typename Value>\nvoid load_path(Value &parameter, const std::string &name,\n               po::variables_map &variables, bool raw)\n{\n    // The path is not set as an argument so we can't load from file.\n    auto variable = variables.find(name);\n    if (variable == variables.end())\n        return;\n\n    // Get the argument value as a string.\n    const auto path = boost::any_cast<std::string>(variable->second.value());\n\n    // The path is the stdio sentinal, so clear parameter and don't read file.\n    if (path == BX_STDIO_PATH_SENTINEL)\n    {\n        variables.erase(variable);\n        return;\n    }\n\n    bc::ifstream file(path, std::ios::binary);\n    if (!file.good())\n    {\n        BOOST_THROW_EXCEPTION(po::invalid_option_value(path));\n    }\n\n    deserialize(parameter, file, !raw);\n}\n\ntemplate <typename Value>\nstd::string serialize(const Value &value, const std::string &fallback)\n{\n    std::stringstream stream;\n    stream << value;\n    const auto &text = stream.str();\n    return text.empty() ? fallback : text;\n}\n\ntemplate <typename Item>\ndata_chunk serialize_satoshi_item(const Item &item)\n{\n    return item.to_data();\n}\n\ntemplate <typename Instance>\nvoid write_file(std::ostream &output, const std::string &path,\n                const Instance &instance, bool terminate)\n{\n    if (path.empty() || path == BX_STDIO_PATH_SENTINEL)\n    {\n        output << instance;\n        if (terminate)\n            output << std::endl;\n    }\n    else\n    {\n        bc::ofstream file(path, std::ofstream::binary);\n        file << instance;\n        if (terminate)\n            file << std::endl;\n    }\n}\n\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/json_helper.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_PROPERTY_TREE_HPP\n#define BX_PROPERTY_TREE_HPP\n\n#include <map>\n#include <string>\n#include <vector>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/config/header.hpp>\n#include <UChain/explorer/config/input.hpp>\n#include <UChain/explorer/config/output.hpp>\n#include <UChain/explorer/config/point.hpp>\n#include <UChain/explorer/config/transaction.hpp>\n#include <UChain/explorer/config/wrapper.hpp>\n#include <UChainService/txs/wallet/wallet.hpp>\n\n#include <jsoncpp/json/json.h>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\nclass base2;\nclass header;\nclass input;\nclass output;\nclass transaction;\nclass wrapper;\n\n/**\n* A tuple to represent settings and serialized values.\n*/\ntypedef std::map<std::string, std::string> settings_list;\n\ntemplate <typename Value>\nJson::Value &operator+=(Json::Value &a, const Value &b);\n\n/**\n* Create a string of value elements.\n* @param      <Value>  The element type.\n* @returns             A string of the element.\n*/\ntemplate <typename Value>\nstd::string operator+(const Value &value);\n\nstruct json_helper\n{\n\n    explicit json_helper(int ver = 1) : version_(ver) {}\n\n    /**\n * Create a property tree array of property tree elements.\n * The child elements of Value contain no arrays.\n * @param      <Values>  The array element type.\n * @param[in]  name      The name of the list elements.\n * @param[in]  values    The enumerable with elements of type Values.\n * @param[in]  json      Use json array formating.\n * @returns              A new property tree containing the list.\n */\n    template <typename Values>\n    Json::Value prop_tree_list(const std::string &name, const Values &values,\n                               bool json);\n\n    /**\n * Create a property tree array of property tree elements.\n * The child elements of Value contain arrays.\n * @param      <Values>  The array element type.\n * @param[in]  name      The name of the list elements.\n * @param[in]  values    The enumerable with elements of type Values.\n * @param[in]  json      Use json array formating.\n * @returns              A new property tree containing the list.\n */\n    template <typename Values>\n    Json::Value prop_tree_list_of_lists(const std::string &name,\n                                        const Values &values, bool json);\n\n    /**\n * Create a property tree array of value elements.\n * @param      <Values>  The array element type.\n * @param[in]  name      The name of the list elements.\n * @param[in]  values    The enumerable with elements of type Values.\n * @param[in]  json      Use json array formating.\n * @returns              A new property tree containing the list.\n */\n    template <typename Values>\n    Json::Value prop_value_list(const std::string &name, const Values &values,\n                                bool json);\n\n    /**\n * Generate a property list for a block header.\n * @param[in]  header  The header.\n * @return             A property list.\n */\n    BCX_API Json::Value prop_list(const header &header);\n\n    /**\n * Generate a property tree for a block header.\n * @param[in]  header  The header.\n * @return             A property tree.\n */\n    BCX_API Json::Value prop_tree(const header &header);\n\n    /**\n * Generate a property tree for a set of headers.\n * @param[in]  headers  The set of headers.\n * @return              A property tree.\n */\n    BCX_API Json::Value prop_tree(const std::vector<header> &headers, bool json);\n\n    /**\n* Generate a property list for a history row.\n* @param[in]  row  The history row.\n* @return          A property list.\n*/\n    BCX_API Json::Value prop_list(const chain::history &row);\n\n    /**\n * Generate a property tree for a history row.\n * @param[in]  row  The history row.\n * @return          A property tree.\n */\n    BCX_API Json::Value prop_tree(const chain::history &row);\n\n    /**\n * Generate a property tree for a set of history rows.\n *\n * @param[in]  rows  The set of history rows.\n * @param[in]  json  Use json array formatting.\n * @return           A property tree.\n */\n    BCX_API Json::Value prop_tree(const chain::history::list &rows, bool json);\n\n    /**\n * Generate a property list from balance rows for an address.\n * This doesn't require array formatting because it summarizes the rows.\n * @param[in]  rows             The set of balance rows.\n * @param[in]  balance_address  The payment address for the balance rows.\n * @return                      A property list.\n */\n    BCX_API Json::Value prop_list(const chain::history::list &rows,\n                                  const bc::wallet::payment_address &balance_address);\n\n    /**\n * Generate a property tree from balance rows for an address.\n * This doesn't require array formatting because it summarizes the rows.\n * @param[in]  rows             The set of balance rows.\n * @param[in]  balance_address  The payment address for the balance rows.\n * @return                      A property tree.\n */\n    BCX_API Json::Value prop_tree(const chain::history::list &rows,\n                                  const bc::wallet::payment_address &balance_address);\n\n    /**\n * Generate a property list for a transaction input.\n * @param[in]  tx_input  The input.\n * @return               A property list.\n */\n    BCX_API Json::Value prop_list(const tx_input_type &tx_input);\n\n    /**\n * Generate a property tree for a transaction input.\n * @param[in]  tx_input  The input.\n * @return               A property tree.\n */\n    BCX_API Json::Value prop_tree(const tx_input_type &tx_input);\n\n    /**\n * Generate a property tree for a set of transaction inputs.\n * @param[in]  tx_inputs  The set of transaction inputs.\n * @param[in]  json       Use json array formatting.\n * @return                A property tree.\n */\n    BCX_API Json::Value prop_tree(const tx_input_type::list &tx_inputs, bool json);\n\n    /**\n * Generate a property list for an input.\n * @param[in]  input  The input.\n * @return            A property list.\n */\n    BCX_API Json::Value prop_list(const explorer::config::input &input);\n\n    /**\n * Generate a property tree for an input.\n * @param[in]  input  The input.\n * @return            A property tree.\n */\n    BCX_API Json::Value prop_tree(const explorer::config::input &input);\n\n    /**\n * Generate a property tree for a set of inputs.\n * @param[in]  inputs  The set of inputs.\n * @param[in]  json    Use json array formatting.\n * @return             A property tree.\n */\n    BCX_API Json::Value prop_tree(\n        const std::vector<explorer::config::input> &inputs, bool json);\n\n    /**\n * Generate a property list for a transaction output.\n * @param[in]  tx_output  The transaction output.\n * @return                A property list.\n */\n    BCX_API Json::Value prop_list(const tx_output_type &tx_output);\n    /**\n * Generate a property list for a asset.\n * @param[in]  output_attach  The asset in output.\n * @return                A property list.\n */\n    BCX_API Json::Value prop_list(const tx_output_type &tx_output, uint32_t index);\n\n    BCX_API Json::Value prop_list(bc::chain::asset &output_attach);\n    /**\n * Generate a property tree for a transaction output.\n * @param[in]  tx_output  The transaction output.\n * @return                A property tree.\n */\n    BCX_API Json::Value prop_tree(const tx_output_type &tx_output);\n\n    /**\n * Generate a property tree for a set of transaction outputs.\n * @param[in]  tx_outputs  The set of transaction outputs.\n * @param[in]  json        Use json array formatting.\n * @return                 A property tree.\n */\n    BCX_API Json::Value prop_tree(const tx_output_type::list &tx_outputs,\n                                  bool json);\n\n    /**\n * Generate a property list for a point.\n * @param[in]  p          The point.\n * @return                A property list.\n */\n    BCX_API Json::Value prop_list(const chain::point &point);\n\n    /**\n * Generate a property tree for a set of points.\n * @param[in]  points  The set of points.\n * @param[in]  json        Use json array formatting.\n * @return                 A property tree.\n */\n    BCX_API Json::Value prop_tree(const chain::point::list &points, bool json);\n\n    /**\n * Generate a property tree for a points_info.\n * @param[in]  p_info       The points_info.\n * @param[in]  json         Use json array formatting.\n * @return                  A property tree.\n */\n    BCX_API Json::Value prop_tree(const chain::points_info &points_info, bool json);\n\n    /**\n * Generate a property list for a transaction.\n * @param[in]  transaction  The transaction.\n * @param[in]  json         Use json array formatting.\n * @return                  A property list.\n */\n    BCX_API Json::Value prop_list(const transaction &transaction, bool json);\n    BCX_API Json::Value prop_list(const transaction &transaction, uint64_t tx_height, bool json);\n\n    BCX_API Json::Value prop_list_of_rawtx(const transaction &transaction, bool with_hash, bool ignore_compatibility = false);\n\n    /**\n * Generate a property tree for a transaction.\n * @param[in]  transaction  The transaction.\n * @param[in]  json         Use json array formatting.\n * @return                  A property tree.\n */\n    BCX_API Json::Value prop_tree(const transaction &transaction, bool json);\n\n    /**\n * Generate a property tree for a set of transactions.\n * @param[in]  transactions  The set of transactions.\n * @param[in]  json          Use json array formatting.\n * @return                   A property tree.\n */\n    BCX_API Json::Value prop_tree(const std::vector<transaction> &transactions,\n                                  bool json);\n\n    /**\n * Generate a property list for a wrapper.\n * @param[in]  wrapper  The wrapper instance.\n * @return              A property list.\n */\n    BCX_API Json::Value prop_list(const bc::wallet::wrapped_data &wrapper);\n\n    /**\n * Generate a property tree for a wrapper.\n * @param[in]  wrapper  The wrapper instance.\n * @return              A property tree.\n */\n    BCX_API Json::Value prop_tree(const bc::wallet::wrapped_data &wrapper);\n\n    /**\n * Generate a property list for transaction with extended data.\n * @param[in]  tx          The transaction.\n * @param[in]  block_hash  The block_hash of the transaction.\n * @param[in]  address     The address used to locate the transaction.\n * @param[in]  json        Use json array formatting.\n * @return                 A property list.\n */\n    BCX_API Json::Value prop_list(const tx_type &tx, const hash_digest &block_hash,\n                                  const bc::wallet::payment_address &address, bool json);\n\n    /**\n * Generate a property tree for transaction with extended data.\n * @param[in]  tx          The transaction.\n * @param[in]  block_hash  The block_hash of the transaction.\n * @param[in]  address     The address used to locate the transaction.\n * @param[in]  json        Use json array formatting.\n * @return                 A property tree.\n */\n    BCX_API Json::Value prop_tree(const tx_type &tx, const hash_digest &block_hash,\n                                  const bc::wallet::payment_address &address, bool json);\n\n    /**\n * Generate a property list for a stealth address.\n * @param[in]  stealth_address  The stealth address.\n * @param[in]  json             Use json array formatting.\n * @return                      A property list.\n */\n    BCX_API Json::Value prop_list(const bc::wallet::stealth_address &stealth, bool json);\n\n    /**\n * Generate a property tree for a stealth address.\n * @param[in]  stealth_address  The stealth address.\n * @param[in]  json             Use json array formatting.\n * @return                      A property tree.\n */\n    BCX_API Json::Value prop_tree(const bc::wallet::stealth_address &stealth, bool json);\n\n    /**\n * Generate a property list for a stealth metadata row.\n * @param[in]  rows  The stealth row.\n * @return           A property list.\n */\n    BCX_API Json::Value prop_list(const chain::stealth &row);\n\n    /**\n * Generate a property tree for a stealth metadata row.\n * @param[in]  rows  The stealth row.\n * @return           A property tree.\n */\n    BCX_API Json::Value prop_tree(const chain::stealth &row);\n\n    /**\n * Generate a property tree from stealth metadata rows.\n * @param[in]  rows    The set of stealth rows.\n * @param[in]  json    Use json array formatting.\n * @return             A property tree.\n */\n    BCX_API Json::Value prop_tree(const chain::stealth::list &rows, bool json);\n\n    /**\n * Create a property list for the fetch-tx-index command.\n * @param[in]  hash    The block hash.\n * @param[in]  height  The block height.\n * @param[in]  index   The tx index.\n * @returns            A new property list containing the list.\n */\n    BCX_API Json::Value prop_list(const bc::hash_digest &hash, size_t height,\n                                  size_t index);\n\n    /**\n * Create a property tree for the fetch-tx-index command.\n * @param[in]  hash    The block hash.\n * @param[in]  height  The block height.\n * @param[in]  index   The tx index.\n * @returns            A new property tree containing the list.\n */\n    BCX_API Json::Value prop_tree(const bc::hash_digest &hash, size_t height,\n                                  size_t index);\n\n    /**\n * Create a property tree for the settings command.\n * @param[in]  settings   The list of settings.\n * @returns               A new property tree containing the settings.\n */\n    BCX_API Json::Value prop_tree(const settings_list &settings);\n\n    /**\n * Create a property tree for a parsed bitcoin uri.\n * @param[in]  uri   The parsed uri.\n * @returns          A new property tree containing the settings.\n */\n    BCX_API Json::Value prop_tree(const bc::wallet::bitcoin_uri &uri);\n\n    /**\n * Create a property tree for a parsed bitcoin uri.\n * @param[in]  block The parsed block.\n * @param[in]  json  json output.\n * @param[in]  tx_json   json output for tx within this block.\n * @returns          A new property tree containing the settings.\n */\n    BCX_API Json::Value prop_tree(const block &block, bool json, bool tx_json);\n\n    /**\n * Generate a property list for a token detail.\n * @param[in]  detail_info          The token detail.\n * @param[in]  is_maximum_supply    The token amount means maximum_supply or quantity.\n * @param[in]  show_address         A boolean value indicate whether show address.\n * @return             A property list.\n */\n    BCX_API Json::Value prop_list(const bc::chain::token_detail &detail_info, bool is_maximum_supply, bool show_address = true);\n\n    /**\n * Generate a property list for a token transfer with detail.\n * @param[in]  balance_info The token balance info.\n * @param[in]  issued_info  The issued token detail. include the other info.\n * @param[in]  show_address A boolean value indicate whether show address.\n * @return             A property list.\n */\n    BCX_API Json::Value prop_list(const bc::chain::token_balances &balance_info, const bc::chain::token_detail &issued_info, bool show_address = true);\n\n    /**\n * Generate a property list for a token transfer with detail.\n * @param[in]  balance_info The token balance info.\n * @return             A property list.\n */\n    BCX_API Json::Value prop_list(const bc::chain::token_balances &balance_info);\n\n    /**\n * Generate a property list for a token transfer with detail.\n * @param[in]  balance_info The deoisuted token balance info.\n * @param[in]  issued_info  The issued token detail. include the other info.\n * @param[in]  show_address A boolean value indicate whether show address.\n * @return             A property list.\n */\n    BCX_API Json::Value prop_list(const bc::chain::token_deposited_balance &balance_info, const bc::chain::token_detail &issued_info, bool show_address = true);\n\n    /**\n * Generate a property list for a token transfer.\n * @param[in]  trans_info        The token transfer.\n * @param[in]  decimal_number    The token transfer unit. if equals max_uint8, do not add \"decimal_number\" index.\n * @return             A property list.\n */\n    BCX_API Json::Value prop_list(const bc::chain::token_transfer &trans_info, uint8_t decimal_number = max_uint8);\n\n    /**\n * Generate a property list for a token cert.\n * @param[in]  cert_info        The token cert.\n * @return             A property list.\n */\n    BCX_API Json::Value prop_list(const bc::chain::token_cert &cert_info);\n\n    /**\n * Generate a property list for an identifiable token.\n * @param[in]  cert_info        The identifiable token.\n * @return             A property list.\n */\n    BCX_API Json::Value prop_list(const bc::chain::candidate &candidate_info, bool always_show_content = false);\n    BCX_API Json::Value prop_list(const bc::chain::candidate_info &candidate_info, bool always_show_content = false, bool show_vote = false);\n\n    /**\n * Generate a property list for a multisign.\n * @param[in]  multisign        The multisign.\n * @return             A property list.\n */\n    BCX_API Json::Value prop_list(const bc::chain::wallet_multisig &multisign);\n\n    /**\n * Generate a property list for a attenuation_model_param.\n * @param[in]  param            The parameter of attenuation model.\n * @return             A property list.\n */\n    BCX_API Json::Value prop_attenuation_model_param(const data_chunk &param);\n    BCX_API Json::Value prop_attenuation_model_param(const std::string &param);\n\n    /**\n * Generate a property list for an wallet.\n * @param[in]  acc        The wallet.\n * @return             A property list.\n */\n    typedef std::tuple<std::string, std::string, Json::Value> wallet_info;\n    BCX_API Json::Value prop_list(const wallet_info &acc);\n\n  private:\n    uint8_t version_{1}; //1 - api v1; 2 - api v2;\n};\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n\n#include <UChain/explorer/impl/json_helper.ipp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/parser.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_PARSER_HPP\n#define BX_PARSER_HPP\n\n#include <iostream>\n#include <string>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/command.hpp>\n#include <UChain/explorer/define.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\n\n/// Parse configurable values from environment variables, settings file, and\n/// command line positional and non-positional options.\nclass BCX_API parser\n    : public bc::config::parser\n{\n  public:\n    /// Construct the parser for the given command.\n    parser(command &instance);\n\n    /// Parse all configuration into member settings.\n    virtual bool parse(std::string &out_error, std::istream &input,\n                       int argc, const char *argv[]);\n\n    virtual bool help() const;\n\n    /// Load command line options (named).\n    virtual options_metadata load_options();\n\n    /// Load command line arguments (positional).\n    virtual arguments_metadata load_arguments();\n\n    /// Load configuration file settings.\n    virtual options_metadata load_settings();\n\n    /// Load environment variable settings.\n    virtual options_metadata load_environment();\n\n  protected:\n    virtual void load_command_variables(variables_map &variables,\n                                        std::istream &input, int argc, const char *argv[]);\n\n  private:\n    static std::string system_config_directory();\n    static boost::filesystem::path default_config_path();\n    bool is_negative(const char *c);\n\n    bool help_;\n    command &instance_;\n};\n\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/utility.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef BX_UTILITY_HPP\n#define BX_UTILITY_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <iostream>\n#include <cstdint>\n#include <fstream>\n#include <string>\n#include <system_error>\n#include <tuple>\n#include <vector>\n#include <boost/algorithm/string.hpp>\n#include <boost/bind.hpp>\n#include <boost/filesystem.hpp>\n#include <boost/program_options.hpp>\n#include <boost/dynamic_bitset/dynamic_bitset.hpp>\n#include <boost/range/algorithm/find_if.hpp>\n#include <boost/lexical_cast.hpp>\n#include <UChain/client.hpp>\n#include <UChain/explorer/define.hpp>\n\n/* NOTE: don't declare 'using namespace foo' in headers. */\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\n\n/**\n * Types for defining name-value pair list.\n */\ntypedef std::pair<std::string, std::string> name_value_pair;\ntypedef std::vector<name_value_pair> name_value_pairs;\n\n/**\n * Forward declaration to break header cycle.\n */\nclass command;\n\n/**\n * Convert a text string to the specified type.\n * @param      <Value>  The converted type.\n * @param[out] value    The parsed value.\n * @param[in]  text     The text to convert.\n * @param[in]  trim     True if value should be trimmed before conversion.\n */\ntemplate <typename Value>\nvoid deserialize(Value &value, const std::string &text, bool trim);\n\n/**\n * Read an input stream to the specified type.\n * @param      <Value>  The converted type.\n * @param[out] value    The parsed value.\n * @param[in]  input    The stream to convert.\n * @param[in]  trim     True if value should be trimmed before conversion.\n */\ntemplate <typename Value>\nvoid deserialize(Value &value, std::istream &input, bool trim);\n\n/**\n * Deserialize the tokens of a text string to a vector of the inner type.\n * @param      <Value>     The inner type.\n * @param[out] collection  The parsed vector value.\n * @param[in]  text        The text to convert.\n * @param[in]  trim        True if value should be trimmed before conversion.\n */\ntemplate <typename Value>\nvoid deserialize(std::vector<Value> &collection, const std::string &text,\n                 bool trim);\n\n/**\n * Deserialize a satoshi item from the specified binary data.\n * @param      <Item>  The type of the item to parse.\n * @param[out] item    The deserialized item.\n * @param[in]  data    The binary data.\n * @return             True if a item was parsed.\n */\ntemplate <typename Item>\nbool deserialize_satoshi_item(Item &item, const data_chunk &data);\n\n/**\n * If the variable is not yet loaded, load from stdin as fallback.\n * @param      <Value>    The type of the parameter to load.\n * @param[in]  name       The parameter name.\n * @param[in]  variables  The loaded variables.\n * @param[in]  input      The input stream for loading the parameter.\n * @param[in]  raw        True if the input is raw (should not be trimmed).\n */\ntemplate <typename Value>\nvoid load_input(Value &parameter, const std::string &name,\n                po::variables_map &variables, std::istream &input, bool raw);\n\n/**\n * Load file contents as parameter fallback. Obtain the path from the parameter\n * in the variables map.\n * @param      <Value>    The type of the parameter to load.\n * @param[in]  name       The parameter name.\n * @param[in]  variables  The loaded variables.\n * @param[in]  raw        True if the file is raw (should not be trimmed).\n */\ntemplate <typename Value>\nvoid load_path(Value &parameter, const std::string &name,\n               po::variables_map &variables, bool raw);\n\n/**\n * Conveniently convert an instance of the specified type to string.\n * @param      <Value>   The type to serialize.\n * @param[in]  value     The instance to convert.\n * @param[in]  fallback  The text to populate if value is empty.\n * @return               The serialized value.\n */\ntemplate <typename Value>\nstd::string serialize(const Value &value, const std::string &fallback = \"\");\n\n/**\n * Serialize the specified satoshi item to binary data.\n * The data will be resized as necessary to fit the item.\n * @param       <Item>  The type of the item.\n * @param[out] data     The binary data.\n * @param[in]  item     The satoshi item.\n */\ntemplate <typename Item>\ndata_chunk serialize_satoshi_item(const Item &item);\n\n/**\n * Write a value to a file in the specified path and otherwise to the\n * specified stream. Not unit testable due to embedded file i/o.\n * @param      Instance   The type of the instance to write.\n * @param[out] output     The fallback out stream.\n * @param[in]  path       The file path or stdio sentinel or empty.\n * @param[in]  terminate  Indicates /n should be added (defaults to true).\n * @param[in]  instance   The instance to serialize.\n */\ntemplate <typename Instance>\nvoid write_file(std::ostream &output, const std::string &path,\n                const Instance &instance, bool terminate = true);\n\n/**\n * Get the connection settings for the configured network.\n * @param    cmd  The command.\n * @returns       A structure containing the connection settings.\n */\nBCX_API client::connection_type get_connection(const command &cmd);\n\n/**\n * Generate a new ec key from a seed.\n * @param[in]  seed  The seed for key randomness.\n * @return           The new key.\n */\nBCX_API ec_secret new_key(const data_chunk &seed);\n\n/**\n * Generate a new pseudorandom seed.\n * @param[in]  seed  The seed length in bits. Will be aligned to nearest byte.\n * @return           The new key.\n */\nBCX_API data_chunk new_seed(size_t bitlength = minimum_seed_bits);\n\n/**\n * Convert a list of indexes to a list of strings. This could be generalized.\n * @param[in]  indexes  The list of indexes to convert.\n * @return              The list of strings.\n */\nBCX_API std::vector<std::string> numbers_to_strings(\n    const chain::point::indexes &indexes);\n\n/**\n * DEPRECATED in favor of libbitcoin::pseudo_random_fill.\n * Fill a buffer with randomness using the default random engine.\n * @param[in]  chunk  The buffer to fill with randomness.\n */\nBCX_API void random_fill(data_chunk &chunk);\n\n/**\n * Get a message from the specified input stream.\n * @param[in]  stream The input stream to read.\n * @return            The message read from the input stream.\n */\nBCX_API std::string read_stream(std::istream &stream);\n\n/**\n * Convert any script to an opcode::raw_data script (e.g. for input signing).\n * @param[in]  script  The script to convert.\n * @return             The data script.\n */\nBCX_API chain::script script_to_raw_data_script(const chain::script &script);\n\n/**\n * Split a list of tokens with delimiters into a name-value pair list.\n * @param[in]  tokens     The string to test\n * @param[in]  delimiter  The delimiter, defualts to \":\".\n * @return                The name-value pair list.\n */\nname_value_pairs split_pairs(const std::vector<std::string> tokens,\n                             const std::string delimiter = \":\");\n\n/**\n * Determine if a string starts with another (case insensitive).\n * @param[in]  value   The string to test\n * @param[in]  prefix  The prefix to test against.\n * @return             True if the value is prefixed by the prefix.\n */\nBCX_API bool starts_with(const std::string &value, const std::string &prefix);\n\n/**\n * Unwrap a wrapped payload.\n * @param[in]  data     The data structure to accept the unwrap.\n * @param[in]  wrapped  The wrapped data to unwrap.\n * @return              True if input checksum validates.\n */\nBCX_API bool unwrap(bc::wallet::wrapped_data &data, data_slice wrapped);\n\n/**\n * Wrap arbitrary data.\n * @param[in]  data  The data structure to wrap.\n * @return           The wrapped data.\n */\nBCX_API data_chunk wrap(const bc::wallet::wrapped_data &data);\n\n/**\n * Serialize a property tree using a specified encoding.\n * @param[out] output  The output stream to write to.\n * @param[in]  tree    The property tree to serialize.\n * @param[in]  engine  The stream writing engine type to use, defaults to info.\n * @return             The output stream (for convenience).\n */\nBCX_API std::ostream &write_stream(std::ostream &output, const Json::Value &tree,\n                                   encoding_engine engine = encoding_engine::info);\n\n} // namespace explorer\n} // namespace libbitcoin\n\n#include <UChain/explorer/impl/utility.ipp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer/version.hpp",
    "content": "///////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 2014-2018 libbitcoin-explorer developers (see COPYING).\n//\n//        GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY\n//\n///////////////////////////////////////////////////////////////////////////////\n#ifndef UC_EXPLORER_VERSION_HPP\n#define UC_EXPLORER_VERSION_HPP\n\n/**\n * The semantic version of this repository as: [major].[minor].[patch]\n * For interpretation of the versioning scheme see: http://semver.org\n */\n\n#define UC_EXPLORER_VERSION \"0.0.6\"\n#define UC_EXPLORER_MAJOR_VERSION 0\n#define UC_EXPLORER_MINOR_VERSION 0\n#define UC_EXPLORER_PATCH_VERSION 6\n\n#endif\n"
  },
  {
    "path": "include/UChain/explorer.hpp",
    "content": "///////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 2014-2018 libbitcoin-explorer developers (see COPYING).\n//\n//        GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY\n//\n///////////////////////////////////////////////////////////////////////////////\n#ifndef UC_EXPLORER_HPP\n#define UC_EXPLORER_HPP\n\n/**\n * API Users: Include only this header. Direct use of other headers is fragile\n * and unsupported as header organization is subject to change.\n *\n * Maintainers: Do not include this header internal to this library.\n */\n\n#include <UChain/client.hpp>\n#include <UChain/network.hpp>\n#include <UChain/explorer/callback_state.hpp>\n#include <UChain/explorer/command.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChain/explorer/display.hpp>\n#include <UChain/explorer/generated.hpp>\n#include <UChain/explorer/parser.hpp>\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/utility.hpp>\n#include <UChain/explorer/version.hpp>\n#include <UChain/explorer/commands/fetch-history.hpp>\n#include <UChain/explorer/commands/fetch-stealth.hpp>\n#include <UChain/explorer/commands/help.hpp>\n#include <UChain/explorer/commands/send-tx.hpp>\n#include <UChain/explorer/commands/settings.hpp>\n#include <UChain/explorer/commands/stealth-decode.hpp>\n#include <UChain/explorer/commands/stealth-encode.hpp>\n#include <UChain/explorer/commands/stealth-public.hpp>\n#include <UChain/explorer/commands/stealth-secret.hpp>\n#include <UChain/explorer/commands/stealth-shared.hpp>\n#include <UChain/explorer/commands/tx-decode.hpp>\n#include <UChain/explorer/commands/validate-tx.hpp>\n#include <UChain/explorer/config/address.hpp>\n#include <UChain/explorer/config/algorithm.hpp>\n#include <UChain/explorer/config/btc.hpp>\n#include <UChain/explorer/config/byte.hpp>\n#include <UChain/explorer/config/cert_key.hpp>\n#include <UChain/explorer/config/ec_private.hpp>\n#include <UChain/explorer/config/encoding.hpp>\n#include <UChain/explorer/config/endorsement.hpp>\n#include <UChain/explorer/config/hashtype.hpp>\n#include <UChain/explorer/config/hd_key.hpp>\n#include <UChain/explorer/config/header.hpp>\n#include <UChain/explorer/config/input.hpp>\n#include <UChain/explorer/config/language.hpp>\n#include <UChain/explorer/config/output.hpp>\n#include <UChain/explorer/config/point.hpp>\n#include <UChain/explorer/config/raw.hpp>\n#include <UChain/explorer/config/script.hpp>\n#include <UChain/explorer/config/signature.hpp>\n#include <UChain/explorer/config/transaction.hpp>\n#include <UChain/explorer/config/wrapper.hpp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/network/acceptor.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_ACCEPTOR_HPP\n#define UC_NETWORK_ACCEPTOR_HPP\n\n#include <atomic>\n#include <cstdint>\n#include <functional>\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/define.hpp>\n#include <UChain/network/settings.hpp>\n#include <UChain/network/socket.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\n/// Create inbound socket connections, thread and lock safe.\nclass BCT_API acceptor\n  : public enable_shared_from_base<acceptor>, track<acceptor>\n{\npublic:\n    typedef std::shared_ptr<acceptor> ptr;\n    typedef std::function<void(const code&)> result_handler;\n    typedef std::function<void(const code&, channel::ptr)> accept_handler;\n\n    /// Construct an instance.\n    acceptor(threadpool& pool, const settings& settings);\n\n    /// Validate acceptor stopped.\n    ~acceptor();\n\n    /// This class is not copyable.\n    acceptor(const acceptor&) = delete;\n    void operator=(const acceptor&) = delete;\n\n    /// Start the listener on the specified port.\n    virtual void listen(uint16_t port, result_handler handler);\n\n    /// Accept the next connection available, until canceled.\n    virtual void accept(accept_handler handler);\n\n    /// Cancel the listener and all outstanding accept attempts.\n    virtual void stop();\n\nprivate:\n    code safe_listen(uint16_t port);\n    void safe_accept(socket::ptr socket, accept_handler handler);\n    std::shared_ptr<channel> new_channel(socket::ptr socket);\n    void handle_accept(const boost_code& ec, socket::ptr socket,\n        accept_handler handler);\n\n    threadpool& pool_;\n    const settings& settings_;\n    dispatcher dispatch_;\n    asio::acceptor_ptr acceptor_;\n    mutable shared_mutex mutex_;\n};\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/network/channel.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_CHANNEL_HPP\n#define UC_NETWORK_CHANNEL_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <memory>\n#include <utility>\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/network/const_buffer.hpp>\n#include <UChain/network/define.hpp>\n#include <UChain/network/proxy.hpp>\n#include <UChain/network/message_subscriber.hpp>\n#include <UChain/network/settings.hpp>\n#include <UChain/network/socket.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\n/// A concrete proxy with timers and state, mostly thread safe.\nclass BCT_API channel\n  : public proxy, track<channel>\n{\npublic:\n    typedef std::shared_ptr<channel> ptr;\n\n    /// Construct an instance.\n    channel(threadpool& pool, socket::ptr socket, const settings& settings);\n\n    void start(result_handler handler) override;\n\n    virtual bool notify() const;\n    virtual void set_notify(bool value);\n\n    virtual uint64_t nonce() const;\n    virtual void set_nonce(uint64_t value);\n\n    void set_protocol_start_handler(std::function<void()> handler);\n\n    void invoke_protocol_start_handler(const code& ec);\n\nprotected:\n    virtual void handle_activity();\n    virtual void handle_stopping();\n\nprivate:\n    void do_start(const code& ec, result_handler handler);\n\n    void start_expiration();\n    void handle_expiration(const code& ec);\n\n    void start_inactivity();\n    void handle_inactivity(const code& ec);\n\n    bool notify_;\n    uint64_t nonce_;\n    deadline::ptr expiration_;\n    deadline::ptr inactivity_;\n    std::function<void()> protocol_start_handler_;\n    upgrade_mutex mutex_;\n};\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/network/connections.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_CONNECTIONS_HPP\n#define UC_NETWORK_CONNECTIONS_HPP\n\n#include <atomic>\n#include <cstddef>\n#include <cstdint>\n#include <functional>\n#include <memory>\n#include <string>\n#include <vector>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/define.hpp>\n#include <UChain/coin/message/address.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\n/// Pool of active connections, thread and lock safe.\nclass BCT_API connections\n  : public enable_shared_from_base<connections>\n{\npublic:\n    typedef std::shared_ptr<connections> ptr;\n    typedef std::function<void(bool)> truth_handler;\n    typedef std::function<void(size_t)> count_handler;\n    typedef std::function<void(const code&)> result_handler;\n    typedef std::function<void(const code&, channel::ptr)> channel_handler;\n\n    /// Construct an instance.\n    connections();\n\n    /// Validate connections stopped.\n    ~connections();\n\n    /// This class is not copyable.\n    connections(const connections&) = delete;\n    void operator=(const connections&) = delete;\n\n    /// Send a message to all channels, with completion handlers.\n    /// Complete always returns success, use channel handler for failure codes.\n    template <typename Message>\n    void broadcast(const Message& message, channel_handler handle_channel,\n        result_handler handle_complete)\n    {\n        // We cannot use a synchronizer here because handler closure in loop.\n        auto counter = std::make_shared<std::atomic<size_t>>(channels_.size());\n\n        for (const auto channel: safe_copy())\n        {\n            const auto handle_send = [=](code ec)\n            {\n                handle_channel(ec, channel);\n\n                if (counter->fetch_sub(1) == 1)\n                    handle_complete(error::success);\n            };\n\n            // No pre-serialize, channels may have different protocol versions.\n            channel->send(message, handle_send);\n        }\n    }\n\n    /// Subscribe to all incoming messages of a type.\n    template <class Message>\n    void subscribe(message_handler<Message>&& handler)\n    {\n        for (const auto channel: safe_copy())\n        {\n            auto handler_copy = handler;\n            channel->subscribe(std::move(handler_copy));//by jianglh\n//            channel->subscribe(\n//                std::forward<message_handler<Message>>(handler));\n        }\n    }\n\n    virtual void stop(const code& ec);\n    virtual void stop(const config::authority& authority);\n    virtual void count(count_handler handler) const;\n    virtual void store(channel::ptr channel, result_handler handler);\n    virtual void remove(channel::ptr channel, result_handler handler);\n    virtual void exists(const config::authority& authority,\n        truth_handler handler) const;\n    config::authority::list authority_list();\n\nprivate:\n    typedef std::vector<channel::ptr> list;\n\n    list safe_copy() const;\n    size_t safe_count() const;\n    code safe_store(channel::ptr channel);\n    bool safe_remove(channel::ptr channel);\n    bool safe_exists(const config::authority& address) const;\n\n    list channels_;\n    std::atomic<bool> stopped_;\n    mutable upgrade_mutex mutex_;\n};\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/network/connector.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_CONNECTOR_HPP\n#define UC_NETWORK_CONNECTOR_HPP\n\n#include <atomic>\n#include <functional>\n#include <memory>\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/define.hpp>\n#include <UChain/network/pending_sockets.hpp>\n#include <UChain/network/settings.hpp>\n#include <UChain/network/socket.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\n/// Create outbound socket connections, thread and lock safe.\nclass BCT_API connector\n  : public enable_shared_from_base<connector>, track<connector>\n{\npublic:\n    typedef std::shared_ptr<connector> ptr;\n    typedef std::function<void(const code& ec, channel::ptr)> connect_handler;\n    typedef std::function<void(const asio::endpoint& endpoint)> resolve_handler;\n\n    /// Construct an instance.\n    connector(threadpool& pool, const settings& settings);\n\n    /// This class is not copyable.\n    connector(const connector&) = delete;\n    void operator=(const connector&) = delete;\n\n    /// Try to connect to the endpoint.\n    virtual void connect(const config::endpoint& endpoint,\n        connect_handler handler, resolve_handler = nullptr);\n\n    /// Try to connect to the authority.\n    virtual void connect(const config::authority& authority,\n        connect_handler handler, resolve_handler = nullptr);\n\n    /// Try to connect to host:port.\n    virtual void connect(const std::string& hostname, uint16_t port,\n        connect_handler handler, resolve_handler = nullptr);\n\n    /// Cancel all outstanding connection attempts.\n    void stop();\n\nprivate:\n    bool stopped();\n    void close_socket(socket socket);\n    std::shared_ptr<channel> new_channel(socket::ptr socket);\n\n    void safe_stop();\n    void safe_resolve(asio::query_ptr query, connect_handler handler);\n    void safe_connect(asio::iterator iterator, socket::ptr socket,\n        deadline::ptr timer, connect_handler handler);\n\n    void handle_resolve(const boost_code& ec, asio::iterator iterator,\n        connect_handler handler, resolve_handler);\n    void handle_timer(const code& ec, socket::ptr socket,\n        connect_handler handler);\n    void handle_connect(const boost_code& ec, socket::ptr socket, deadline::ptr timer, connect_handler handler);\n\n    std::atomic<bool> stopped_;\n    threadpool& pool_;\n    const settings& settings_;\n    pending_sockets pending_;\n    dispatcher dispatch_;\n    std::shared_ptr<asio::resolver> resolver_;\n    mutable upgrade_mutex mutex_;\n};\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/network/const_buffer.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_CONST_BUFFER_HPP\n#define UC_NETWORK_CONST_BUFFER_HPP\n\n#include <cstddef>\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/network/define.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\n// A shared boost::asio write buffer, thread safe.\nclass BCT_API const_buffer\n{\npublic:\n\n    // Required by ConstBufferSequence.\n    typedef asio::const_buffer value_type;\n    typedef const value_type* const_iterator;\n\n    const_buffer();\n    explicit const_buffer(data_chunk&& data);\n    explicit const_buffer(const data_chunk& data);\n\n    size_t size() const;\n    const_iterator begin() const;\n    const_iterator end() const;\n\nprivate:\n    std::shared_ptr<data_chunk> data_;\n    value_type buffer_;\n};\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/network/define.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-node.\n *\n * UChain-node is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_DEFINE_HPP\n#define UC_NETWORK_DEFINE_HPP\n\n#include <UChain/coin.hpp>\n\n// We use the generic helper definitions in libbitcoin to define BCT_API\n// and BCT_INTERNAL. BCT_API is used for the public API symbols. It either DLL\n// imports or DLL exports (or does nothing for static build) BCT_INTERNAL is\n// used for non-api symbols.\n\n#if defined BCT_STATIC\n    #define BCT_API\n    #define BCT_INTERNAL\n#elif defined BCT_DLL\n    #define BCT_API      BC_HELPER_DLL_EXPORT\n    #define BCT_INTERNAL BC_HELPER_DLL_LOCAL\n#else\n    #define BCT_API      BC_HELPER_DLL_IMPORT\n    #define BCT_INTERNAL BC_HELPER_DLL_LOCAL\n#endif\n\n// Log name.\n#define LOG_NETWORK \"network\"\n\n// Avoid namespace conflict between boost::placeholders and std::placeholders.\n#define BOOST_BIND_NO_PLACEHOLDERS\n\n// Include boost only here, so placeholders exclusion works.\n#include <boost/asio.hpp>\n#include <boost/circular_buffer.hpp>\n#include <boost/filesystem.hpp>\n#include <boost/iostreams/stream.hpp>\n#include <boost/thread.hpp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/network/hosts.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_HOSTS_HPP\n#define UC_NETWORK_HOSTS_HPP\n\n#include <atomic>\n#include <cstddef>\n#include <cstdint>\n#include <functional>\n#include <memory>\n#include <string>\n#include <vector>\n#include <UChain/coin.hpp>\n#include <UChain/network/define.hpp>\n#include <UChain/network/settings.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\n/// This class is thread safe.\n/// The hosts class manages a thread-safe dynamic store of network addresses.\n/// The store can be loaded and saved from/to the specified file path.\n/// The file is a line-oriented set of config::authority serializations.\n/// Duplicate addresses and those with zero-valued ports are disacarded.\n\nstruct address_compare{\n    bool operator()(const libbitcoin::message::network_address& lhs, const libbitcoin::message::network_address& rhs) const\n    {\n        return lhs.ip < rhs.ip ? true : (lhs.ip > rhs.ip ? false : lhs.port < rhs.port);\n    }\n};\n\nclass BCT_API hosts\n  : public enable_shared_from_base<hosts>\n{\npublic:\n    typedef std::shared_ptr<hosts> ptr;\n    typedef message::network_address address;\n    typedef std::function<void(const code&)> result_handler;\n\n    /// Construct an instance.\n    hosts(threadpool& pool, const settings& settings);\n\n    /// This class is not copyable.\n    hosts(const hosts&) = delete;\n    void operator=(const hosts&) = delete;\n\n    /// Load hosts file if found.\n    virtual code start();\n\n    // Save hosts to file.\n    virtual code stop();\n\n    // Clear hosts buffer\n    virtual code clear();\n    virtual code after_reseeding();\n\n    virtual size_t count() const;\n    virtual code fetch(address& out, const config::authority::list& excluded_list);\n    virtual code remove(const address& host);\n    virtual code store(const address& host);\n    virtual void store(const address::list& hosts, result_handler handler);\n    address::list copy();\nprivate:\n    //    typedef boost::circular_buffer<address> list;\n    using list = std::set<address, address_compare >;\n\n    typedef list::iterator iterator;\n\n    iterator find(const address& host);\n    void do_store(const address& host, result_handler handler);\n    void handle_timer(const code& ec);\n\n    // These are protected by a mutex.\n    list buffer_;\n    list backup_;\n    list inactive_;\n    std::atomic<bool> stopped_;\n    mutable upgrade_mutex mutex_;\n\n    // This is thread safe.\n    dispatcher dispatch_;\n\n    // HACK: we use this because the buffer capacity cannot be set to zero.\n    const bool disabled_;\n    const boost::filesystem::path file_path_;\n    threadpool& pool_;\n    deadline::ptr snap_timer_;\n\n    // record the seed count\n    const size_t seed_count;\n};\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n\n"
  },
  {
    "path": "include/UChain/network/locked_socket.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_LOCKED_SOCKET_HPP\n#define UC_LOCKED_SOCKET_HPP\n\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/network/define.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\n/// A wrapper to lock the socket until out of scope.\nclass BCT_API locked_socket\n  : track<locked_socket>\n{\npublic:\n    typedef std::shared_ptr<locked_socket> ptr;\n\n    locked_socket(asio::socket& socket, upgrade_mutex& mutex);\n    ~locked_socket();\n\n    /// Obtain exclusive reference to the socket.\n    /// The wrapper must be kept in scope while this reference is in use.\n    asio::socket& get();\n\nprivate:\n    asio::socket& socket_;\n    upgrade_mutex& mutex_;\n};\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/network/message_subscriber.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_MESSAGE_SUBSCRIBER_HPP\n#define UC_NETWORK_MESSAGE_SUBSCRIBER_HPP\n\n#include <istream>\n#include <functional>\n#include <map>\n#include <memory>\n#include <utility>\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/network/define.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\n#define DEFINE_SUBSCRIBER_TYPE(value) \\\n    typedef resubscriber<const code&, message::value::ptr> \\\n        value##_subscriber_type\n\n#define DEFINE_SUBSCRIBER_OVERLOAD(value) \\\n    template <typename Handler> \\\n    void subscribe(message::value&&, Handler&& handler) \\\n    { \\\n        value##_subscriber_->subscribe(std::forward<Handler>(handler), \\\n            error::channel_stopped, nullptr); \\\n    }\n\n#define DECLARE_SUBSCRIBER(value) \\\n    value##_subscriber_type::ptr value##_subscriber_\n\ntemplate <class Message>\nusing message_handler = std::function<bool(const code&,\n    std::shared_ptr<Message>)>;\n\n/// Aggregation of subscribers by messasge type, thread safe.\nclass BCT_API message_subscriber\n{\npublic:\n    DEFINE_SUBSCRIBER_TYPE(address);\n    DEFINE_SUBSCRIBER_TYPE(block_msg);\n    DEFINE_SUBSCRIBER_TYPE(block_txs);\n    DEFINE_SUBSCRIBER_TYPE(compact_block);\n    DEFINE_SUBSCRIBER_TYPE(fee_filter);\n    DEFINE_SUBSCRIBER_TYPE(filter_add);\n    DEFINE_SUBSCRIBER_TYPE(filter_clear);\n    DEFINE_SUBSCRIBER_TYPE(filter_load);\n    DEFINE_SUBSCRIBER_TYPE(get_address);\n    DEFINE_SUBSCRIBER_TYPE(get_blocks);\n    DEFINE_SUBSCRIBER_TYPE(get_block_txs);\n    DEFINE_SUBSCRIBER_TYPE(get_data);\n    DEFINE_SUBSCRIBER_TYPE(get_headers);\n    DEFINE_SUBSCRIBER_TYPE(headers);\n    DEFINE_SUBSCRIBER_TYPE(inventory);\n    DEFINE_SUBSCRIBER_TYPE(memory_pool);\n    DEFINE_SUBSCRIBER_TYPE(merkle_block);\n    DEFINE_SUBSCRIBER_TYPE(not_found);\n    DEFINE_SUBSCRIBER_TYPE(ping);\n    DEFINE_SUBSCRIBER_TYPE(pong);\n    DEFINE_SUBSCRIBER_TYPE(reject);\n    DEFINE_SUBSCRIBER_TYPE(send_headers);\n    DEFINE_SUBSCRIBER_TYPE(send_compact_blocks);\n    DEFINE_SUBSCRIBER_TYPE(tx_message);\n    DEFINE_SUBSCRIBER_TYPE(verack);\n    DEFINE_SUBSCRIBER_TYPE(version);\n\n    /**\n     * Create an instance of this class.\n     * @param[in]  pool  The threadpool to use for sending notifications.\n     */\n    message_subscriber(threadpool& pool);\n\n    /// This class is not copyable.\n    message_subscriber(const message_subscriber&) = delete;\n    void operator=(const message_subscriber&) = delete;\n\n    /**\n     * Subscribe to receive a notification when a message of type is received.\n     * The handler is unregistered when the call is made.\n     * Subscribing must be immediate, we cannot switch thread contexts.\n     * @param[in]  handler  The handler to register.\n     */\n    template <class Message, typename Handler>\n    void subscribe(Handler&& handler)\n    {\n        subscribe(Message(), std::forward<Handler>(handler));\n    }\n\n    /**\n     * Load a stream into a message instance and notify subscribers.\n     * @param[in]  stream      The stream from which to load the message.\n     * @param[in]  version  The peer protocol version.\n     * @param[in]  subscriber  The subscriber for the message type.\n     * @return                 Returns error::bad_stream if failed.\n     */\n    template <class Message, class Subscriber>\n    code relay(std::istream& stream, uint32_t version,\n        Subscriber subscriber) const\n    {\n        const auto message_ptr = std::make_shared<Message>();\n        const bool parsed = message_ptr->from_data(version, stream);\n        const code ec(parsed ? error::success : error::bad_stream);\n        subscriber->relay(ec, message_ptr);\n        return ec;\n    }\n\n    /**\n     * Load a stream into a message instance and invoke subscribers.\n     * @param[in]  stream      The stream from which to load the message.\n     * @param[in]  version  The peer protocol version.\n     * @param[in]  subscriber  The subscriber for the message type.\n     * @return                 Returns error::bad_stream if failed.\n     */\n    template <class Message, class Subscriber>\n    code handle(std::istream& stream, uint32_t version,\n        Subscriber subscriber) const\n    {\n        const auto message_ptr = std::make_shared<Message>();\n        const bool parsed = message_ptr->from_data(version, stream);\n        const code ec(parsed ? error::success : error::bad_stream);\n        subscriber->invoke(ec, message_ptr);\n        return ec;\n    }\n\n    /**\n     * Broadcast a default message instance with the specified error code.\n     * @param[in]  ec  The error code to broadcast.\n     */\n    virtual void broadcast(const code& ec);\n\n    /*\n     * Load a stream of the specified command type.\n     * Creates an instance of the indicated message type.\n     * Sends the message instance to each subscriber of the type.\n     * @param[in]  type     The stream message type identifier.\n     * @param[in]  version  The peer protocol version.\n     * @param[in]  stream   The stream from which to load the message.\n     * @return              Returns error::bad_stream if failed.\n     */\n    virtual code load(message::message_type type, uint32_t version,\n        std::istream& stream) const;\n\n    /**\n     * Start all subscribers so that they accept subscription.\n     */\n    virtual void start();\n\n    /**\n     * Stop all subscribers so that they no longer accept subscription.\n     */\n    virtual void stop();\n\nprivate:\n    DEFINE_SUBSCRIBER_OVERLOAD(address);\n    DEFINE_SUBSCRIBER_OVERLOAD(block_msg);\n    DEFINE_SUBSCRIBER_OVERLOAD(block_txs);\n    DEFINE_SUBSCRIBER_OVERLOAD(compact_block);\n    DEFINE_SUBSCRIBER_OVERLOAD(fee_filter);\n    DEFINE_SUBSCRIBER_OVERLOAD(filter_add);\n    DEFINE_SUBSCRIBER_OVERLOAD(filter_clear);\n    DEFINE_SUBSCRIBER_OVERLOAD(filter_load);\n    DEFINE_SUBSCRIBER_OVERLOAD(get_address);\n    DEFINE_SUBSCRIBER_OVERLOAD(get_blocks);\n    DEFINE_SUBSCRIBER_OVERLOAD(get_block_txs);\n    DEFINE_SUBSCRIBER_OVERLOAD(get_data);\n    DEFINE_SUBSCRIBER_OVERLOAD(get_headers);\n    DEFINE_SUBSCRIBER_OVERLOAD(headers);\n    DEFINE_SUBSCRIBER_OVERLOAD(inventory);\n    DEFINE_SUBSCRIBER_OVERLOAD(memory_pool);\n    DEFINE_SUBSCRIBER_OVERLOAD(merkle_block);\n    DEFINE_SUBSCRIBER_OVERLOAD(not_found);\n    DEFINE_SUBSCRIBER_OVERLOAD(ping);\n    DEFINE_SUBSCRIBER_OVERLOAD(pong);\n    DEFINE_SUBSCRIBER_OVERLOAD(reject);\n    DEFINE_SUBSCRIBER_OVERLOAD(send_headers);\n    DEFINE_SUBSCRIBER_OVERLOAD(send_compact_blocks);\n    DEFINE_SUBSCRIBER_OVERLOAD(tx_message);\n    DEFINE_SUBSCRIBER_OVERLOAD(verack);\n    DEFINE_SUBSCRIBER_OVERLOAD(version);\n\n    DECLARE_SUBSCRIBER(address);\n    DECLARE_SUBSCRIBER(block_msg);\n    DECLARE_SUBSCRIBER(block_txs);\n    DECLARE_SUBSCRIBER(compact_block);\n    DECLARE_SUBSCRIBER(fee_filter);\n    DECLARE_SUBSCRIBER(filter_add);\n    DECLARE_SUBSCRIBER(filter_clear);\n    DECLARE_SUBSCRIBER(filter_load);\n    DECLARE_SUBSCRIBER(get_address);\n    DECLARE_SUBSCRIBER(get_blocks);\n    DECLARE_SUBSCRIBER(get_block_txs);\n    DECLARE_SUBSCRIBER(get_data);\n    DECLARE_SUBSCRIBER(get_headers);\n    DECLARE_SUBSCRIBER(headers);\n    DECLARE_SUBSCRIBER(inventory);\n    DECLARE_SUBSCRIBER(memory_pool);\n    DECLARE_SUBSCRIBER(merkle_block);\n    DECLARE_SUBSCRIBER(not_found);\n    DECLARE_SUBSCRIBER(ping);\n    DECLARE_SUBSCRIBER(pong);\n    DECLARE_SUBSCRIBER(reject);\n    DECLARE_SUBSCRIBER(send_headers);\n    DECLARE_SUBSCRIBER(send_compact_blocks);\n    DECLARE_SUBSCRIBER(tx_message);\n    DECLARE_SUBSCRIBER(verack);\n    DECLARE_SUBSCRIBER(version);\n};\n\n#undef DEFINE_SUBSCRIBER_TYPE\n#undef DEFINE_SUBSCRIBER_OVERLOAD\n#undef DECLARE_SUBSCRIBER\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/network/p2p.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_P2P_HPP\n#define UC_NETWORK_P2P_HPP\n\n#include <atomic>\n#include <cstddef>\n#include <cstdint>\n#include <functional>\n#include <memory>\n#include <string>\n#include <vector>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/connections.hpp>\n#include <UChain/network/define.hpp>\n#include <UChain/network/hosts.hpp>\n#include <UChain/network/message_subscriber.hpp>\n#include <UChain/network/sessions/session_inbound.hpp>\n#include <UChain/network/sessions/session_manual.hpp>\n#include <UChain/network/sessions/session_outbound.hpp>\n#include <UChain/network/sessions/session_seed.hpp>\n#include <UChain/network/settings.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\n/// Top level public networking interface, partly thread safe.\nclass BCT_API p2p\n  : public enable_shared_from_base<p2p>\n{\npublic:\n    typedef std::shared_ptr<p2p> ptr;\n    typedef message::network_address address;\n    typedef std::function<void()> stop_handler;\n    typedef std::function<void(bool)> truth_handler;\n    typedef std::function<void(size_t)> count_handler;\n    typedef std::function<void(const code&)> result_handler;\n    typedef std::function<void(const code&, const address&)> address_handler;\n    typedef std::function<void(const code&, channel::ptr)> channel_handler;\n    typedef std::function<bool(const code&, channel::ptr)> connect_handler;\n    typedef subscriber<const code&> stop_subscriber;\n    typedef resubscriber<const code&, channel::ptr> channel_subscriber;\n\n    // Templates (send/receive).\n    // ------------------------------------------------------------------------\n\n    /// Send message to all connections.\n    template <typename Message>\n    void broadcast(Message&& message, channel_handler handle_channel,\n        result_handler handle_complete)\n    {\n        connections_->broadcast(message, handle_channel, handle_complete);\n    }\n\n    /// Subscribe to all incoming messages of a type.\n    template <class Message>\n    void subscribe(message_handler<Message>&& handler)\n    {\n        connections_->subscribe(\n            std::forward<message_handler<Message>>(handler));\n    }\n\n    // Constructors.\n    // ------------------------------------------------------------------------\n\n    /// Construct an instance.\n    p2p(const settings& settings);\n\n    /// This class is not copyable.\n    p2p(const p2p&) = delete;\n    void operator=(const p2p&) = delete;\n\n    /// Ensure all threads are coalesced.\n    virtual ~p2p();\n\n    // Start/Run sequences.\n    // ------------------------------------------------------------------------\n\n    /// Invoke startup and seeding sequence, call from constructing thread.\n    virtual void start(result_handler handler);\n\n    /// Synchronize the blockchain and then begin long running sessions,\n    /// call from start result handler. Call base method to skip sync.\n    virtual void run(result_handler handler);\n\n    // Shutdown.\n    // ------------------------------------------------------------------------\n\n    /// Idempotent call to signal work stop, start may be reinvoked after.\n    /// Returns the result of file save operation.\n    virtual bool stop();\n\n    /// Blocking call to coalesce all work and then terminate all threads.\n    /// Call from thread that constructed this class, or don't call at all.\n    /// This calls stop, and start may be reinvoked after calling this.\n    virtual bool close();\n\n    // Properties.\n    // ------------------------------------------------------------------------\n\n    /// Network configuration settings.\n    virtual const settings& network_settings() const;\n\n    /// Return the current block height.\n    virtual size_t height() const;\n\n    /// Set the current block height, for use in version messages.\n    virtual void set_height(size_t value);\n\n    /// Determine if the network is stopped.\n    virtual bool stopped() const;\n\n    /// Return a reference to the network threadpool.\n    virtual threadpool& thread_pool();\n\n    // Subscriptions.\n    // ------------------------------------------------------------------------\n\n    /// Subscribe to connection creation events.\n    virtual void subscribe_connection(connect_handler handler);\n\n    /// Subscribe to service stop event.\n    virtual void subscribe_stop(result_handler handler);\n\n    // Manual connections.\n    // ----------------------------------------------------------------------------\n\n    /// Maintain a connection to hostname:port.\n    virtual void connect(const config::endpoint& peer);\n\n    /// Maintain a connection to hostname:port.\n    virtual void connect(const std::string& hostname, uint16_t port);\n\n    /// Maintain a connection to hostname:port.\n    /// The callback is invoked by the first connection creation only.\n    virtual void connect(const std::string& hostname, uint16_t port,\n        channel_handler handler);\n\n    // Connections collection.\n    // ------------------------------------------------------------------------\n\n    /// Determine if there exists a connection to the address.\n    virtual void connected(const address& address, truth_handler handler);\n\n    /// Store a connection.\n    virtual void store(channel::ptr channel, result_handler handler);\n\n    /// Remove a connection.\n    virtual void remove(channel::ptr channel, result_handler handler);\n\n    /// Get the number of connections.\n    virtual void connected_count(count_handler handler);\n\n    // Hosts collection.\n    // ------------------------------------------------------------------------\n\n    /// Get a randomly-selected address.\n    virtual void fetch_address(const config::authority::list& excluded_list, address_handler handler);\n\n    ///Get authority of all connections\n    config::authority::list authority_list();\n\n    /// Store an address.\n    virtual void store(const address& address, result_handler handler);\n\n    /// Store a collection of addresses.\n    virtual void store(const address::list& addresses, result_handler handler);\n\n    /// Remove an address.\n    virtual void remove(const address& address, result_handler handler);\n\n    /// Get the number of addresses.\n    virtual void address_count(count_handler handler);\n\n    address::list address_list();\n\n    /// Get connection pool.\n    virtual connections::ptr connections_ptr();\n\n    //upnp functions\n    virtual void map_port(bool use_upnp);\n#ifdef USE_UPNP\n    static void thread_map_port(uint16_t map_port);\n    config::authority::ptr get_out_address();\n#endif\n\n    //restart the seeding session\n    void restart_seeding();\n\nprotected:\n\n    /// Attach a session to the network, caller must start the session.\n    template <class Session, typename... Args>\n    typename Session::ptr attach(Args&&... args)\n    {\n        return std::make_shared<Session>(*this, std::forward<Args>(args)...);\n    }\n\n    /// Override to attach specialized sessions.\n    virtual session_seed::ptr attach_seed_session();\n    virtual session_manual::ptr attach_manual_session();\n    virtual session_inbound::ptr attach_inbound_session();\n    virtual session_outbound::ptr attach_outbound_session();\n\nprivate:\n    void handle_manual_started(const code& ec, result_handler handler);\n    void handle_inbound_started(const code& ec, result_handler handler);\n    void handle_hosts_loaded(const code& ec, result_handler handler);\n    void handle_hosts_saved(const code& ec, result_handler handler);\n    void handle_new_connection(const code& ec, channel::ptr channel,\n        result_handler handler);\n\n    void handle_started(const code& ec, result_handler handler);\n    void handle_running(const code& ec, result_handler handler);\n\n    const settings& settings_;\n\n    // These are thread safe.\n    std::atomic<bool> stopped_;\n    std::atomic<size_t> height_;\n    bc::atomic<session_manual::ptr> manual_;\n    threadpool threadpool_;\n    hosts::ptr hosts_;\n    connections::ptr connections_;\n    stop_subscriber::ptr stop_subscriber_;\n    channel_subscriber::ptr channel_subscriber_;\n    session_seed::ptr seed;\n};\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/network/pending_channels.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_PENDING_CHANNELS_HPP\n#define UC_NETWORK_PENDING_CHANNELS_HPP\n\n#include <cstdint>\n#include <functional>\n#include <vector>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/define.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\n/// Class to manage a pending channel pool, thread and lock safe.\nclass BCT_API pending_channels\n{\npublic:\n    typedef std::function<void(bool)> truth_handler;\n    typedef std::function<void(const code&)> result_handler;\n\n    pending_channels();\n    ~pending_channels();\n\n    /// This class is not copyable.\n    pending_channels(const pending_channels&) = delete;\n    void operator=(const pending_channels&) = delete;\n\n    virtual void store(channel::ptr channel, result_handler handler);\n    virtual void remove(channel::ptr channel, result_handler handler);\n    virtual void exists(uint64_t version_nonce, truth_handler handler) const;\n\nprivate:\n    typedef std::vector<channel::ptr> list;\n\n    bool safe_store(channel::ptr channel);\n    bool safe_remove(channel::ptr channel);\n    bool safe_exists(uint64_t version_nonce) const;\n\n    list channels_;\n    mutable upgrade_mutex mutex_;\n};\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n\n"
  },
  {
    "path": "include/UChain/network/pending_sockets.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_PENDING_SOCKETS_HPP\n#define UC_NETWORK_PENDING_SOCKETS_HPP\n\n#include <vector>\n#include <UChain/coin.hpp>\n#include <UChain/network/define.hpp>\n#include <UChain/network/socket.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\n/// Class to manage a pending socket pool, thread and lock safe.\nclass BCT_API pending_sockets\n{\npublic:\n    pending_sockets();\n    ~pending_sockets();\n\n    /// This class is not copyable.\n    pending_sockets(const pending_sockets&) = delete;\n    void operator=(const pending_sockets&) = delete;\n\n    virtual void clear();\n    virtual void store(socket::ptr socket);\n    virtual void remove(socket::ptr socket);\n\nprivate:\n    typedef std::vector<socket::ptr> list;\n\n    bool safe_clear();\n    bool safe_store(socket::ptr socket);\n    bool safe_remove(socket::ptr socket);\n\n    list sockets_;\n    mutable shared_mutex mutex_;\n};\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n\n"
  },
  {
    "path": "include/UChain/network/protocols/protocol.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_PROTOCOL_HPP\n#define UC_NETWORK_PROTOCOL_HPP\n\n#include <functional>\n#include <memory>\n#include <string>\n#include <utility>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/define.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\n#define PROTOCOL_ARGS(handler, args) \\\n    std::forward<Handler>(handler), \\\n    shared_from_base<Protocol>(), \\\n    std::forward<Args>(args)...\n#define BOUND_PROTOCOL(handler, args) \\\n    std::bind(PROTOCOL_ARGS(handler, args))\n\n#define PROTOCOL_ARGS_TYPE(handler, args) \\\n    std::forward<Handler>(handler), \\\n    std::shared_ptr<Protocol>(), \\\n    std::forward<Args>(args)...\n#define BOUND_PROTOCOL_TYPE(handler, args) \\\n    std::bind(PROTOCOL_ARGS_TYPE(handler, args))\n\nclass p2p;\n\n/// Virtual base class for protocol implementation, mostly thread safe.\nclass BCT_API protocol\n  : public enable_shared_from_base<protocol>\n{\nprotected:\n    typedef std::shared_ptr<protocol> ptr;\n    typedef std::function<void()> completion_handler;\n    typedef std::function<void(const code&)> event_handler;\n    typedef std::function<void(const code&, size_t)> count_handler;\n\n    /// Construct an instance.\n    protocol(p2p& network, channel::ptr channel, const std::string& name);\n\n    /// This class is not copyable.\n    protocol(const protocol&) = delete;\n    void operator=(const protocol&) = delete;\n\n    /// Bind a method in the derived class.\n    template <class Protocol, typename Handler, typename... Args>\n    auto bind(Handler&& handler, Args&&... args) ->\n        decltype(BOUND_PROTOCOL_TYPE(handler, args))\n    {\n        return BOUND_PROTOCOL(handler, args);\n    }\n\n    /// Send a message on the channel and handle the result.\n    template <class Protocol, class Message, typename Handler, typename... Args>\n    void send(Message&& packet, Handler&& handler, Args&&... args)\n    {\n        channel_->send(std::forward<Message>(packet),\n            BOUND_PROTOCOL(handler, args));\n    }\n\n    /// Subscribe to all channel messages, blocking until subscribed.\n    template <class Protocol, class Message, typename Handler, typename... Args>\n    void subscribe(Handler&& handler, Args&&... args)\n    {\n        channel_->template subscribe<Message>(BOUND_PROTOCOL(handler, args));\n    }\n\n    /// Subscribe to the channel stop, blocking until subscribed.\n    template <class Protocol, typename Handler, typename... Args>\n    void subscribe_stop(Handler&& handler, Args&&... args)\n    {\n        channel_->subscribe_stop(BOUND_PROTOCOL(handler, args));\n    }\n\n    /// Get the address of the channel.\n    virtual config::authority authority() const;\n\n    /// Get the protocol name, for logging purposes.\n    virtual const std::string& name() const;\n\n    /// Get the channel nonce.\n    virtual uint64_t nonce() const;\n\n    /// Get the peer version message. This method is NOT thread safe and must\n    /// not be called if any other thread could write the peer version.\n    virtual message::version peer_version() const;\n\n    /// Set the channel version. This method is NOT thread safe and must\n    /// complete before any other thread could read the peer version.\n    virtual void set_peer_version(message::version::ptr value);\n\n    uint32_t peer_start_height();\n\n    /// Get the threadpool.\n    virtual threadpool& pool();\n\n    /// Stop the channel (and the protocol).\n    virtual void stop(const code& ec);\n\n    virtual bool misbehaving(int32_t howmuch);\n\n    bool channel_stopped() { return channel_->stopped(); }\n\nprivate:\n    threadpool& pool_;\n    channel::ptr channel_;\n    const std::string name_;\n};\n\n#undef PROTOCOL_ARGS\n#undef BOUND_PROTOCOL\n#undef PROTOCOL_ARGS_TYPE\n#undef BOUND_PROTOCOL_TYPE\n\n#define BIND1(method, p1) \\\n    bind<CLASS>(&CLASS::method, p1)\n#define BIND2(method, p1, p2) \\\n    bind<CLASS>(&CLASS::method, p1, p2)\n#define BIND3(method, p1, p2, p3) \\\n    bind<CLASS>(&CLASS::method, p1, p2, p3)\n\n#define SEND1(message, method, p1) \\\n    send<CLASS>(message, &CLASS::method, p1)\n#define SEND2(message, method, p1, p2) \\\n    send<CLASS>(message, &CLASS::method, p1, p2)\n#define SEND3(message, method, p1, p2, p3) \\\n    send<CLASS>(message, &CLASS::method, p1, p2, p3)\n\n#define SUBSCRIBE2(message, method, p1, p2) \\\n    subscribe<CLASS, message>(&CLASS::method, p1, p2)\n#define SUBSCRIBE3(message, method, p1, p2, p3) \\\n    subscribe<CLASS, message>(&CLASS::method, p1, p2, p3)\n#define SUBSCRIBE4(message, method, p1, p2, p3, p4) \\\n    subscribe<CLASS, message>(&CLASS::method, p1, p2, p3, p4)\n\n\n#define SUBSCRIBE_STOP1(method, p1) \\\n    subscribe_stop<CLASS>(&CLASS::method, p1)\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/network/protocols/protocol_address.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_PROTOCOL_ADDRESS_HPP\n#define UC_NETWORK_PROTOCOL_ADDRESS_HPP\n\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/define.hpp>\n#include <UChain/network/protocols/protocol_events.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\nclass p2p;\n\n/**\n * Address protocol.\n * Attach this to a channel immediately following handshake completion.\n */\nclass BCT_API protocol_address\n  : public protocol_events, track<protocol_address>\n{\npublic:\n    typedef std::shared_ptr<protocol_address> ptr;\n\n    /**\n     * Construct an address protocol instance.\n     * @param[in]  network   The network interface.\n     * @param[in]  channel   The channel on which to start the protocol.\n     */\n    protocol_address(p2p& network, channel::ptr channel);\n\n    ptr do_subscribe();\n\n    /**\n     * Start the protocol.\n     */\n    virtual void start();\n\nprivate:\n    void handle_stop(const code& ec);\n    void handle_store_addresses(const code& ec, message::address::ptr message);\n    void remove_useless_address(message::address::ptr& message);\n    bool handle_receive_address(const code& ec, message::address::ptr address);\n    bool handle_receive_get_address(const code& ec,\n        message::get_address::ptr message);\n\n    p2p& network_;\n    message::address self_;\n};\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/network/protocols/protocol_events.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_PROTOCOL_EVENTS_HPP\n#define UC_NETWORK_PROTOCOL_EVENTS_HPP\n\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/define.hpp>\n#include <UChain/network/protocols/protocol.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\nclass p2p;\n\n/**\n * Base class for stateful protocol implementation, thread and lock safe.\n */\nclass BCT_API protocol_events\n  : public protocol\n{\nprotected:\n\n    /**\n     * Construct a protocol instance.\n     * @param[in]  network   The network interface.\n     * @param[in]  channel   The channel on which to start the protocol.\n     * @param[in]  name      The instance name for logging purposes.\n     */\n    protocol_events(p2p& network, channel::ptr channel,\n        const std::string& name);\n\n    /**\n     * Start the protocol.\n     * The event handler may be invoked one or more times.\n     * @param[in]  handler  The handler to call at each completion event.\n     */\n    virtual void start(event_handler handler);\n\n    /**\n     * Invoke the event handler.\n     * @param[in]  ec  The error code of the preceding operation.\n     */\n    virtual void set_event(const code& ec);\n\n    /**\n     * Determine if the event handler has been cleared.\n     */\n    virtual bool stopped();\n\nprotected:\n    void handle_send(const code& ec, const std::string& command);\n\nprivate:\n    void handle_started(completion_handler handler);\n    void handle_stopped(const code& ec);\n    void do_set_event(const code& ec);\n\n    bc::atomic<event_handler> handler_;\n};\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/network/protocols/protocol_ping.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_PROTOCOL_PING_HPP\n#define UC_NETWORK_PROTOCOL_PING_HPP\n\n#include <cstdint>\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/define.hpp>\n#include <UChain/network/protocols/protocol_timer.hpp>\n#include <UChain/network/settings.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\nclass p2p;\n\n/**\n * Ping-pong protocol.\n * Attach this to a channel immediately following handshake completion.\n */\nclass BCT_API protocol_ping\n  : public protocol_timer, track<protocol_ping>\n{\npublic:\n    typedef std::shared_ptr<protocol_ping> ptr;\n\n    /**\n     * Construct a ping protocol instance.\n     * @param[in]  network   The network interface.\n     * @param[in]  channel   The channel on which to start the protocol.\n     */\n    protocol_ping(p2p& network, channel::ptr channel);\n\n    ptr do_subscribe();\n\n    /**\n     * Start the protocol.\n     */\n    virtual void start();\n\n    void handle_or_not(uint64_t nonce);\n\nprivate:\n    void send_ping(const code& ec);\n    void test_call_handler(const code& ec);\n    bool handle_receive_ping(const code& ec, message::ping::ptr message);\n    bool handle_receive_pong(const code& ec, message::pong::ptr message,\n        uint64_t nonce);\n\n    const settings& settings_;\n};\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/network/protocols/protocol_seed.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_PROTOCOL_SEED_HPP\n#define UC_NETWORK_PROTOCOL_SEED_HPP\n\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/define.hpp>\n#include <UChain/network/protocols/protocol_timer.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\nclass p2p;\n\n/**\n * Seeding protocol.\n * Attach this to a channel immediately following seed handshake completion.\n */\nclass BCT_API protocol_seed\n  : public protocol_timer, track<protocol_seed>\n{\npublic:\n    typedef std::shared_ptr<protocol_seed> ptr;\n\n    /**\n     * Construct a seed protocol instance.\n     * @param[in]  network   The network interface.\n     * @param[in]  channel   The channel on which to start the protocol.\n     */\n    protocol_seed(p2p& network, channel::ptr channel);\n\n    /**\n     * Start the protocol.\n     * @param[in]  handler   Invoked upon stop or complete.\n     */\n    virtual void start(event_handler handler);\n\nprivate:\n    void send_own_address(const settings& settings);\n\n    void handle_send_address(const code& ec);\n    void handle_send_get_address(const code& ec);\n    void handle_store_addresses(const code& ec);\n    void handle_seeding_complete(const code& ec, event_handler handler);\n\n    bool handle_receive_address(const code& ec, message::address::ptr address);\n    ////bool handle_receive_get_address(const code& ec,\n    ////    message::get_address::ptr message);\n\n    p2p& network_;\n    const config::authority self_;\n};\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/network/protocols/protocol_timer.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_PROTOCOL_TIMER_HPP\n#define UC_NETWORK_PROTOCOL_TIMER_HPP\n\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/define.hpp>\n#include <UChain/network/protocols/protocol_events.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\nclass p2p;\n\n/**\n * Base class for timed protocol implementation.\n */\nclass BCT_API protocol_timer\n  : public protocol_events\n{\nprotected:\n\n    /**\n     * Construct a timed protocol instance.\n     * @param[in]  network   The network interface.\n     * @param[in]  channel    The channel on which to start the protocol.\n     * @param[in]  perpetual  Set for automatic timer reset unless stopped.\n     * @param[in]  name       The instance name for logging purposes.\n     */\n    protocol_timer(p2p& network, channel::ptr channel, bool perpetual,\n        const std::string& name);\n\n    /**\n     * Define the event handler and start the protocol and timer.\n     * The timer is automatically canceled on stop (only).\n     * The timer is suspended while the handler is executing.\n     * @param[in]  timeout  The timer period (not automatically reset).\n     * @param[in]  handler  Invoke automatically on stop and timer events.\n     */\n    virtual void start(const asio::duration& timeout, event_handler handler);\n\nprotected:\n    void reset_timer();\n\nprivate:\n    void handle_timer(const code& ec);\n    void handle_notify(const code& ec, event_handler handler);\n\n    const bool perpetual_;\n    deadline::ptr timer_;\n};\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/network/protocols/protocol_version.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_PROTOCOL_VERSION_HPP\n#define UC_NETWORK_PROTOCOL_VERSION_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/define.hpp>\n#include <UChain/network/protocols/protocol_timer.hpp>\n#include <UChain/network/settings.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\nclass p2p;\n\nclass BCT_API protocol_version\n  : public protocol_timer, track<protocol_version>\n{\npublic:\n    typedef std::shared_ptr<protocol_version> ptr;\n\n    /**\n     * Construct a version protocol instance.\n     * @param[in]  network   The network interface.\n     * @param[in]  channel   The channel on which to start the protocol.\n     */\n    protocol_version(p2p& network, channel::ptr channel);\n\n    /**\n     * Start the protocol.\n     * @param[in]  handler  Invoked upon stop or receipt of version and verack.\n     */\n    virtual void start(event_handler handler);\n\nprotected:\n    void handle_complete(const code& ec);\n    /// Override to vary the version message.\n    virtual void send_version(const message::version& self);\n\nprivate:\n    static message::version version_factory(\n        const config::authority& authority, const settings& settings,\n        uint64_t nonce, size_t height);\n\n    void handle_version_sent(const code& ec);\n    void handle_verack_sent(const code& ec);\n\n    bool handle_receive_version(const code& ec, message::version::ptr version);\n    bool handle_receive_verack(const code& ec, message::verack::ptr);\n\n    p2p& network_;\n    std::function<void(const code& ec)> complete_handler_;\n};\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n\n"
  },
  {
    "path": "include/UChain/network/proxy.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_PROXY_HPP\n#define UC_NETWORK_PROXY_HPP\n\n#include <atomic>\n#include <cstddef>\n#include <cstdint>\n#include <functional>\n#include <memory>\n#include <set>\n#include <string>\n#include <utility>\n#include <UChain/coin.hpp>\n#include <UChain/network/const_buffer.hpp>\n#include <UChain/network/define.hpp>\n#include <UChain/network/message_subscriber.hpp>\n#include <UChain/network/socket.hpp>\n#include <UChain/coin/utility/dispatcher.hpp>\n#include <boost/thread.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\n/// Manages all socket communication, thread safe.\nclass BCT_API proxy\n  : public enable_shared_from_base<proxy>\n{\npublic:\n    typedef std::shared_ptr<proxy> ptr;\n    typedef std::function<void()> completion_handler;\n    typedef std::function<void(const code&)> result_handler;\n    typedef subscriber<const code&> stop_subscriber;\n    typedef resubscriber<const code&, const std::string&, const_buffer,\n        result_handler> send_subscriber;\n    using request_callback = std::function<void()>;\n\n    /// Construct an instance.\n    proxy(threadpool& pool, socket::ptr socket, uint32_t protocol_magic,\n        uint32_t protocol_version);\n\n    /// Validate proxy stopped.\n    ~proxy();\n\n    /// This class is not copyable.\n    proxy(const proxy&) = delete;\n    void operator=(const proxy&) = delete;\n\n    /// Send a message on the socket.\n    template <class Message>\n    void send(const Message& message, result_handler handler)\n    {\n        const auto buffer = const_buffer(message::serialize(protocol_version_,\n            message, protocol_magic_));\n        do_send(message.command, buffer, handler);\n    }\n\n    /// Subscribe to messages of the specified type on the socket.\n    template <class Message>\n    void subscribe(message_handler<Message>&& handler)\n    {\n        auto stopped = std::forward<message_handler<Message>>(handler);\n        message_subscriber_.subscribe<Message>(stopped);\n    }\n\n    /// Subscribe to the stop event.\n    virtual void subscribe_stop(result_handler handler);\n\n    /// Get the authority of the far end of this socket.\n    virtual const config::authority& authority() const;\n\n    /// Get the p2p protocol version object of the peer.\n    virtual message::version version() const;\n\n    /// Save the p2p protocol version object of the peer.\n    virtual void set_version(message::version::ptr value);\n\n    uint32_t peer_start_height() { return peer_version_message_.load() ? peer_version_message_.load()->start_height : 0; }\n\n    /// Read messages from this socket.\n    virtual void start(result_handler handler);\n\n    /// Stop reading or sending messages on this socket.\n    virtual void stop(const code& ec);\n\n    void dispatch();\n\n    static bool blacklisted(const config::authority&);\n    static bool manualbanned(const config::authority& authority);\n    static void manual_ban(const config::authority&);\n    static void manual_unban(const config::authority&);\n\n    virtual bool misbehaving(int32_t howmuch);\n\n    virtual bool stopped() const;\nprotected:\n    virtual void handle_activity() = 0;\n    virtual void handle_stopping() = 0;\n\nprivate:\n    typedef byte_source<data_chunk> payload_source;\n    typedef boost::iostreams::stream<payload_source> payload_stream;\n\n    static config::authority authority_factory(socket::ptr socket);\n\n    void do_close();\n    void stop(const boost_code& ec);\n\n    void read_heading();\n    void handle_read_heading(const boost_code& ec, size_t payload_size);\n\n    void read_payload(const message::heading& head);\n    void handle_read_payload(const boost_code& ec, size_t,\n        const message::heading& head);\n\n    void do_send(const std::string& command, const_buffer buffer,\n        result_handler handler);\n    void handle_send(const boost_code& ec, const_buffer buffer,\n        result_handler handler);\n\n    void handle_request(data_chunk payload_buffer, uint32_t protocol_version_, message::heading head, size_t payload_size);\n\n    const uint32_t protocol_magic_;\n    const uint32_t protocol_version_;\n    const config::authority authority_;\n\n    // These are protected by sequential ordering.\n    data_chunk heading_buffer_;\n    data_chunk payload_buffer_;\n\n    dispatcher dispatch_;\n\n    // These are thread safe.\n    socket::ptr socket_;\n    std::atomic<bool> stopped_;\n    std::atomic<uint32_t> peer_protocol_version_;\n    bc::atomic<message::version::ptr> peer_version_message_;\n    message_subscriber message_subscriber_;\n    stop_subscriber::ptr stop_subscriber_;\n    std::queue<request_callback> outbound_queue_;\n    std::atomic_bool has_sent_;\n\n    std::atomic_int misbehaving_;\n    static boost::detail::spinlock spinlock_;\n    static std::map<config::authority, int64_t> banned_;\n\n    static boost::detail::spinlock manual_banned_spinlock_;\n    static std::list<config::authority> manual_banned_;\n};\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n\n"
  },
  {
    "path": "include/UChain/network/sessions/session.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_SESSION_HPP\n#define UC_NETWORK_SESSION_HPP\n\n#include <atomic>\n#include <cstddef>\n#include <functional>\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/network/acceptor.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/connections.hpp>\n#include <UChain/network/connector.hpp>\n#include <UChain/network/define.hpp>\n#include <UChain/network/pending_channels.hpp>\n#include <UChain/network/proxy.hpp>\n#include <UChain/network/settings.hpp>\n#include <UChain/coin/message/network_address.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\n// Base session type.\n\n#define BASE_ARGS(handler, args) \\\n    std::forward<Handler>(handler), \\\n    shared_from_this(), \\\n    std::forward<Args>(args)...\n#define BOUND_BASE(handler, args) \\\n    std::bind(BASE_ARGS(handler, args))\n\n#define BASE_ARGS_TYPE(handler, args) \\\n    std::forward<Handler>(handler), \\\n    std::shared_ptr<session>(), \\\n    std::forward<Args>(args)...\n#define BOUND_BASE_TYPE(handler, args) \\\n    std::bind(BASE_ARGS_TYPE(handler, args))\n\n// Derived session types.\n\n#define SESSION_ARGS(handler, args) \\\n    std::forward<Handler>(handler), \\\n    shared_from_base<Session>(), \\\n    std::forward<Args>(args)...\n#define BOUND_SESSION(handler, args) \\\n    std::bind(SESSION_ARGS(handler, args))\n\n#define SESSION_ARGS_TYPE(handler, args) \\\n    std::forward<Handler>(handler), \\\n    std::shared_ptr<Session>(), \\\n    std::forward<Args>(args)...\n#define BOUND_SESSION_TYPE(handler, args) \\\n    std::bind(SESSION_ARGS_TYPE(handler, args))\n\nclass p2p;\n\n/// Base class for maintaining the lifetime of a channel set, thread safe.\nclass BCT_API session\n  : public enable_shared_from_base<session>\n{\npublic:\n    typedef std::shared_ptr<session> ptr;\n    typedef config::authority authority;\n    typedef std::function<void(bool)> truth_handler;\n    typedef std::function<void(size_t)> count_handler;\n    typedef std::function<void(const code&)> result_handler;\n    typedef std::function<void(const code&, channel::ptr)> channel_handler;\n    typedef std::function<void(const code&, acceptor::ptr)> accept_handler;\n    typedef std::function<void(const code&, const authority&)> host_handler;\n\n    /// Start the session, invokes handler once stop is registered.\n    virtual void start(result_handler handler);\n\n    /// Subscribe to receive session stop notification.\n    virtual void subscribe_stop(result_handler handler);\n\nprotected:\n\n    /// Construct an instance.\n    session(p2p& network, bool outgoing, bool persistent);\n\n    /// Validate session stopped.\n    ~session();\n\n    /// This class is not copyable.\n    session(const session&) = delete;\n    void operator=(const session&) = delete;\n\n    /// Attach a protocol to a channel, caller must start the channel.\n    template <class Protocol, typename... Args>\n    typename Protocol::ptr attach(channel::ptr channel, Args&&... args)\n    {\n        return std::make_shared<Protocol>(network_, channel,\n            std::forward<Args>(args)...);\n    }\n\n    /// Bind a method in the derived class.\n    template <class Session, typename Handler, typename... Args>\n    auto bind(Handler&& handler, Args&&... args) ->\n        decltype(BOUND_SESSION_TYPE(handler, args))\n    {\n        return BOUND_SESSION(handler, args);\n    }\n\n    /////// Dispatch a concurrent method in the derived class.\n    ////template <class Session, typename Handler, typename... Args>\n    ////void concurrent(Handler&& handler, Args&&... args)\n    ////{\n    ////    return dispatch_.concurrent(SESSION_ARGS(handler, args));\n    ////}\n\n    /// Bind a concurrent delegate to a method in the derived class.\n    template <class Session, typename Handler, typename... Args>\n    auto concurrent_delegate(Handler&& handler, Args&&... args) ->\n        delegates::concurrent<decltype(BOUND_SESSION_TYPE(handler, args))>\n    {\n        return dispatch_.concurrent_delegate(SESSION_ARGS(handler, args));\n    }\n\n    /// Properties.\n    virtual void address_count(count_handler handler);\n    virtual void fetch_address(host_handler handler);\n    virtual void connection_count(count_handler handler);\n    virtual bool blacklisted(const authority& authority) const;\n    virtual bool stopped() const;\n\n    void remove(const message::network_address& address, result_handler handler);\n\n    void store(const message::network_address& address);\n\n    /// Socket creators.\n    virtual acceptor::ptr create_acceptor();\n    virtual connector::ptr create_connector();\n\n    /// Override to attach specialized handshake protocols upon session start.\n    virtual void attach_handshake_protocols(channel::ptr channel,\n        result_handler handle_started);\n\n    /// Register a new channel with the session and bind its handlers.\n    virtual void register_channel(channel::ptr channel,\n        result_handler handle_started, result_handler handle_stopped);\n\n    // TODO: create session_timer base class.\n    threadpool& pool_;\n\n    const settings& settings_;\n\nprivate:\n\n    /// Bind a method in the base class.\n    template <typename Handler, typename... Args>\n    auto base_bind(Handler&& handler, Args&&... args) ->\n        decltype(BOUND_BASE_TYPE(handler, args))\n    {\n        return BOUND_BASE(handler, args);\n    }\n\n    // Socket creators.\n    void do_stop_acceptor(const code& ec, acceptor::ptr connect);\n    void do_stop_connector(const code& ec, connector::ptr connect);\n\n    // Start sequence.\n    void do_stop_session(const code&);\n\n    // Connect sequence\n    void new_connect(connector::ptr connect, channel_handler handler);\n    void start_connect(const code& ec, const authority& host,\n        connector::ptr connect, channel_handler handler);\n    void handle_connect(const code& ec, channel::ptr channel,\n        const authority& host, connector::ptr connect,\n        channel_handler handler);\n\n    // Registration sequence.\n    void handle_channel_start(const code& ec, channel::ptr channel,\n        result_handler handle_started);\n    void handle_pend(const code& ec, channel::ptr channel,\n        result_handler handle_started);\n    void handle_handshake(const code& ec, channel::ptr channel,\n        result_handler handle_started);\n    void handle_is_pending(bool pending, channel::ptr channel,\n        result_handler handle_started);\n    void handle_start(const code& ec, channel::ptr channel,\n        result_handler handle_started, result_handler handle_stopped);\n    void do_unpend(const code& ec, channel::ptr channel,\n        result_handler handle_started);\n    void do_remove(const code& ec, channel::ptr channel,\n        result_handler handle_stopped);\n    void handle_unpend(const code& ec);\n    void handle_remove(const code& ec);\n\n    std::atomic<bool> stopped_;\n    const bool incoming_;\n    const bool notify_;\n\n    // These are thread safe.\n    p2p& network_;\n    dispatcher dispatch_;\n    pending_channels pending_;\n};\n\n// Base session type.\n\n#undef BASE_ARGS\n#undef BOUND_BASE\n#undef BASE_ARGS_TYPE\n#undef BOUND_BASE_TYPE\n\n// Derived session types.\n\n#undef SESSION_ARGS\n#undef BOUND_SESSION\n#undef SESSION_ARGS_TYPE\n#undef BOUND_SESSION_TYPE\n\n#define BIND1(method, p1) \\\n    bind<CLASS>(&CLASS::method, p1)\n#define BIND2(method, p1, p2) \\\n    bind<CLASS>(&CLASS::method, p1, p2)\n#define BIND3(method, p1, p2, p3) \\\n    bind<CLASS>(&CLASS::method, p1, p2, p3)\n#define BIND4(method, p1, p2, p3, p4) \\\n    bind<CLASS>(&CLASS::method, p1, p2, p3, p4)\n#define BIND5(method, p1, p2, p3, p4, p5) \\\n    bind<CLASS>(&CLASS::method, p1, p2, p3, p4, p5)\n#define BIND6(method, p1, p2, p3, p4, p5, p6) \\\n    bind<CLASS>(&CLASS::method, p1, p2, p3, p4, p5, p6)\n#define BIND7(method, p1, p2, p3, p4, p5, p6, p7) \\\n    bind<CLASS>(&CLASS::method, p1, p2, p3, p4, p5, p6, p7)\n\n#define CONCURRENT2(method, p1, p2) \\\n    concurrent_delegate<CLASS>(&CLASS::method, p1, p2)\n\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/network/sessions/session_batch.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_SESSION_BATCH_HPP\n#define UC_NETWORK_SESSION_BATCH_HPP\n\n#include <atomic>\n#include <cstddef>\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/connector.hpp>\n#include <UChain/network/define.hpp>\n#include <UChain/network/sessions/session.hpp>\n#include <UChain/network/settings.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\nclass p2p;\n\n/// Intermediate base class for adding batch connect sequence.\nclass BCT_API session_batch\n  : public session\n{\nprotected:\n\n    /// Construct an instance.\n    session_batch(p2p& network, bool persistent);\n\n    /// Create a channel from the configured number of concurrent attempts.\n    virtual void connect(connector::ptr connect, channel_handler handler);\n\nprivate:\n    typedef std::atomic<size_t> atomic_counter;\n    typedef std::shared_ptr<atomic_counter> atomic_counter_ptr;\n    typedef std::shared_ptr<upgrade_mutex> upgrade_mutex_ptr;\n\n    void converge(const code& ec, channel::ptr channel,\n        atomic_counter_ptr counter, upgrade_mutex_ptr mutex,\n        channel_handler handler);\n\n    // Connect sequence\n    void new_connect(connector::ptr connect, atomic_counter_ptr counter,\n        channel_handler handler);\n    void start_connect(const code& ec, const authority& host,\n        connector::ptr connect, atomic_counter_ptr counter,\n        channel_handler handler);\n    void handle_connect(const code& ec, channel::ptr channel,\n        const authority& host, connector::ptr connect,\n        atomic_counter_ptr counter, std::size_t count, channel_handler handler);\n\n    const size_t batch_size_;\n};\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/network/sessions/session_inbound.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_SESSION_INBOUND_HPP\n#define UC_NETWORK_SESSION_INBOUND_HPP\n\n#include <cstddef>\n#include <memory>\n#include <vector>\n#include <UChain/coin.hpp>\n#include <UChain/network/acceptor.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/define.hpp>\n#include <UChain/network/sessions/session.hpp>\n#include <UChain/network/settings.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\nclass p2p;\n\n/// Inbound connections session, thread safe.\nclass BCT_API session_inbound\n  : public session, track<session_inbound>\n{\npublic:\n    typedef std::shared_ptr<session_inbound> ptr;\n\n    /// Construct an instance.\n    session_inbound(p2p& network);\n\n    /// Start the session.\n    void start(result_handler handler) override;\n\nprotected:\n    /// Override to attach specialized protocols upon channel start.\n    virtual void attach_protocols(channel::ptr channel);\n\nprivate:\n    void start_accept(const code& ec, acceptor::ptr accept);\n    void handle_started(const code& ec, result_handler handler);\n    void handle_is_loopback(bool loopback, channel::ptr channel);\n    void handle_connection_count(size_t connections, channel::ptr channel);\n    void handle_accept(const code& ec, channel::ptr channel,\n        acceptor::ptr accept);\n\n    void handle_channel_start(const code& ec, channel::ptr channel);\n    void handle_channel_stop(const code& ec);\n    p2p& network_;\n};\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/network/sessions/session_manual.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_SESSION_MANUAL_HPP\n#define UC_NETWORK_SESSION_MANUAL_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <memory>\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/connector.hpp>\n#include <UChain/network/define.hpp>\n#include <UChain/network/sessions/session_batch.hpp>\n#include <UChain/network/settings.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\nclass p2p;\n\n/// Manual connections session, thread safe.\nclass BCT_API session_manual\n  : public session_batch, track<session_manual>\n{\npublic:\n    typedef std::shared_ptr<session_manual> ptr;\n    typedef std::function<void(const code&, channel::ptr)> channel_handler;\n\n    /// Construct an instance.\n    session_manual(p2p& network);\n\n    /// Start the manual session.\n    void start(result_handler handler) override;\n\n    /// Maintain connection to a node.\n    virtual void connect(const std::string& hostname, uint16_t port);\n\n    /// Maintain connection to a node with callback on first connect.\n    virtual void connect(const std::string& hostname, uint16_t port,\n        channel_handler handler);\n\nprotected:\n    /// Override to attach specialized protocols upon channel start.\n    virtual void attach_protocols(channel::ptr channel);\n\n    void delay_new_connection(const std::string& hostname, uint16_t port\n            , channel_handler handler, uint32_t retries);\n\nprivate:\n    void handle_started(const code& ec, result_handler handler);\n    void start_connect(const std::string& hostname, uint16_t port,\n        channel_handler handler, uint32_t retries);\n    void handle_connect(const code& ec, channel::ptr channel,\n        const std::string& hostname, uint16_t port,\n        channel_handler handler, uint32_t retries);\n\n    void handle_channel_start(const code& ec, const std::string& hostname,\n        uint16_t port, channel::ptr channel, channel_handler handler);\n    void handle_channel_stop(const code& ec, const std::string& hostname,\n        uint16_t port);\n\n    bc::atomic<connector::ptr> connector_;\n};\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/network/sessions/session_outbound.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_SESSION_OUTBOUND_HPP\n#define UC_NETWORK_SESSION_OUTBOUND_HPP\n\n#include <cstddef>\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/define.hpp>\n#include <UChain/network/sessions/session_batch.hpp>\n#include <UChain/network/settings.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\nclass p2p;\n\n/// Outbound connections session, thread safe.\nclass BCT_API session_outbound\n  : public session_batch, track<session_outbound>\n{\npublic:\n    typedef std::shared_ptr<session_outbound> ptr;\n\n    /// Construct an instance.\n    session_outbound(p2p& network);\n\n    /// Start the session.\n    void start(result_handler handler) override;\n\nprotected:\n    /// Override to attach specialized protocols upon channel start.\n    virtual void attach_protocols(channel::ptr channel);\n    void delay_new_connect(connector::ptr connect);\n\n    void delay_reseeding();\n\nprivate:\n    void new_connection(connector::ptr connect);\n    void handle_started(const code& ec, result_handler handler);\n    void handle_connect(const code& ec, channel::ptr channel,\n        connector::ptr connect);\n\n    void handle_channel_stop(const code& ec, connector::ptr connect,\n        channel::ptr channel);\n    void handle_channel_start(const code& ec, connector::ptr connect,\n        channel::ptr channel);\n\n    std::atomic_int outbound_counter;\n    std::atomic_bool in_reseeding; //to mark if the re-seeding timer is active\n    p2p& network__;\n};\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/network/sessions/session_seed.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_SESSION_SEED_HPP\n#define UC_NETWORK_SESSION_SEED_HPP\n\n#include <cstddef>\n#include <memory>\n#include <vector>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/define.hpp>\n#include <UChain/network/sessions/session.hpp>\n#include <UChain/network/settings.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\nclass p2p;\n\n/// Seed connections session, thread safe.\nclass BCT_API session_seed\n  : public session, track<session_seed>\n{\npublic:\n    typedef std::shared_ptr<session_seed> ptr;\n\n    /// Construct an instance.\n    session_seed(p2p& network);\n\n    /// Start the session.\n    void start(result_handler handler) override;\n\n    void restart(result_handler handler);\n\nprotected:\n    /// Override to attach specialized protocols upon channel start.\n    virtual void attach_protocols(channel::ptr channel,\n        result_handler handler);\n\nprivate:\n    void handle_count(size_t start_size, result_handler handler);\n    void start_seeding(size_t start_size, connector::ptr connect,\n        result_handler handler);\n    void start_seed(const config::endpoint& seed, connector::ptr connect,\n        result_handler handler);\n    void handle_started(const code& ec, result_handler handler);\n    void handle_connect(const code& ec, channel::ptr channel,\n        const config::endpoint& seed, result_handler handler);\n    void handle_complete(size_t start_size, result_handler handler);\n    void handle_final_count(size_t current_size, size_t start_size,\n        result_handler handler);\n\n    void handle_channel_start(const code& ec, channel::ptr channel,\n        result_handler handler);\n    void handle_channel_stop(const code& ec);\n\nprivate:\n    p2p& network_;\n};\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n\n"
  },
  {
    "path": "include/UChain/network/settings.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_SETTINGS_HPP\n#define UC_NETWORK_SETTINGS_HPP\n\n#include <cstdint>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/network/define.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\n/// Common database configuration settings, properties not thread safe.\nclass BCT_API settings\n{\npublic:\n    settings();\n    settings(bc::settings context);\n\n    /// Properties.\n    uint32_t threads;\n    uint32_t protocol;\n    uint32_t identifier;\n    uint16_t inbound_port;\n    uint32_t inbound_connections;\n    uint32_t outbound_connections;\n    uint32_t manual_attempt_limit;\n    uint32_t connect_batch_size;\n    uint32_t connect_timeout_seconds;\n    uint32_t channel_handshake_seconds;\n    uint32_t channel_heartbeat_minutes;\n    uint32_t channel_inactivity_minutes;\n    uint32_t channel_expiration_minutes;\n    uint32_t channel_germination_seconds;\n    uint32_t host_pool_capacity;\n    bool relay_transactions;\n    bool enable_re_seeding;\n    boost::filesystem::path hosts_file;\n    boost::filesystem::path debug_file;\n    boost::filesystem::path error_file;\n    config::authority self;\n    config::authority::list blacklists;\n    config::endpoint::list peers;\n    bool upnp_map_port;\n    bool be_found;\n    config::endpoint::list seeds;\n\n    /// Helpers.\n    asio::duration connect_timeout() const;\n    asio::duration channel_handshake() const;\n    asio::duration channel_heartbeat() const;\n    asio::duration channel_inactivity() const;\n    asio::duration channel_expiration() const;\n    asio::duration channel_germination() const;\n};\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/network/socket.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NETWORK_SOCKET_HPP\n#define UC_NETWORK_SOCKET_HPP\n\n#include <UChain/coin.hpp>\n#include <UChain/network/define.hpp>\n#include <UChain/network/locked_socket.hpp>\n\nnamespace libbitcoin {\nnamespace network {\n\n/// A thread safe asio socket.\nclass BCT_API socket\n  : public track<socket>\n{\npublic:\n    typedef std::shared_ptr<socket> ptr;\n\n    /// Construct an instance.\n    socket(threadpool& pool);\n\n    /// This class is not copyable.\n    socket(const socket&) = delete;\n    void operator=(const socket&) = delete;\n\n    /// Obtain an exclusive reference to the socket.\n    locked_socket::ptr get_socket();\n\n    /// Obtain the authority of the remote endpoint.\n    config::authority get_authority() const;\n\n    /// Close the contained socket.\n    virtual void close();\n\nprivate:\n    asio::socket socket_;\n    mutable upgrade_mutex mutex_;\n};\n\n} // namespace network\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/network/version.hpp",
    "content": "///////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 2014-2018 libbitcoin-network developers (see COPYING).\n//\n//        GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY\n//\n///////////////////////////////////////////////////////////////////////////////\n#ifndef UC_NETWORK_VERSION_HPP\n#define UC_NETWORK_VERSION_HPP\n\n/**\n * The semantic version of this repository as: [major].[minor].[patch]\n * For interpretation of the versioning scheme see: http://semver.org\n */\n\n#define UC_NETWORK_VERSION \"6\"\n#define UC_NETWORK_MAJOR_VERSION 0\n#define UC_NETWORK_MINOR_VERSION 0\n#define UC_NETWORK_PATCH_VERSION 6\n\n#endif\n"
  },
  {
    "path": "include/UChain/network.hpp",
    "content": "///////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 2014-2018 libbitcoin-network developers (see COPYING).\n//\n//        GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY\n//\n///////////////////////////////////////////////////////////////////////////////\n#ifndef UC_NETWORK_HPP\n#define UC_NETWORK_HPP\n\n/**\n * API Users: Include only this header. Direct use of other headers is fragile\n * and unsupported as header organization is subject to change.\n *\n * Maintainers: Do not include this header internal to this library.\n */\n\n#include <UChain/coin.hpp>\n#include <UChain/network/acceptor.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/connections.hpp>\n#include <UChain/network/connector.hpp>\n#include <UChain/network/const_buffer.hpp>\n#include <UChain/network/define.hpp>\n#include <UChain/network/hosts.hpp>\n#include <UChain/network/locked_socket.hpp>\n#include <UChain/network/message_subscriber.hpp>\n#include <UChain/network/p2p.hpp>\n#include <UChain/network/pending_channels.hpp>\n#include <UChain/network/pending_sockets.hpp>\n#include <UChain/network/proxy.hpp>\n#include <UChain/network/settings.hpp>\n#include <UChain/network/socket.hpp>\n#include <UChain/network/version.hpp>\n#include <UChain/network/protocols/protocol.hpp>\n#include <UChain/network/protocols/protocol_address.hpp>\n#include <UChain/network/protocols/protocol_events.hpp>\n#include <UChain/network/protocols/protocol_ping.hpp>\n#include <UChain/network/protocols/protocol_seed.hpp>\n#include <UChain/network/protocols/protocol_timer.hpp>\n#include <UChain/network/protocols/protocol_version.hpp>\n#include <UChain/network/sessions/session.hpp>\n#include <UChain/network/sessions/session_batch.hpp>\n#include <UChain/network/sessions/session_inbound.hpp>\n#include <UChain/network/sessions/session_manual.hpp>\n#include <UChain/network/sessions/session_outbound.hpp>\n#include <UChain/network/sessions/session_seed.hpp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/node/configuration.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-node.\n *\n * UChain-node is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NODE_CONFIGURATION_HPP\n#define UC_NODE_CONFIGURATION_HPP\n\n#include <cstddef>\n#include <string>\n#include <boost/filesystem.hpp>\n#include <boost/program_options.hpp>\n#include <UChain/blockchain.hpp>\n#include <UChain/network.hpp>\n#include <UChain/node/define.hpp>\n#include <UChain/node/settings.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\n// Not localizable.\n#define BN_HELP_VARIABLE \"help\"\n#define BN_SETTINGS_VARIABLE \"settings\"\n#define BN_VERSION_VARIABLE \"version\"\n#define BN_DAEMON_VARIABLE \"daemon\"\n//#define BS_UI_VARIABLE \"ui\"\n\n// This must be lower case but the env var part can be any case.\n#define BN_CONFIG_VARIABLE \"config\"\n\n// This must match the case of the env var.\n#define BN_ENVIRONMENT_VARIABLE_PREFIX \"BN_\"\n\n/// Full node configuration, thread safe.\nclass BCN_API configuration\n{\n  public:\n    configuration(bc::settings context);\n    configuration(const configuration &other);\n\n    /// Options.\n    bool help;\n    bool initchain;\n    bool settings;\n    bool version;\n    bool daemon;\n    bool use_testnet_rules;\n    bool ui;\n    bool upnp_map_port;\n\n    /// Options and environment vars.\n    boost::filesystem::path file;\n    boost::filesystem::path data_dir;\n\n    /// Settings.\n    node::settings node;\n    blockchain::settings chain;\n    database::settings database;\n    network::settings network;\n};\n\n} // namespace node\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/node/define.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-node.\n *\n * UChain-node is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NODE_DEFINE_HPP\n#define UC_NODE_DEFINE_HPP\n\n#include <UChain/coin.hpp>\n\n// We use the generic helper definitions in libbitcoin to define BCN_API\n// and BCN_INTERNAL. BCN_API is used for the public API symbols. It either DLL\n// imports or DLL exports (or does nothing for static build) BCN_INTERNAL is\n// used for non-api symbols.\n\n#if defined BCN_STATIC\n#define BCN_API\n#define BCN_INTERNAL\n#elif defined BCN_DLL\n#define BCN_API BC_HELPER_DLL_EXPORT\n#define BCN_INTERNAL BC_HELPER_DLL_LOCAL\n#else\n#define BCN_API BC_HELPER_DLL_IMPORT\n#define BCN_INTERNAL BC_HELPER_DLL_LOCAL\n#endif\n\n// Log name.\n#define LOG_NODE \"node\"\n\n#endif\n"
  },
  {
    "path": "include/UChain/node/p2p_node.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-node.\n *\n * UChain-node is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NODE_P2P_NODE_HPP\n#define UC_NODE_P2P_NODE_HPP\n\n#include <cstdint>\n#include <memory>\n#include <UChain/blockchain.hpp>\n#include <UChain/network.hpp>\n#include <UChain/node/configuration.hpp>\n#include <UChain/node/define.hpp>\n#include <UChain/node/sessions/session_block_sync.hpp>\n#include <UChain/node/sessions/session_header_sync.hpp>\n#include <UChain/node/utility/header_queue.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\n/// A full node on the Bitcoin P2P network.\nclass BCN_API p2p_node\n    : public network::p2p\n{\n  public:\n    typedef std::shared_ptr<p2p_node> ptr;\n    typedef blockchain::organizer::reorganize_handler reorganize_handler;\n    typedef blockchain::tx_pool::transaction_handler\n        transaction_handler;\n\n    /// Construct the full node.\n    p2p_node(const configuration &configuration);\n\n    /// Ensure all threads are coalesced.\n    virtual ~p2p_node();\n\n    // Start/Run sequences.\n    // ------------------------------------------------------------------------\n\n    /// Invoke startup and seeding sequence, call from constructing thread.\n    void start(result_handler handler) override;\n\n    /// Synchronize the blockchain and then begin long running sessions,\n    /// call from start result handler. Call base method to skip sync.\n    void run(result_handler handler) override;\n\n    // Shutdown.\n    // ------------------------------------------------------------------------\n\n    /// Idempotent call to signal work stop, start may be reinvoked after.\n    /// Returns the result of file save operation.\n    bool stop() override;\n\n    /// Blocking call to coalesce all work and then terminate all threads.\n    /// Call from thread that constructed this class, or don't call at all.\n    /// This calls stop, and start may be reinvoked after calling this.\n    bool close() override;\n\n    // Properties.\n    // ------------------------------------------------------------------------\n\n    /// Node configuration settings.\n    virtual const settings &node_settings() const;\n\n    /// Blockchain query interface.\n    virtual blockchain::block_chain &chain();\n\n    /// BlockchainImpl query interface.\n    virtual blockchain::block_chain_impl &chain_impl();\n\n    /// Transaction pool interface.\n    virtual blockchain::tx_pool &pool();\n\n    // Subscriptions.\n    // ------------------------------------------------------------------------\n\n    /// Subscribe to blockchain reorganization and stop events.\n    virtual void subscribe_blockchain(reorganize_handler handler);\n\n    /// Subscribe to transaction pool acceptance and stop events.\n    virtual void subscribe_tx_pool(transaction_handler handler);\n\n  protected:\n    /// Override to attach specialized p2p sessions.\n    ////network::session_seed::ptr attach_seed_session() override;\n    network::session_manual::ptr attach_manual_session() override;\n    network::session_inbound::ptr attach_inbound_session() override;\n    network::session_outbound::ptr attach_outbound_session() override;\n\n    /// Override to attach specialized node sessions.\n    virtual session_header_sync::ptr attach_header_sync_session();\n    virtual session_block_sync::ptr attach_block_sync_session();\n\n  private:\n    typedef message::block_msg::ptr_list block_ptr_list;\n\n    bool handle_reorganized(const code &ec, size_t fork_point,\n                            const block_ptr_list &incoming, const block_ptr_list &outgoing);\n\n    void handle_headers_synchronized(const code &ec, result_handler handler);\n    void handle_network_stopped(const code &ec, result_handler handler);\n\n    void handle_started(const code &ec, result_handler handler);\n    void handle_running(const code &ec, result_handler handler);\n\n    // These are thread safe.\n    header_queue hashes_;\n    const settings &settings_;\n\n  protected:\n    // fix me, for explorer only.\n    blockchain::block_chain_impl blockchain_;\n};\n\n} // namespace node\n} //namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/node/parser.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-node.\n *\n * UChain-node is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NODE_PARSER_HPP\n#define UC_NODE_PARSER_HPP\n\n#include <ostream>\n#include <UChain/coin.hpp>\n#include <UChain/node/define.hpp>\n#include <UChain/node/configuration.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\n/// Parse configurable values from environment variables, settings file, and\n/// command line positional and non-positional options.\nclass BCN_API parser\n    : public config::parser\n{\npublic:\n  parser(bc::settings context);\n  parser(const configuration defaults);\n\n  /// Parse all configuration into member settings.\n  virtual bool parse(int argc, const char *argv[], std::ostream &error);\n\n  /// Load command line options (named).\n  virtual options_metadata load_options();\n\n  /// Load command line arguments (positional).\n  virtual arguments_metadata load_arguments();\n\n  /// Load configuration file settings.\n  virtual options_metadata load_settings();\n\n  /// Load environment variable settings.\n  virtual options_metadata load_environment();\n\n  /// The populated configuration settings values.\n  configuration configured;\n};\n\n} // namespace node\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/node/protocols/protocol_block_in.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NODE_PROTOCOL_BLOCK_IN_HPP\n#define UC_NODE_PROTOCOL_BLOCK_IN_HPP\n\n#include <atomic>\n#include <cstddef>\n#include <memory>\n#include <UChain/blockchain.hpp>\n#include <UChain/network.hpp>\n#include <UChain/node/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\nclass BCN_API protocol_block_in\n    : public network::protocol_timer,\n      track<protocol_block_in>\n{\n  public:\n    typedef std::shared_ptr<protocol_block_in> ptr;\n\n    /// Construct a block protocol instance.\n    protocol_block_in(network::p2p &network, network::channel::ptr channel,\n                      blockchain::block_chain &blockchain);\n\n    ptr do_subscribe();\n\n    /// Start the protocol.\n    virtual void start();\n\n  private:\n    // Local type aliases.\n    typedef message::get_data::ptr get_data_ptr;\n    typedef message::block_msg::ptr block_ptr;\n    typedef message::headers::ptr headers_ptr;\n    typedef message::inventory::ptr inventory_ptr;\n    typedef message::not_found::ptr not_found_ptr;\n    typedef message::block_msg::ptr_list block_ptr_list;\n\n    void get_block_inventory(const code &ec);\n    void send_get_blocks(const hash_digest &stop_hash);\n    void send_get_blocks(const hash_digest &from_hash, const hash_digest &to_hash);\n    void send_get_data(const code &ec, get_data_ptr message);\n\n    bool handle_receive_block(const code &ec, block_ptr message);\n    bool handle_receive_headers(const code &ec, headers_ptr message);\n    bool handle_receive_inventory(const code &ec, inventory_ptr message);\n    bool handle_receive_not_found(const code &ec, not_found_ptr message);\n    void handle_filter_orphans(const code &ec, get_data_ptr message);\n    void handle_store_block(const code &ec, block_ptr message);\n    void handle_fetch_block_locator(const code &ec, const hash_list &locator,\n                                    const hash_digest &stop_hash);\n    bool handle_reorganized(const code &ec, size_t fork_point,\n                            const block_ptr_list &incoming, const block_ptr_list &outgoing);\n\n    blockchain::block_chain &blockchain_;\n    bc::atomic<hash_digest> last_locator_top_;\n    bc::atomic<hash_digest> current_chain_top_;\n    const bool headers_from_peer_;\n    std::atomic_int headers_batch_size_;\n};\n\n} // namespace node\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/node/protocols/protocol_block_out.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NODE_PROTOCOL_BLOCK_OUT_HPP\n#define UC_NODE_PROTOCOL_BLOCK_OUT_HPP\n\n#include <atomic>\n#include <cstddef>\n#include <memory>\n#include <UChain/blockchain.hpp>\n#include <UChain/network.hpp>\n#include <UChain/node/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\n// Protocol limit.\nconstexpr auto locator_cap = 500u;\n\nclass BCN_API protocol_block_out\n    : public network::protocol_events,\n      track<protocol_block_out>\n{\n  public:\n    typedef std::shared_ptr<protocol_block_out> ptr;\n\n    /// Construct a block protocol instance.\n    protocol_block_out(network::p2p &network, network::channel::ptr channel,\n                       blockchain::block_chain &blockchain);\n\n    ptr do_subscribe();\n\n    /// Start the protocol.\n    virtual void start();\n\n  private:\n    // Local type aliases.\n    typedef message::block_msg::ptr block_ptr;\n    typedef message::get_data::ptr get_data_ptr;\n    typedef message::get_blocks::ptr get_blocks_ptr;\n    typedef message::get_headers::ptr get_headers_ptr;\n    typedef message::send_headers::ptr send_headers_ptr;\n    typedef message::merkle_block::ptr merkle_block_ptr;\n    typedef message::block_msg::ptr_list block_ptr_list;\n    typedef chain::header::list header_list;\n\n    void send_block(const code &ec, chain::block::ptr block,\n                    const hash_digest &hash);\n    void send_merkle_block(const code &ec, merkle_block_ptr message,\n                           const hash_digest &hash);\n\n    bool handle_receive_get_data(const code &ec, get_data_ptr message);\n    bool handle_receive_get_blocks(const code &ec, get_blocks_ptr message);\n    bool handle_receive_get_headers(const code &ec, get_headers_ptr message);\n    bool handle_receive_send_headers(const code &ec, send_headers_ptr message);\n\n    void handle_fetch_locator_hashes(const code &ec, const hash_list &hashes);\n    void handle_fetch_locator_headers(const code &ec,\n                                      const header_list &headers);\n\n    void handle_stop(const code &);\n    bool handle_reorganized(const code &ec, size_t fork_point,\n                            const block_ptr_list &incoming, const block_ptr_list &outgoing);\n\n    size_t locator_limit() const;\n\n    blockchain::block_chain &blockchain_;\n    bc::atomic<hash_digest> last_locator_top_;\n    std::atomic<size_t> current_chain_height_;\n    std::atomic<bool> headers_to_peer_;\n};\n\n} // namespace node\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/node/protocols/protocol_block_sync.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NODE_PROTOCOL_BLOCK_SYNC_HPP\n#define UC_NODE_PROTOCOL_BLOCK_SYNC_HPP\n\n#include <cstddef>\n#include <memory>\n#include <UChain/blockchain.hpp>\n#include <UChain/network.hpp>\n#include <UChain/node/define.hpp>\n#include <UChain/node/utility/reservation.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\n/// Blocks sync protocol, thread safe.\nclass BCN_API protocol_block_sync\n    : public network::protocol_timer,\n      public track<protocol_block_sync>\n{\n  public:\n    typedef std::shared_ptr<protocol_block_sync> ptr;\n\n    /// Construct a block sync protocol instance.\n    protocol_block_sync(network::p2p &network, network::channel::ptr channel,\n                        reservation::ptr row);\n\n    /// Start the protocol.\n    virtual void start(event_handler handler);\n\n  private:\n    typedef message::block_msg::ptr block_ptr;\n\n    void send_get_blocks(event_handler complete, bool reset);\n    void handle_send(const code &ec, event_handler complete);\n    void handle_event(const code &ec, event_handler complete);\n    void blocks_complete(const code &ec, event_handler handler);\n    bool handle_receive(const code &ec, block_ptr message,\n                        event_handler complete);\n\n    reservation::ptr reservation_;\n};\n\n} // namespace node\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/node/protocols/protocol_header_sync.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NODE_PROTOCOL_HEADER_SYNC_HPP\n#define UC_NODE_PROTOCOL_HEADER_SYNC_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <memory>\n#include <vector>\n#include <UChain/network.hpp>\n#include <UChain/node/configuration.hpp>\n#include <UChain/node/define.hpp>\n#include <UChain/node/utility/header_queue.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\n/// Headers sync protocol, thread safe.\nclass BCN_API protocol_header_sync\n    : public network::protocol_timer,\n      public track<protocol_header_sync>\n{\n  public:\n    typedef std::shared_ptr<protocol_header_sync> ptr;\n\n    /// Construct a header sync protocol instance.\n    protocol_header_sync(network::p2p &network, network::channel::ptr channel,\n                         header_queue &hashes, uint32_t minimum_rate,\n                         const config::checkpoint &last);\n\n    /// Start the protocol.\n    virtual void start(event_handler handler);\n\n  private:\n    typedef message::headers::ptr headers_ptr;\n\n    static size_t final_height(header_queue &headers,\n                               const config::checkpoint::list &checkpoints);\n\n    size_t sync_rate() const;\n    size_t next_height() const;\n\n    void send_get_headers(event_handler complete);\n    void handle_send(const code &ec, event_handler complete);\n    void handle_event(const code &ec, event_handler complete);\n    void headers_complete(const code &ec, event_handler handler);\n    bool handle_receive(const code &ec, headers_ptr message,\n                        event_handler complete);\n\n    // Thread safe and guarded by sequential header sync.\n    header_queue &hashes_;\n\n    // This is guarded by protocol_timer/deadline contract (exactly one call).\n    size_t current_second_;\n\n    const uint32_t minimum_rate_;\n    const size_t start_size_;\n    const config::checkpoint last_;\n};\n\n} // namespace node\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/node/protocols/protocol_miner.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef INCLUDE_BITCOIN_NODE_PROTOCOLS_PROTOCOL_MINER_HPP_\n#define INCLUDE_BITCOIN_NODE_PROTOCOLS_PROTOCOL_MINER_HPP_\n\n#include <atomic>\n#include <cstddef>\n#include <memory>\n#include <UChain/blockchain.hpp>\n#include <UChain/network.hpp>\n#include <UChain/node/define.hpp>\n\nnamespace libbitcoin\n{\n\nnamespace node\n{\n\nclass BCN_API protocol_miner : public network::protocol_events, track<protocol_miner>\n{\n  public:\n    using ptr = std::shared_ptr<protocol_miner>;\n    using indexes = chain::point::indexes;\n    using transaction_ptr = message::tx_message::ptr;\n    protocol_miner(network::p2p &network, network::channel::ptr channel, blockchain::block_chain &blockchain\n                   /*, blockchain::tx_pool& pool*/);\n    virtual void start();\n\n  private:\n    void handle_stop(const code &ec);\n    //    bool handle_accept_transaction(const code&, const indexes&, transaction_ptr);\n  private:\n    blockchain::block_chain &blockchain_;\n    //    blockchain::tx_pool& pool_;\n};\n\n} // namespace node\n} // namespace libbitcoin\n\n#endif /* INCLUDE_BITCOIN_NODE_PROTOCOLS_PROTOCOL_MINER_HPP_ */\n"
  },
  {
    "path": "include/UChain/node/protocols/protocol_tx_in.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NODE_protocol_tx_in_HPP\n#define UC_NODE_protocol_tx_in_HPP\n\n#include <memory>\n#include <UChain/blockchain.hpp>\n#include <UChain/network.hpp>\n#include <UChain/node/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\nclass BCN_API protocol_tx_in\n    : public network::protocol_events,\n      track<protocol_tx_in>\n{\n  public:\n    typedef std::shared_ptr<protocol_tx_in> ptr;\n\n    /// Construct a transaction protocol instance.\n    protocol_tx_in(network::p2p &network,\n                            network::channel::ptr channel, blockchain::block_chain &blockchain,\n                            blockchain::tx_pool &pool);\n\n    ptr do_subscribe();\n\n    /// Start the protocol.\n    virtual void start();\n\n  private:\n    typedef chain::point::indexes index_list;\n    typedef message::get_data::ptr get_data_ptr;\n    typedef message::inventory::ptr inventory_ptr;\n    typedef message::tx_message::ptr transaction_ptr;\n    typedef message::block_msg::ptr_list block_ptr_list;\n    typedef message::block_msg::ptr block_ptr;\n\n    void send_get_data(const code &ec, get_data_ptr message);\n    void handle_filter_floaters(const code &ec, get_data_ptr message);\n    bool handle_receive_inventory(const code &ec, inventory_ptr message);\n    bool handle_receive_transaction(const code &ec, transaction_ptr message);\n    void handle_store_confirmed(const code &ec, transaction_ptr message);\n    void handle_store_validated(const code &ec, transaction_ptr message,\n                                const index_list &unconfirmed);\n    bool handle_reorganized(const code &ec, size_t fork_point,\n                            const block_ptr_list &incoming, const block_ptr_list &outgoing);\n\n    void handle_stop(const code &);\n\n    blockchain::block_chain &blockchain_;\n    blockchain::tx_pool &pool_;\n    const bool relay_from_peer_;\n    const bool peer_suports_memory_pool_;\n    const bool refresh_pool_;\n};\n\n} // namespace node\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/node/protocols/protocol_tx_out.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NODE_protocol_tx_out_HPP\n#define UC_NODE_protocol_tx_out_HPP\n\n#include <atomic>\n#include <cstdint>\n#include <memory>\n#include <UChain/blockchain.hpp>\n#include <UChain/network.hpp>\n#include <UChain/node/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\nclass BCN_API protocol_tx_out\n    : public network::protocol_events,\n      track<protocol_tx_out>\n{\n  public:\n    typedef std::shared_ptr<protocol_tx_out> ptr;\n\n    /// Construct a transaction protocol instance.\n    protocol_tx_out(network::p2p &network,\n                             network::channel::ptr channel, blockchain::block_chain &blockchain,\n                             blockchain::tx_pool &pool);\n\n    ptr do_subscribe();\n\n    /// Start the protocol.\n    virtual void start();\n\n  private:\n    // Local type aliases.\n    typedef message::tx_message::ptr transaction_ptr;\n    typedef message::fee_filter::ptr fee_filter_ptr;\n    typedef message::memory_pool::ptr memory_pool_ptr;\n    typedef message::get_data::ptr get_data_ptr;\n    typedef chain::point::indexes index_list;\n\n    void send_transaction(const code &ec,\n                          const chain::transaction &transaction, const hash_digest &hash);\n\n    bool handle_receive_get_data(const code &ec, get_data_ptr message);\n    bool handle_receive_fee_filter(const code &ec, fee_filter_ptr message);\n    bool handle_receive_memory_pool(const code &ec, memory_pool_ptr message);\n\n    void handle_stop(const code &);\n    bool handle_floated(const code &ec, const index_list &unconfirmed,\n                        transaction_ptr message);\n\n    blockchain::block_chain &blockchain_;\n    blockchain::tx_pool &pool_;\n    std::atomic<uint64_t> minimum_fee_;\n    const bool relay_to_peer_;\n};\n\n} // namespace node\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/node/protocols/protocol_version_quiet.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NODE_PROTOCOL_VERSION_QUIET_HPP\n#define UC_NODE_PROTOCOL_VERSION_QUIET_HPP\n\n#include <memory>\n#include <UChain/network.hpp>\n#include <UChain/node/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\nclass BCN_API protocol_version_quiet\n    : public network::protocol_version\n{\n  public:\n    typedef std::shared_ptr<protocol_version_quiet> ptr;\n\n    /// Construct a quiet version protocol instance.\n    protocol_version_quiet(network::p2p &network,\n                           network::channel::ptr channel);\n\n  protected:\n    /// Overridden to set relay to false.\n    void send_version(const message::version &self) override;\n};\n\n} // namespace node\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/node/sessions/session_block_sync.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NODE_SESSION_BLOCK_SYNC_HPP\n#define UC_NODE_SESSION_BLOCK_SYNC_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <memory>\n#include <UChain/blockchain.hpp>\n#include <UChain/network.hpp>\n#include <UChain/node/define.hpp>\n#include <UChain/node/settings.hpp>\n#include <UChain/node/utility/header_queue.hpp>\n#include <UChain/node/utility/reservation.hpp>\n#include <UChain/node/utility/reservations.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\n/// Class to manage initial block download connections, thread safe.\nclass BCN_API session_block_sync\n    : public network::session_batch,\n      track<session_block_sync>\n{\n  public:\n    typedef std::shared_ptr<session_block_sync> ptr;\n\n    session_block_sync(network::p2p &network, header_queue &hashes,\n                       blockchain::simple_chain &chain, const settings &settings);\n\n    virtual void start(result_handler handler);\n\n  protected:\n    /// Overridden to attach and start specialized handshake.\n    void attach_handshake_protocols(network::channel::ptr channel,\n                                    result_handler handle_started) override;\n\n    /// Override to attach and start specialized protocols after handshake.\n    virtual void attach_protocols(network::channel::ptr channel,\n                                  network::connector::ptr connect, reservation::ptr row,\n                                  result_handler handler);\n\n  private:\n    void handle_started(const code &ec, result_handler handler);\n    void new_connection(network::connector::ptr connect,\n                        reservation::ptr row, result_handler handler);\n    void handle_complete(const code &ec, network::channel::ptr channel, network::connector::ptr connect,\n                         reservation::ptr row, result_handler handler);\n    void handle_connect(const code &ec, network::channel::ptr channel,\n                        network::connector::ptr connect, reservation::ptr row,\n                        result_handler handler);\n    void handle_channel_start(const code &ec, network::channel::ptr channel,\n                              network::connector::ptr connect, reservation::ptr row,\n                              result_handler handler);\n    void handle_channel_stop(const code &ec, network::connector::ptr connect, reservation::ptr row, result_handler handler);\n\n    void reset_timer(network::connector::ptr connect);\n    void handle_timer(const code &ec, network::connector::ptr connect);\n\n    // These are thread safe.\n    blockchain::simple_chain &blockchain_;\n    reservations reservations_;\n    deadline::ptr timer_;\n    unique_mutex mutex_;\n    int32_t reservations_count_;\n\n    const settings &settings_;\n};\n\n} // namespace node\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/node/sessions/session_header_sync.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NODE_SESSION_HEADER_SYNC_HPP\n#define UC_NODE_SESSION_HEADER_SYNC_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <memory>\n#include <UChain/blockchain.hpp>\n#include <UChain/network.hpp>\n#include <UChain/node/define.hpp>\n#include <UChain/node/settings.hpp>\n#include <UChain/node/utility/header_queue.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\n/// Class to manage initial header download connection, thread safe.\nclass BCN_API session_header_sync\n    : public network::session_batch,\n      track<session_header_sync>\n{\n  public:\n    typedef std::shared_ptr<session_header_sync> ptr;\n\n    session_header_sync(network::p2p &network, header_queue &hashes,\n                        blockchain::simple_chain &blockchain,\n                        const config::checkpoint::list &checkpoints);\n\n    virtual void start(result_handler handler);\n\n  protected:\n    /// Overridden to attach and start specialized handshake.\n    void attach_handshake_protocols(network::channel::ptr channel,\n                                    result_handler handle_started) override;\n\n    /// Override to attach and start specialized protocols after handshake.\n    virtual void attach_protocols(network::channel::ptr channel,\n                                  network::connector::ptr connect, result_handler handler);\n\n  private:\n    bool initialize(result_handler handler);\n    void handle_started(const code &ec, result_handler handler);\n    void new_connection(network::connector::ptr connect,\n                        result_handler handler);\n    void start_syncing(const code &ec, const config::authority &host,\n                       network::connector::ptr connect, result_handler handler);\n    void handle_connect(const code &ec, network::channel::ptr channel,\n                        network::connector::ptr connect, result_handler handler);\n    void handle_complete(const code &ec, network::channel::ptr channel, network::connector::ptr connect,\n                         result_handler handler);\n    void handle_channel_start(const code &ec, network::connector::ptr connect,\n                              network::channel::ptr channel, result_handler handler);\n    void handle_channel_stop(const code &ec, network::connector::ptr connect, result_handler handler);\n    code get_range(config::checkpoint &out_seed, config::checkpoint &out_stop);\n\n    // Thread safe.\n    header_queue &hashes_;\n\n    // These do not require guard because they are not used concurrently.\n    uint32_t minimum_rate_;\n    config::checkpoint last_;\n    blockchain::simple_chain &blockchain_;\n    const config::checkpoint::list checkpoints_;\n    std::atomic_int try_count_;\n    std::atomic_bool synced_;\n};\n\n} // namespace node\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/node/sessions/session_inbound.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NODE_SESSION_INBOUND_HPP\n#define UC_NODE_SESSION_INBOUND_HPP\n\n#include <memory>\n#include <UChain/blockchain.hpp>\n#include <UChain/network.hpp>\n#include <UChain/node/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\n/// Inbound connections session, thread safe.\nclass BCN_API session_inbound\n    : public network::session_inbound\n{\n  public:\n    typedef std::shared_ptr<session_inbound> ptr;\n\n    /// Construct an instance.\n    session_inbound(network::p2p &network, blockchain::block_chain &blockchain,\n                    blockchain::tx_pool &pool);\n\n    virtual void attach_handshake_protocols(network::channel::ptr channel,\n                                            result_handler handle_started) override;\n\n  protected:\n    /// Overridden to attach blockchain protocols.\n    void attach_protocols(network::channel::ptr channel) override;\n\n    blockchain::block_chain &blockchain_;\n    blockchain::tx_pool &pool_;\n};\n\n} // namespace node\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/node/sessions/session_manual.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NODE_SESSION_MANUAL_HPP\n#define UC_NODE_SESSION_MANUAL_HPP\n\n#include <memory>\n#include <UChain/blockchain.hpp>\n#include <UChain/network.hpp>\n#include <UChain/node/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\n/// Manual connections session, thread safe.\nclass BCN_API session_manual\n    : public network::session_manual\n{\n  public:\n    typedef std::shared_ptr<session_manual> ptr;\n\n    /// Construct an instance.\n    session_manual(network::p2p &network, blockchain::block_chain &blockchain,\n                   blockchain::tx_pool &pool);\n\n  protected:\n    void attach_handshake_protocols(network::channel::ptr channel, result_handler handle_started);\n    /// Overridden to attach blockchain protocols.\n    void attach_protocols(network::channel::ptr channel) override;\n\n    blockchain::block_chain &blockchain_;\n    blockchain::tx_pool &pool_;\n};\n\n} // namespace node\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/node/sessions/session_outbound.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NODE_SESSION_OUTBOUND_HPP\n#define UC_NODE_SESSION_OUTBOUND_HPP\n\n#include <memory>\n#include <UChain/blockchain.hpp>\n#include <UChain/network.hpp>\n#include <UChain/node/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\n/// Outbound connections session, thread safe.\nclass BCN_API session_outbound\n    : public network::session_outbound\n{\n  public:\n    typedef std::shared_ptr<session_outbound> ptr;\n\n    /// Construct an instance.\n    session_outbound(network::p2p &network,\n                     blockchain::block_chain &blockchain,\n                     blockchain::tx_pool &pool);\n\n    virtual void attach_handshake_protocols(network::channel::ptr channel,\n                                            result_handler handle_started) override;\n\n  protected:\n    /// Overridden to attach blockchain protocols.\n    void attach_protocols(network::channel::ptr channel) override;\n\n    blockchain::block_chain &blockchain_;\n    blockchain::tx_pool &pool_;\n    /*mine::miner& miner_*/\n};\n\n} // namespace node\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/node/settings.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-node.\n *\n * UChain-node is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NODE_SETTINGS_HPP\n#define UC_NODE_SETTINGS_HPP\n\n#include <cstdint>\n#include <UChain/coin.hpp>\n#include <UChain/node/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\n/// Common database configuration settings, properties not thread safe.\nclass BCN_API settings\n{\n  public:\n    settings();\n    settings(bc::settings context);\n\n    /// Properties.\n    uint32_t block_timeout_seconds;\n    uint32_t download_connections;\n    bool tx_pool_refresh;\n};\n\n} // namespace node\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/node/utility/header_queue.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NODE_HEADER_QUEUE_HPP\n#define UC_NODE_HEADER_QUEUE_HPP\n\n#include <cstddef>\n#include <vector>\n#include <UChain/coin.hpp>\n#include <UChain/node/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\n// A smart queue for chaining blockchain headers, thread safe.\nclass BCN_API header_queue\n{\n  public:\n    /// True if the specified hash is marked as removed.\n    static bool valid(const hash_digest &hash);\n\n    /// Construct a block hash list with specified height offset.\n    header_queue(const config::checkpoint::list &checkpoints);\n\n    /// True if the list is empty.\n    bool empty() const;\n\n    /// The number of elements.\n    size_t size() const;\n\n    /// The height of the first element.\n    size_t first_height() const;\n\n    /// The height of the last element.\n    size_t last_height() const;\n\n    /// The last hash in the list or null_hash if none.\n    hash_digest last_hash() const;\n\n    /// Remove the first count of hashes, return true if satisfied.\n    bool dequeue(size_t count = 1);\n\n    /// Obtain and remove the first hash.\n    bool dequeue(hash_digest &out_hash, size_t &out_height);\n\n    /// Merge the hashes in the message with those in the queue.\n    bool enqueue(message::headers::ptr message);\n\n    /// Clear the queue and populate the hash at the given height.\n    void initialize(const config::checkpoint &check);\n\n    /// Clear the queue and populate the hash at the given height.\n    void initialize(const hash_digest &hash, size_t height);\n\n    /// Mark the heights if they exist.\n    void invalidate(size_t first_height, size_t count);\n\n  private:\n    // True if the queue is empty (not locked).\n    bool is_empty() const;\n\n    // The number of hashes in the queue (not locked).\n    size_t get_size() const;\n\n    // The last hash in the list or null_hash if none (not locked).\n    size_t last() const;\n\n    // Roll back the list to the last checkpoint.\n    void rollback();\n\n    // Merge a list of block hashes to the list, validating linkage.\n    bool merge(const chain::header::list &headers);\n\n    // Determine if the hash violates a checkpoint.\n    bool check(const hash_digest &hash, size_t height) const;\n\n    // Determine if the hash is linked to the give (preceding) header.\n    bool linked(const chain::header &header, const hash_digest &hash) const;\n\n    // The list of checkpoints that determines the sync range.\n    const config::checkpoint::list &checkpoints_;\n\n    // protected by mutex.\n    size_t height_;\n    hash_list list_;\n    hash_list::iterator head_;\n    mutable upgrade_mutex mutex_;\n};\n\n} // namespace node\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/node/utility/performance.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NODE_PERFORMANCE_HPP\n#define UC_NODE_PERFORMANCE_HPP\n\n#include <cmath>\n#include <cstddef>\n#include <cstdint>\n#include <UChain/blockchain.hpp>\n#include <UChain/node/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\nclass BCN_API performance\n{\n  public:\n    /// The normalized rate derived from the performance values.\n    double normal() const;\n\n    /// The rate derived from the performance values (inclusive of store cost).\n    double total() const;\n\n    /// The ratio of database time to total time.\n    double ratio() const;\n\n    bool idle;\n    size_t events;\n    uint64_t database;\n    uint64_t window;\n};\n\n// Coerce division into double and error into zero.\ntemplate <typename Quotient, typename Dividend, typename Divisor>\nstatic Quotient divide(Dividend dividend, Divisor divisor)\n{\n    const auto quotient = static_cast<Quotient>(dividend) / divisor;\n    return std::isnan(quotient) || std::isinf(quotient) ? 0.0 : quotient;\n}\n\n} // namespace node\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/node/utility/reservation.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NODE_RESERVATION_HPP\n#define UC_NODE_RESERVATION_HPP\n\n#include <chrono>\n#include <cstddef>\n#include <cstdint>\n#include <memory>\n#include <vector>\n#include <boost/bimap.hpp>\n#include <boost/bimap/set_of.hpp>\n#include <boost/bimap/unordered_set_of.hpp>\n#include <UChain/blockchain.hpp>\n#include <UChain/node/define.hpp>\n#include <UChain/node/utility/performance.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\nclass reservations;\n\n// Class to manage hashes during sync, thread safe.\nclass BCN_API reservation\n    : public enable_shared_from_base<reservation>\n{\n  public:\n    typedef std::shared_ptr<reservation> ptr;\n    typedef std::vector<reservation::ptr> list;\n\n    /// Construct a block reservation with the specified identifier.\n    reservation(reservations &reservations, size_t slot,\n                uint32_t block_timeout_seconds);\n\n    /// Ensure there are no remaining reserved hashes.\n    ~reservation();\n\n    /// The sequential identifier of this reservation.\n    size_t slot() const;\n\n    /// True if there are currently no hashes.\n    bool empty() const;\n\n    /// The number of outstanding blocks.\n    size_t size() const;\n\n    /// The reservation is empty and will remain so.\n    bool stopped() const;\n\n    /// True if block import rate was more than one standard deviation low.\n    bool expired() const;\n\n    /// Sets the idle state to true. Call when channel is stopped.\n    void reset();\n\n    /// True if the reservation is not applied to a channel.\n    bool idle() const;\n\n    /// The current cached average block import rate excluding import time.\n    performance rate() const;\n\n    /// The current cached average block import rate excluding import time.\n    void set_rate(const performance &rate);\n\n    /// The block data request message for the outstanding block hashes.\n    /// Set new if the preceding request was unsuccessful or discarded.\n    message::get_data request(bool new_channel);\n\n    /// Add the block hash to the reservation.\n    void insert(const config::checkpoint &checkpoint);\n\n    /// Add the block hash to the reservation.\n    void insert(const hash_digest &hash, size_t height);\n\n    /// Add to the blockchain, with height determined by the reservation.\n    void import(chain::block::ptr block);\n\n    /// Determine if the reservation was partitioned and reset partition flag.\n    bool toggle_partitioned();\n\n    /// Move half of the reservation to the specified reservation.\n    bool partition(reservation::ptr minimal);\n\n    /// If not stopped and if empty try to get more hashes.\n    void populate();\n\n  protected:\n    // Accessor for testability.\n    bool pending() const;\n\n    // Accessor for testability.\n    void set_pending(bool value);\n\n    // Accessor for validating construction.\n    std::chrono::microseconds rate_window() const;\n\n    // Isolation of side effect to enable unit testing.\n    virtual std::chrono::high_resolution_clock::time_point now() const;\n\n  private:\n    typedef struct\n    {\n        size_t events;\n        uint64_t database;\n        std::chrono::high_resolution_clock::time_point time;\n    } import_record;\n\n    typedef std::vector<import_record> rate_history;\n\n    // A bidirection map is used for efficient hash and height retrieval.\n    typedef boost::bimaps::bimap<\n        boost::bimaps::unordered_set_of<hash_digest>,\n        boost::bimaps::set_of<uint32_t>>\n        hash_heights;\n\n    // Return rate history to startup state.\n    void clear_history();\n\n    // Get the height of the block hash, remove and return true if it is found.\n    bool find_height_and_erase(const hash_digest &hash, uint32_t &out_height);\n\n    // Update rate history to reflect an additional block of the given size.\n    void update_rate(size_t events, const std::chrono::microseconds &database);\n\n    // Thread safe.\n    reservations &reservations_;\n\n    // Protected by rate mutex.\n    performance rate_;\n    mutable upgrade_mutex rate_mutex_;\n\n    // Protected by history mutex.\n    rate_history history_;\n    mutable upgrade_mutex history_mutex_;\n\n    // Protected by stop mutex.\n    bool stopped_;\n    mutable upgrade_mutex stop_mutex_;\n\n    // Protected by hash mutex.\n    bool pending_;\n    bool partitioned_;\n    hash_heights heights_;\n    mutable upgrade_mutex hash_mutex_;\n\n    const size_t slot_;\n    const std::chrono::microseconds rate_window_;\n};\n\n} // namespace node\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/node/utility/reservations.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_NODE_RESERVATIONS_HPP\n#define UC_NODE_RESERVATIONS_HPP\n\n#include <atomic>\n#include <cstddef>\n#include <cstdint>\n#include <memory>\n#include <vector>\n#include <UChain/blockchain.hpp>\n#include <UChain/node/define.hpp>\n#include <UChain/node/settings.hpp>\n#include <UChain/node/utility/header_queue.hpp>\n#include <UChain/node/utility/reservation.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\n// Class to manage a set of reservation objects during sync, thread safe.\nclass BCN_API reservations\n{\n  public:\n    typedef struct\n    {\n        size_t active_count;\n        double arithmentic_mean;\n        double standard_deviation;\n    } rate_statistics;\n\n    typedef std::shared_ptr<reservations> ptr;\n\n    /// Construct a reservation table of reservations, allocating hashes evenly\n    /// among the rows up to the limit of a single get headers p2p request.\n    reservations(header_queue &hashes, blockchain::simple_chain &chain,\n                 const settings &settings);\n\n    /// The average and standard deviation of block import rates.\n    rate_statistics rates() const;\n\n    /// Return a copy of the reservation table.\n    reservation::list table() const;\n\n    /// Import the given block to the blockchain at the specified height.\n    bool import(chain::block::ptr block, size_t height);\n\n    /// Populate a starved row by taking half of the hashes from a weak row.\n    bool populate(reservation::ptr minimal);\n\n    /// Remove the row from the reservation table if found.\n    void remove(reservation::ptr row);\n\n    /// The max size of a block request.\n    size_t max_request() const;\n\n    /// Set the max size of a block request (defaults to 50000).\n    void set_max_request(size_t value);\n\n    std::size_t size()\n    {\n        shared_lock lock(mutex_);\n        return table_.size();\n    }\n\n  private:\n    // Create the specified number of reservations and distribute hashes.\n    void initialize(size_t size);\n\n    // Mark hashes for blocks we already have.\n    void mark_existing();\n\n    // Find the reservation with the most hashes.\n    reservation::ptr find_maximal();\n\n    // Move half of the maximal reservation to the specified reservation.\n    bool partition(reservation::ptr minimal);\n\n    // Move the maximum unreserved hashes to the specified reservation.\n    bool reserve(reservation::ptr minimal);\n\n    // Thread safe.\n    header_queue &hashes_;\n    blockchain::simple_chain &blockchain_;\n\n    // Protected by mutex.\n    reservation::list table_;\n    mutable upgrade_mutex mutex_;\n\n    const uint32_t timeout_;\n    std::atomic<size_t> max_request_;\n};\n\n} // namespace node\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/node/version.hpp",
    "content": "///////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 2014-2018 libbitcoin-node developers (see COPYING).\n//\n//        GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY\n//\n///////////////////////////////////////////////////////////////////////////////\n#ifndef UC_NODE_VERSION_HPP\n#define UC_NODE_VERSION_HPP\n\n/**\n * The semantic version of this repository as: [major].[minor].[patch]\n * For interpretation of the versioning scheme see: http://semver.org\n */\n\n#define UC_NODE_VERSION \"0.0.6\"\n#define UC_NODE_MAJOR_VERSION 0\n#define UC_NODE_MINOR_VERSION 0\n#define UC_NODE_PATCH_VERSION 6\n\n#endif\n"
  },
  {
    "path": "include/UChain/node.hpp",
    "content": "///////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 2014-2018 libbitcoin-node developers (see COPYING).\n//\n//        GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY\n//\n///////////////////////////////////////////////////////////////////////////////\n#ifndef UC_NODE_HPP\n#define UC_NODE_HPP\n\n/**\n * API Users: Include only this header. Direct use of other headers is fragile\n * and unsupported as header organization is subject to change.\n *\n * Maintainers: Do not include this header internal to this library.\n */\n\n#include <UChain/blockchain.hpp>\n#include <UChain/network.hpp>\n#include <UChain/node/configuration.hpp>\n#include <UChain/node/define.hpp>\n#include <UChain/node/p2p_node.hpp>\n#include <UChain/node/parser.hpp>\n#include <UChain/node/settings.hpp>\n#include <UChain/node/version.hpp>\n#include <UChain/node/protocols/protocol_block_in.hpp>\n#include <UChain/node/protocols/protocol_block_out.hpp>\n#include <UChain/node/protocols/protocol_block_sync.hpp>\n#include <UChain/node/protocols/protocol_header_sync.hpp>\n#include <UChain/node/protocols/protocol_tx_in.hpp>\n#include <UChain/node/protocols/protocol_tx_out.hpp>\n#include <UChain/node/protocols/protocol_version_quiet.hpp>\n#include <UChain/node/sessions/session_block_sync.hpp>\n#include <UChain/node/sessions/session_header_sync.hpp>\n#include <UChain/node/sessions/session_inbound.hpp>\n#include <UChain/node/sessions/session_manual.hpp>\n#include <UChain/node/sessions/session_outbound.hpp>\n#include <UChain/node/utility/header_queue.hpp>\n#include <UChain/node/utility/performance.hpp>\n#include <UChain/node/utility/reservation.hpp>\n#include <UChain/node/utility/reservations.hpp>\n\n#endif\n"
  },
  {
    "path": "include/UChain/protocol/converter.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifdef UC_VERSION4\n\n#ifndef UC_PROTOCOL_CONVERSION_HPP\n#define UC_PROTOCOL_CONVERSION_HPP\n\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/protocol/define.hpp>\n#include <UChain/protocol/interface.pb.h>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\n\nclass BCP_API converter\n{\n  public:\n    virtual bool from_protocol(const point *point,\n                               chain::output_point &result);\n\n    virtual bool from_protocol(const std::shared_ptr<point> point,\n                               chain::output_point &result);\n\n    virtual bool from_protocol(const tx_input *input,\n                               chain::input &result);\n\n    virtual bool from_protocol(const std::shared_ptr<tx_input> input,\n                               chain::input &result);\n\n    virtual bool from_protocol(const tx_output *output,\n                               chain::output &result);\n\n    virtual bool from_protocol(const std::shared_ptr<tx_output> output,\n                               chain::output &result);\n\n    virtual bool from_protocol(const tx *transaction,\n                               chain::transaction &result);\n\n    virtual bool from_protocol(const std::shared_ptr<tx> transaction,\n                               chain::transaction &result);\n\n    virtual bool from_protocol(const block_header *header,\n                               chain::header &result);\n\n    virtual bool from_protocol(const std::shared_ptr<block_header> header,\n                               chain::header &result);\n\n    virtual bool from_protocol(const block *block, chain::block &result);\n\n    virtual bool from_protocol(const std::shared_ptr<block> block,\n                               chain::block &result);\n\n    virtual bool to_protocol(const chain::output_point &point,\n                             protocol::point &result);\n\n    virtual protocol::point *to_protocol(const chain::output_point &point);\n\n    virtual bool to_protocol(const chain::input &input,\n                             tx_input &result);\n\n    virtual tx_input *to_protocol(const chain::input &input);\n\n    virtual bool to_protocol(const chain::output &output,\n                             tx_output &result);\n\n    virtual tx_output *to_protocol(const chain::output &output);\n\n    virtual bool to_protocol(const chain::transaction &transaction,\n                             tx &result);\n\n    virtual tx *to_protocol(const chain::transaction &transaction);\n\n    virtual bool to_protocol(const chain::header &header,\n                             block_header &result);\n\n    virtual block_header *to_protocol(const chain::header &header);\n\n    virtual bool to_protocol(const chain::block &block,\n                             protocol::block &result);\n\n    virtual block *to_protocol(const chain::block &block);\n};\n\n} // namespace protocol\n} // namespace libbitcoin\n\n#endif\n\n#endif\n"
  },
  {
    "path": "include/UChain/protocol/define.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_PROTOCOL_DEFINE_HPP\n#define UC_PROTOCOL_DEFINE_HPP\n\n#include <UChain/coin.hpp>\n\n// We use the generic helper definitions in libbitcoin to define BCP_API\n// and BCP_INTERNAL. BCP_API is used for the public API symbols. It either DLL\n// imports or DLL exports (or does nothing for static build) BCP_INTERNAL is\n// used for non-api symbols.\n\n#if defined BCP_STATIC\n#define BCP_API\n#define BCP_INTERNAL\n#elif defined BCP_DLL\n#define BCP_API BC_HELPER_DLL_EXPORT\n#define BCP_INTERNAL BC_HELPER_DLL_LOCAL\n#else\n#define BCP_API BC_HELPER_DLL_IMPORT\n#define BCP_INTERNAL BC_HELPER_DLL_LOCAL\n#endif\n\n#if defined _WIN32\n#include <winsock.h>\ntypedef SOCKET file_descriptor;\n#else\ntypedef int file_descriptor;\n#endif\n\n#endif\n"
  },
  {
    "path": "include/UChain/protocol/interface.pb.h",
    "content": "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n// source: bitcoin/protocol/interface.proto\n\n#ifdef UC_VERSION4\n\n#ifndef PROTOBUF_bitcoin_2fprotocol_2finterface_2eproto__INCLUDED\n#define PROTOBUF_bitcoin_2fprotocol_2finterface_2eproto__INCLUDED\n\n#include <string>\n\n#include <google/protobuf/stubs/common.h>\n\n#if GOOGLE_PROTOBUF_VERSION < 2006000\n#error This file was generated by a newer version of protoc which is\n#error incompatible with your Protocol Buffer headers.  Please update\n#error your headers.\n#endif\n#if 2006000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION\n#error This file was generated by an older version of protoc which is\n#error incompatible with your Protocol Buffer headers.  Please\n#error regenerate this file with a newer version of protoc.\n#endif\n\n#include <google/protobuf/generated_message_util.h>\n#include <google/protobuf/message.h>\n#include <google/protobuf/repeated_field.h>\n#include <google/protobuf/extension_set.h>\n#include <google/protobuf/generated_enum_reflection.h>\n#include <google/protobuf/unknown_field_set.h>\n#include <UChain/protocol/define.hpp>\n// @@protoc_insertion_point(includes)\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\n\n// Internal implementation detail -- do not call these.\nvoid BCP_API protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\nvoid protobuf_AssignDesc_bitcoin_2fprotocol_2finterface_2eproto();\nvoid protobuf_ShutdownFile_bitcoin_2fprotocol_2finterface_2eproto();\n\nclass block_header;\nclass point;\nclass tx_input;\nclass tx_output;\nclass tx;\nclass block;\nclass filter;\nclass block_id;\nclass block_location;\nclass tx_hash_result;\nclass tx_result;\nclass output;\nclass utxo_result;\nclass block_headers_request;\nclass transactions_request;\nclass request;\nclass response;\nclass response_block_headers;\nclass response_transactions;\n\nenum filters\n{\n  ADDRESS = 1,\n  TRANSACTION = 2,\n  STEALTH = 3\n};\nBCP_API bool filters_IsValid(int value);\nconst filters filters_MIN = ADDRESS;\nconst filters filters_MAX = STEALTH;\nconst int filters_ARRAYSIZE = filters_MAX + 1;\n\nBCP_API const ::google::protobuf::EnumDescriptor *filters_descriptor();\ninline const ::std::string &filters_Name(filters value)\n{\n  return ::google::protobuf::internal::NameOfEnum(\n      filters_descriptor(), value);\n}\ninline bool filters_Parse(\n    const ::std::string &name, filters *value)\n{\n  return ::google::protobuf::internal::ParseNamedEnum<filters>(\n      filters_descriptor(), name, value);\n}\nenum tx_results\n{\n  TX_HASH = 1,\n  TX_RESULT = 2,\n  UTXO_RESULT = 3\n};\nBCP_API bool tx_results_IsValid(int value);\nconst tx_results tx_results_MIN = TX_HASH;\nconst tx_results tx_results_MAX = UTXO_RESULT;\nconst int tx_results_ARRAYSIZE = tx_results_MAX + 1;\n\nBCP_API const ::google::protobuf::EnumDescriptor *tx_results_descriptor();\ninline const ::std::string &tx_results_Name(tx_results value)\n{\n  return ::google::protobuf::internal::NameOfEnum(\n      tx_results_descriptor(), value);\n}\ninline bool tx_results_Parse(\n    const ::std::string &name, tx_results *value)\n{\n  return ::google::protobuf::internal::ParseNamedEnum<tx_results>(\n      tx_results_descriptor(), name, value);\n}\nenum locations\n{\n  NONE = 0,\n  BLOCK = 1,\n  MERKLE = 2\n};\nBCP_API bool locations_IsValid(int value);\nconst locations locations_MIN = NONE;\nconst locations locations_MAX = MERKLE;\nconst int locations_ARRAYSIZE = locations_MAX + 1;\n\nBCP_API const ::google::protobuf::EnumDescriptor *locations_descriptor();\ninline const ::std::string &locations_Name(locations value)\n{\n  return ::google::protobuf::internal::NameOfEnum(\n      locations_descriptor(), value);\n}\ninline bool locations_Parse(\n    const ::std::string &name, locations *value)\n{\n  return ::google::protobuf::internal::ParseNamedEnum<locations>(\n      locations_descriptor(), name, value);\n}\n// ===================================================================\n\nclass BCP_API block_header : public ::google::protobuf::Message\n{\npublic:\n  block_header();\n  virtual ~block_header();\n\n  block_header(const block_header &from);\n\n  inline block_header &operator=(const block_header &from)\n  {\n    CopyFrom(from);\n    return *this;\n  }\n\n  inline const ::google::protobuf::UnknownFieldSet &unknown_fields() const\n  {\n    return _unknown_fields_;\n  }\n\n  inline ::google::protobuf::UnknownFieldSet *mutable_unknown_fields()\n  {\n    return &_unknown_fields_;\n  }\n\n  static const ::google::protobuf::Descriptor *descriptor();\n  static const block_header &default_instance();\n\n  void Swap(block_header *other);\n\n  // implements Message ----------------------------------------------\n\n  block_header *New() const;\n  void CopyFrom(const ::google::protobuf::Message &from);\n  void MergeFrom(const ::google::protobuf::Message &from);\n  void CopyFrom(const block_header &from);\n  void MergeFrom(const block_header &from);\n  void Clear();\n  bool IsInitialized() const;\n\n  int ByteSize() const;\n  bool MergePartialFromCodedStream(\n      ::google::protobuf::io::CodedInputStream *input);\n  void SerializeWithCachedSizes(\n      ::google::protobuf::io::CodedOutputStream *output) const;\n  ::google::protobuf::uint8 *SerializeWithCachedSizesToArray(::google::protobuf::uint8 *output) const;\n  int GetCachedSize() const { return _cached_size_; }\n\nprivate:\n  void SharedCtor();\n  void SharedDtor();\n  void SetCachedSize(int size) const;\n\npublic:\n  ::google::protobuf::Metadata GetMetadata() const;\n\n  // nested types ----------------------------------------------------\n\n  // accessors -------------------------------------------------------\n\n  // required uint32 version = 1;\n  inline bool has_version() const;\n  inline void clear_version();\n  static const int kVersionFieldNumber = 1;\n  inline ::google::protobuf::uint32 version() const;\n  inline void set_version(::google::protobuf::uint32 value);\n\n  // required bytes previous_block_hash = 2;\n  inline bool has_previous_block_hash() const;\n  inline void clear_previous_block_hash();\n  static const int kPreviousBlockHashFieldNumber = 2;\n  inline const ::std::string &previous_block_hash() const;\n  inline void set_previous_block_hash(const ::std::string &value);\n  inline void set_previous_block_hash(const char *value);\n  inline void set_previous_block_hash(const void *value, size_t size);\n  inline ::std::string *mutable_previous_block_hash();\n  inline ::std::string *release_previous_block_hash();\n  inline void set_allocated_previous_block_hash(::std::string *previous_block_hash);\n\n  // required bytes merkle_root = 3;\n  inline bool has_merkle_root() const;\n  inline void clear_merkle_root();\n  static const int kMerkleRootFieldNumber = 3;\n  inline const ::std::string &merkle_root() const;\n  inline void set_merkle_root(const ::std::string &value);\n  inline void set_merkle_root(const char *value);\n  inline void set_merkle_root(const void *value, size_t size);\n  inline ::std::string *mutable_merkle_root();\n  inline ::std::string *release_merkle_root();\n  inline void set_allocated_merkle_root(::std::string *merkle_root);\n\n  // required uint32 timestamp = 4;\n  inline bool has_timestamp() const;\n  inline void clear_timestamp();\n  static const int kTimestampFieldNumber = 4;\n  inline ::google::protobuf::uint32 timestamp() const;\n  inline void set_timestamp(::google::protobuf::uint32 value);\n\n  // required uint32 bits = 5;\n  inline bool has_bits() const;\n  inline void clear_bits();\n  static const int kBitsFieldNumber = 5;\n  inline ::google::protobuf::uint32 bits() const;\n  inline void set_bits(::google::protobuf::uint32 value);\n\n  // required uint32 nonce = 6;\n  inline bool has_nonce() const;\n  inline void clear_nonce();\n  static const int kNonceFieldNumber = 6;\n  inline ::google::protobuf::uint32 nonce() const;\n  inline void set_nonce(::google::protobuf::uint32 value);\n\n  // required uint64 tx_count = 7;\n  inline bool has_tx_count() const;\n  inline void clear_tx_count();\n  static const int kTxCountFieldNumber = 7;\n  inline ::google::protobuf::uint64 tx_count() const;\n  inline void set_tx_count(::google::protobuf::uint64 value);\n\n  // @@protoc_insertion_point(class_scope:libbitcoin.protocol.block_header)\nprivate:\n  inline void set_has_version();\n  inline void clear_has_version();\n  inline void set_has_previous_block_hash();\n  inline void clear_has_previous_block_hash();\n  inline void set_has_merkle_root();\n  inline void clear_has_merkle_root();\n  inline void set_has_timestamp();\n  inline void clear_has_timestamp();\n  inline void set_has_bits();\n  inline void clear_has_bits();\n  inline void set_has_nonce();\n  inline void clear_has_nonce();\n  inline void set_has_tx_count();\n  inline void clear_has_tx_count();\n\n  ::google::protobuf::UnknownFieldSet _unknown_fields_;\n\n  ::google::protobuf::uint32 _has_bits_[1];\n  mutable int _cached_size_;\n  ::std::string *previous_block_hash_;\n  ::google::protobuf::uint32 version_;\n  ::google::protobuf::uint32 timestamp_;\n  ::std::string *merkle_root_;\n  ::google::protobuf::uint32 bits_;\n  ::google::protobuf::uint32 nonce_;\n  ::google::protobuf::uint64 tx_count_;\n  friend void BCP_API protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_AssignDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_ShutdownFile_bitcoin_2fprotocol_2finterface_2eproto();\n\n  void InitAsDefaultInstance();\n  static block_header *default_instance_;\n};\n// -------------------------------------------------------------------\n\nclass BCP_API point : public ::google::protobuf::Message\n{\npublic:\n  point();\n  virtual ~point();\n\n  point(const point &from);\n\n  inline point &operator=(const point &from)\n  {\n    CopyFrom(from);\n    return *this;\n  }\n\n  inline const ::google::protobuf::UnknownFieldSet &unknown_fields() const\n  {\n    return _unknown_fields_;\n  }\n\n  inline ::google::protobuf::UnknownFieldSet *mutable_unknown_fields()\n  {\n    return &_unknown_fields_;\n  }\n\n  static const ::google::protobuf::Descriptor *descriptor();\n  static const point &default_instance();\n\n  void Swap(point *other);\n\n  // implements Message ----------------------------------------------\n\n  point *New() const;\n  void CopyFrom(const ::google::protobuf::Message &from);\n  void MergeFrom(const ::google::protobuf::Message &from);\n  void CopyFrom(const point &from);\n  void MergeFrom(const point &from);\n  void Clear();\n  bool IsInitialized() const;\n\n  int ByteSize() const;\n  bool MergePartialFromCodedStream(\n      ::google::protobuf::io::CodedInputStream *input);\n  void SerializeWithCachedSizes(\n      ::google::protobuf::io::CodedOutputStream *output) const;\n  ::google::protobuf::uint8 *SerializeWithCachedSizesToArray(::google::protobuf::uint8 *output) const;\n  int GetCachedSize() const { return _cached_size_; }\n\nprivate:\n  void SharedCtor();\n  void SharedDtor();\n  void SetCachedSize(int size) const;\n\npublic:\n  ::google::protobuf::Metadata GetMetadata() const;\n\n  // nested types ----------------------------------------------------\n\n  // accessors -------------------------------------------------------\n\n  // required bytes hash = 1;\n  inline bool has_hash() const;\n  inline void clear_hash();\n  static const int kHashFieldNumber = 1;\n  inline const ::std::string &hash() const;\n  inline void set_hash(const ::std::string &value);\n  inline void set_hash(const char *value);\n  inline void set_hash(const void *value, size_t size);\n  inline ::std::string *mutable_hash();\n  inline ::std::string *release_hash();\n  inline void set_allocated_hash(::std::string *hash);\n\n  // required uint32 index = 2;\n  inline bool has_index() const;\n  inline void clear_index();\n  static const int kIndexFieldNumber = 2;\n  inline ::google::protobuf::uint32 index() const;\n  inline void set_index(::google::protobuf::uint32 value);\n\n  // @@protoc_insertion_point(class_scope:libbitcoin.protocol.point)\nprivate:\n  inline void set_has_hash();\n  inline void clear_has_hash();\n  inline void set_has_index();\n  inline void clear_has_index();\n\n  ::google::protobuf::UnknownFieldSet _unknown_fields_;\n\n  ::google::protobuf::uint32 _has_bits_[1];\n  mutable int _cached_size_;\n  ::std::string *hash_;\n  ::google::protobuf::uint32 index_;\n  friend void BCP_API protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_AssignDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_ShutdownFile_bitcoin_2fprotocol_2finterface_2eproto();\n\n  void InitAsDefaultInstance();\n  static point *default_instance_;\n};\n// -------------------------------------------------------------------\n\nclass BCP_API tx_input : public ::google::protobuf::Message\n{\npublic:\n  tx_input();\n  virtual ~tx_input();\n\n  tx_input(const tx_input &from);\n\n  inline tx_input &operator=(const tx_input &from)\n  {\n    CopyFrom(from);\n    return *this;\n  }\n\n  inline const ::google::protobuf::UnknownFieldSet &unknown_fields() const\n  {\n    return _unknown_fields_;\n  }\n\n  inline ::google::protobuf::UnknownFieldSet *mutable_unknown_fields()\n  {\n    return &_unknown_fields_;\n  }\n\n  static const ::google::protobuf::Descriptor *descriptor();\n  static const tx_input &default_instance();\n\n  void Swap(tx_input *other);\n\n  // implements Message ----------------------------------------------\n\n  tx_input *New() const;\n  void CopyFrom(const ::google::protobuf::Message &from);\n  void MergeFrom(const ::google::protobuf::Message &from);\n  void CopyFrom(const tx_input &from);\n  void MergeFrom(const tx_input &from);\n  void Clear();\n  bool IsInitialized() const;\n\n  int ByteSize() const;\n  bool MergePartialFromCodedStream(\n      ::google::protobuf::io::CodedInputStream *input);\n  void SerializeWithCachedSizes(\n      ::google::protobuf::io::CodedOutputStream *output) const;\n  ::google::protobuf::uint8 *SerializeWithCachedSizesToArray(::google::protobuf::uint8 *output) const;\n  int GetCachedSize() const { return _cached_size_; }\n\nprivate:\n  void SharedCtor();\n  void SharedDtor();\n  void SetCachedSize(int size) const;\n\npublic:\n  ::google::protobuf::Metadata GetMetadata() const;\n\n  // nested types ----------------------------------------------------\n\n  // accessors -------------------------------------------------------\n\n  // required .libbitcoin.protocol.point previous_output = 1;\n  inline bool has_previous_output() const;\n  inline void clear_previous_output();\n  static const int kPreviousOutputFieldNumber = 1;\n  inline const ::libbitcoin::protocol::point &previous_output() const;\n  inline ::libbitcoin::protocol::point *mutable_previous_output();\n  inline ::libbitcoin::protocol::point *release_previous_output();\n  inline void set_allocated_previous_output(::libbitcoin::protocol::point *previous_output);\n\n  // required bytes script = 2;\n  inline bool has_script() const;\n  inline void clear_script();\n  static const int kScriptFieldNumber = 2;\n  inline const ::std::string &script() const;\n  inline void set_script(const ::std::string &value);\n  inline void set_script(const char *value);\n  inline void set_script(const void *value, size_t size);\n  inline ::std::string *mutable_script();\n  inline ::std::string *release_script();\n  inline void set_allocated_script(::std::string *script);\n\n  // required uint32 sequence = 3;\n  inline bool has_sequence() const;\n  inline void clear_sequence();\n  static const int kSequenceFieldNumber = 3;\n  inline ::google::protobuf::uint32 sequence() const;\n  inline void set_sequence(::google::protobuf::uint32 value);\n\n  // @@protoc_insertion_point(class_scope:libbitcoin.protocol.tx_input)\nprivate:\n  inline void set_has_previous_output();\n  inline void clear_has_previous_output();\n  inline void set_has_script();\n  inline void clear_has_script();\n  inline void set_has_sequence();\n  inline void clear_has_sequence();\n\n  ::google::protobuf::UnknownFieldSet _unknown_fields_;\n\n  ::google::protobuf::uint32 _has_bits_[1];\n  mutable int _cached_size_;\n  ::libbitcoin::protocol::point *previous_output_;\n  ::std::string *script_;\n  ::google::protobuf::uint32 sequence_;\n  friend void BCP_API protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_AssignDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_ShutdownFile_bitcoin_2fprotocol_2finterface_2eproto();\n\n  void InitAsDefaultInstance();\n  static tx_input *default_instance_;\n};\n// -------------------------------------------------------------------\n\nclass BCP_API tx_output : public ::google::protobuf::Message\n{\npublic:\n  tx_output();\n  virtual ~tx_output();\n\n  tx_output(const tx_output &from);\n\n  inline tx_output &operator=(const tx_output &from)\n  {\n    CopyFrom(from);\n    return *this;\n  }\n\n  inline const ::google::protobuf::UnknownFieldSet &unknown_fields() const\n  {\n    return _unknown_fields_;\n  }\n\n  inline ::google::protobuf::UnknownFieldSet *mutable_unknown_fields()\n  {\n    return &_unknown_fields_;\n  }\n\n  static const ::google::protobuf::Descriptor *descriptor();\n  static const tx_output &default_instance();\n\n  void Swap(tx_output *other);\n\n  // implements Message ----------------------------------------------\n\n  tx_output *New() const;\n  void CopyFrom(const ::google::protobuf::Message &from);\n  void MergeFrom(const ::google::protobuf::Message &from);\n  void CopyFrom(const tx_output &from);\n  void MergeFrom(const tx_output &from);\n  void Clear();\n  bool IsInitialized() const;\n\n  int ByteSize() const;\n  bool MergePartialFromCodedStream(\n      ::google::protobuf::io::CodedInputStream *input);\n  void SerializeWithCachedSizes(\n      ::google::protobuf::io::CodedOutputStream *output) const;\n  ::google::protobuf::uint8 *SerializeWithCachedSizesToArray(::google::protobuf::uint8 *output) const;\n  int GetCachedSize() const { return _cached_size_; }\n\nprivate:\n  void SharedCtor();\n  void SharedDtor();\n  void SetCachedSize(int size) const;\n\npublic:\n  ::google::protobuf::Metadata GetMetadata() const;\n\n  // nested types ----------------------------------------------------\n\n  // accessors -------------------------------------------------------\n\n  // required uint64 value = 1;\n  inline bool has_value() const;\n  inline void clear_value();\n  static const int kValueFieldNumber = 1;\n  inline ::google::protobuf::uint64 value() const;\n  inline void set_value(::google::protobuf::uint64 value);\n\n  // required bytes script = 2;\n  inline bool has_script() const;\n  inline void clear_script();\n  static const int kScriptFieldNumber = 2;\n  inline const ::std::string &script() const;\n  inline void set_script(const ::std::string &value);\n  inline void set_script(const char *value);\n  inline void set_script(const void *value, size_t size);\n  inline ::std::string *mutable_script();\n  inline ::std::string *release_script();\n  inline void set_allocated_script(::std::string *script);\n\n  // @@protoc_insertion_point(class_scope:libbitcoin.protocol.tx_output)\nprivate:\n  inline void set_has_value();\n  inline void clear_has_value();\n  inline void set_has_script();\n  inline void clear_has_script();\n\n  ::google::protobuf::UnknownFieldSet _unknown_fields_;\n\n  ::google::protobuf::uint32 _has_bits_[1];\n  mutable int _cached_size_;\n  ::google::protobuf::uint64 value_;\n  ::std::string *script_;\n  friend void BCP_API protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_AssignDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_ShutdownFile_bitcoin_2fprotocol_2finterface_2eproto();\n\n  void InitAsDefaultInstance();\n  static tx_output *default_instance_;\n};\n// -------------------------------------------------------------------\n\nclass BCP_API tx : public ::google::protobuf::Message\n{\npublic:\n  tx();\n  virtual ~tx();\n\n  tx(const tx &from);\n\n  inline tx &operator=(const tx &from)\n  {\n    CopyFrom(from);\n    return *this;\n  }\n\n  inline const ::google::protobuf::UnknownFieldSet &unknown_fields() const\n  {\n    return _unknown_fields_;\n  }\n\n  inline ::google::protobuf::UnknownFieldSet *mutable_unknown_fields()\n  {\n    return &_unknown_fields_;\n  }\n\n  static const ::google::protobuf::Descriptor *descriptor();\n  static const tx &default_instance();\n\n  void Swap(tx *other);\n\n  // implements Message ----------------------------------------------\n\n  tx *New() const;\n  void CopyFrom(const ::google::protobuf::Message &from);\n  void MergeFrom(const ::google::protobuf::Message &from);\n  void CopyFrom(const tx &from);\n  void MergeFrom(const tx &from);\n  void Clear();\n  bool IsInitialized() const;\n\n  int ByteSize() const;\n  bool MergePartialFromCodedStream(\n      ::google::protobuf::io::CodedInputStream *input);\n  void SerializeWithCachedSizes(\n      ::google::protobuf::io::CodedOutputStream *output) const;\n  ::google::protobuf::uint8 *SerializeWithCachedSizesToArray(::google::protobuf::uint8 *output) const;\n  int GetCachedSize() const { return _cached_size_; }\n\nprivate:\n  void SharedCtor();\n  void SharedDtor();\n  void SetCachedSize(int size) const;\n\npublic:\n  ::google::protobuf::Metadata GetMetadata() const;\n\n  // nested types ----------------------------------------------------\n\n  // accessors -------------------------------------------------------\n\n  // required uint32 version = 1;\n  inline bool has_version() const;\n  inline void clear_version();\n  static const int kVersionFieldNumber = 1;\n  inline ::google::protobuf::uint32 version() const;\n  inline void set_version(::google::protobuf::uint32 value);\n\n  // required uint32 locktime = 2;\n  inline bool has_locktime() const;\n  inline void clear_locktime();\n  static const int kLocktimeFieldNumber = 2;\n  inline ::google::protobuf::uint32 locktime() const;\n  inline void set_locktime(::google::protobuf::uint32 value);\n\n  // repeated .libbitcoin.protocol.tx_input inputs = 3;\n  inline int inputs_size() const;\n  inline void clear_inputs();\n  static const int kInputsFieldNumber = 3;\n  inline const ::libbitcoin::protocol::tx_input &inputs(int index) const;\n  inline ::libbitcoin::protocol::tx_input *mutable_inputs(int index);\n  inline ::libbitcoin::protocol::tx_input *add_inputs();\n  inline const ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::tx_input> &\n  inputs() const;\n  inline ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::tx_input> *\n  mutable_inputs();\n\n  // repeated .libbitcoin.protocol.tx_output outputs = 4;\n  inline int outputs_size() const;\n  inline void clear_outputs();\n  static const int kOutputsFieldNumber = 4;\n  inline const ::libbitcoin::protocol::tx_output &outputs(int index) const;\n  inline ::libbitcoin::protocol::tx_output *mutable_outputs(int index);\n  inline ::libbitcoin::protocol::tx_output *add_outputs();\n  inline const ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::tx_output> &\n  outputs() const;\n  inline ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::tx_output> *\n  mutable_outputs();\n\n  // @@protoc_insertion_point(class_scope:libbitcoin.protocol.tx)\nprivate:\n  inline void set_has_version();\n  inline void clear_has_version();\n  inline void set_has_locktime();\n  inline void clear_has_locktime();\n\n  ::google::protobuf::UnknownFieldSet _unknown_fields_;\n\n  ::google::protobuf::uint32 _has_bits_[1];\n  mutable int _cached_size_;\n  ::google::protobuf::uint32 version_;\n  ::google::protobuf::uint32 locktime_;\n  ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::tx_input> inputs_;\n  ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::tx_output> outputs_;\n  friend void BCP_API protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_AssignDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_ShutdownFile_bitcoin_2fprotocol_2finterface_2eproto();\n\n  void InitAsDefaultInstance();\n  static tx *default_instance_;\n};\n// -------------------------------------------------------------------\n\nclass BCP_API block : public ::google::protobuf::Message\n{\npublic:\n  block();\n  virtual ~block();\n\n  block(const block &from);\n\n  inline block &operator=(const block &from)\n  {\n    CopyFrom(from);\n    return *this;\n  }\n\n  inline const ::google::protobuf::UnknownFieldSet &unknown_fields() const\n  {\n    return _unknown_fields_;\n  }\n\n  inline ::google::protobuf::UnknownFieldSet *mutable_unknown_fields()\n  {\n    return &_unknown_fields_;\n  }\n\n  static const ::google::protobuf::Descriptor *descriptor();\n  static const block &default_instance();\n\n  void Swap(block *other);\n\n  // implements Message ----------------------------------------------\n\n  block *New() const;\n  void CopyFrom(const ::google::protobuf::Message &from);\n  void MergeFrom(const ::google::protobuf::Message &from);\n  void CopyFrom(const block &from);\n  void MergeFrom(const block &from);\n  void Clear();\n  bool IsInitialized() const;\n\n  int ByteSize() const;\n  bool MergePartialFromCodedStream(\n      ::google::protobuf::io::CodedInputStream *input);\n  void SerializeWithCachedSizes(\n      ::google::protobuf::io::CodedOutputStream *output) const;\n  ::google::protobuf::uint8 *SerializeWithCachedSizesToArray(::google::protobuf::uint8 *output) const;\n  int GetCachedSize() const { return _cached_size_; }\n\nprivate:\n  void SharedCtor();\n  void SharedDtor();\n  void SetCachedSize(int size) const;\n\npublic:\n  ::google::protobuf::Metadata GetMetadata() const;\n\n  // nested types ----------------------------------------------------\n\n  // accessors -------------------------------------------------------\n\n  // required .libbitcoin.protocol.block_header header = 1;\n  inline bool has_header() const;\n  inline void clear_header();\n  static const int kHeaderFieldNumber = 1;\n  inline const ::libbitcoin::protocol::block_header &header() const;\n  inline ::libbitcoin::protocol::block_header *mutable_header();\n  inline ::libbitcoin::protocol::block_header *release_header();\n  inline void set_allocated_header(::libbitcoin::protocol::block_header *header);\n\n  // repeated .libbitcoin.protocol.tx transactions = 2;\n  inline int transactions_size() const;\n  inline void clear_transactions();\n  static const int kTransactionsFieldNumber = 2;\n  inline const ::libbitcoin::protocol::tx &transactions(int index) const;\n  inline ::libbitcoin::protocol::tx *mutable_transactions(int index);\n  inline ::libbitcoin::protocol::tx *add_transactions();\n  inline const ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::tx> &\n  transactions() const;\n  inline ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::tx> *\n  mutable_transactions();\n\n  // repeated bytes tree = 3;\n  inline int tree_size() const;\n  inline void clear_tree();\n  static const int kTreeFieldNumber = 3;\n  inline const ::std::string &tree(int index) const;\n  inline ::std::string *mutable_tree(int index);\n  inline void set_tree(int index, const ::std::string &value);\n  inline void set_tree(int index, const char *value);\n  inline void set_tree(int index, const void *value, size_t size);\n  inline ::std::string *add_tree();\n  inline void add_tree(const ::std::string &value);\n  inline void add_tree(const char *value);\n  inline void add_tree(const void *value, size_t size);\n  inline const ::google::protobuf::RepeatedPtrField<::std::string> &tree() const;\n  inline ::google::protobuf::RepeatedPtrField<::std::string> *mutable_tree();\n\n  // @@protoc_insertion_point(class_scope:libbitcoin.protocol.block)\nprivate:\n  inline void set_has_header();\n  inline void clear_has_header();\n\n  ::google::protobuf::UnknownFieldSet _unknown_fields_;\n\n  ::google::protobuf::uint32 _has_bits_[1];\n  mutable int _cached_size_;\n  ::libbitcoin::protocol::block_header *header_;\n  ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::tx> transactions_;\n  ::google::protobuf::RepeatedPtrField<::std::string> tree_;\n  friend void BCP_API protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_AssignDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_ShutdownFile_bitcoin_2fprotocol_2finterface_2eproto();\n\n  void InitAsDefaultInstance();\n  static block *default_instance_;\n};\n// -------------------------------------------------------------------\n\nclass BCP_API filter : public ::google::protobuf::Message\n{\npublic:\n  filter();\n  virtual ~filter();\n\n  filter(const filter &from);\n\n  inline filter &operator=(const filter &from)\n  {\n    CopyFrom(from);\n    return *this;\n  }\n\n  inline const ::google::protobuf::UnknownFieldSet &unknown_fields() const\n  {\n    return _unknown_fields_;\n  }\n\n  inline ::google::protobuf::UnknownFieldSet *mutable_unknown_fields()\n  {\n    return &_unknown_fields_;\n  }\n\n  static const ::google::protobuf::Descriptor *descriptor();\n  static const filter &default_instance();\n\n  void Swap(filter *other);\n\n  // implements Message ----------------------------------------------\n\n  filter *New() const;\n  void CopyFrom(const ::google::protobuf::Message &from);\n  void MergeFrom(const ::google::protobuf::Message &from);\n  void CopyFrom(const filter &from);\n  void MergeFrom(const filter &from);\n  void Clear();\n  bool IsInitialized() const;\n\n  int ByteSize() const;\n  bool MergePartialFromCodedStream(\n      ::google::protobuf::io::CodedInputStream *input);\n  void SerializeWithCachedSizes(\n      ::google::protobuf::io::CodedOutputStream *output) const;\n  ::google::protobuf::uint8 *SerializeWithCachedSizesToArray(::google::protobuf::uint8 *output) const;\n  int GetCachedSize() const { return _cached_size_; }\n\nprivate:\n  void SharedCtor();\n  void SharedDtor();\n  void SetCachedSize(int size) const;\n\npublic:\n  ::google::protobuf::Metadata GetMetadata() const;\n\n  // nested types ----------------------------------------------------\n\n  // accessors -------------------------------------------------------\n\n  // required .libbitcoin.protocol.filters filter_type = 1;\n  inline bool has_filter_type() const;\n  inline void clear_filter_type();\n  static const int kFilterTypeFieldNumber = 1;\n  inline ::libbitcoin::protocol::filters filter_type() const;\n  inline void set_filter_type(::libbitcoin::protocol::filters value);\n\n  // optional uint32 bits = 2;\n  inline bool has_bits() const;\n  inline void clear_bits();\n  static const int kBitsFieldNumber = 2;\n  inline ::google::protobuf::uint32 bits() const;\n  inline void set_bits(::google::protobuf::uint32 value);\n\n  // required bytes prefix = 3;\n  inline bool has_prefix() const;\n  inline void clear_prefix();\n  static const int kPrefixFieldNumber = 3;\n  inline const ::std::string &prefix() const;\n  inline void set_prefix(const ::std::string &value);\n  inline void set_prefix(const char *value);\n  inline void set_prefix(const void *value, size_t size);\n  inline ::std::string *mutable_prefix();\n  inline ::std::string *release_prefix();\n  inline void set_allocated_prefix(::std::string *prefix);\n\n  // @@protoc_insertion_point(class_scope:libbitcoin.protocol.filter)\nprivate:\n  inline void set_has_filter_type();\n  inline void clear_has_filter_type();\n  inline void set_has_bits();\n  inline void clear_has_bits();\n  inline void set_has_prefix();\n  inline void clear_has_prefix();\n\n  ::google::protobuf::UnknownFieldSet _unknown_fields_;\n\n  ::google::protobuf::uint32 _has_bits_[1];\n  mutable int _cached_size_;\n  int filter_type_;\n  ::google::protobuf::uint32 bits_;\n  ::std::string *prefix_;\n  friend void BCP_API protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_AssignDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_ShutdownFile_bitcoin_2fprotocol_2finterface_2eproto();\n\n  void InitAsDefaultInstance();\n  static filter *default_instance_;\n};\n// -------------------------------------------------------------------\n\nclass BCP_API block_id : public ::google::protobuf::Message\n{\npublic:\n  block_id();\n  virtual ~block_id();\n\n  block_id(const block_id &from);\n\n  inline block_id &operator=(const block_id &from)\n  {\n    CopyFrom(from);\n    return *this;\n  }\n\n  inline const ::google::protobuf::UnknownFieldSet &unknown_fields() const\n  {\n    return _unknown_fields_;\n  }\n\n  inline ::google::protobuf::UnknownFieldSet *mutable_unknown_fields()\n  {\n    return &_unknown_fields_;\n  }\n\n  static const ::google::protobuf::Descriptor *descriptor();\n  static const block_id &default_instance();\n\n  void Swap(block_id *other);\n\n  // implements Message ----------------------------------------------\n\n  block_id *New() const;\n  void CopyFrom(const ::google::protobuf::Message &from);\n  void MergeFrom(const ::google::protobuf::Message &from);\n  void CopyFrom(const block_id &from);\n  void MergeFrom(const block_id &from);\n  void Clear();\n  bool IsInitialized() const;\n\n  int ByteSize() const;\n  bool MergePartialFromCodedStream(\n      ::google::protobuf::io::CodedInputStream *input);\n  void SerializeWithCachedSizes(\n      ::google::protobuf::io::CodedOutputStream *output) const;\n  ::google::protobuf::uint8 *SerializeWithCachedSizesToArray(::google::protobuf::uint8 *output) const;\n  int GetCachedSize() const { return _cached_size_; }\n\nprivate:\n  void SharedCtor();\n  void SharedDtor();\n  void SetCachedSize(int size) const;\n\npublic:\n  ::google::protobuf::Metadata GetMetadata() const;\n\n  // nested types ----------------------------------------------------\n\n  // accessors -------------------------------------------------------\n\n  // optional uint32 height = 1;\n  inline bool has_height() const;\n  inline void clear_height();\n  static const int kHeightFieldNumber = 1;\n  inline ::google::protobuf::uint32 height() const;\n  inline void set_height(::google::protobuf::uint32 value);\n\n  // optional bytes hash = 2;\n  inline bool has_hash() const;\n  inline void clear_hash();\n  static const int kHashFieldNumber = 2;\n  inline const ::std::string &hash() const;\n  inline void set_hash(const ::std::string &value);\n  inline void set_hash(const char *value);\n  inline void set_hash(const void *value, size_t size);\n  inline ::std::string *mutable_hash();\n  inline ::std::string *release_hash();\n  inline void set_allocated_hash(::std::string *hash);\n\n  // @@protoc_insertion_point(class_scope:libbitcoin.protocol.block_id)\nprivate:\n  inline void set_has_height();\n  inline void clear_has_height();\n  inline void set_has_hash();\n  inline void clear_has_hash();\n\n  ::google::protobuf::UnknownFieldSet _unknown_fields_;\n\n  ::google::protobuf::uint32 _has_bits_[1];\n  mutable int _cached_size_;\n  ::std::string *hash_;\n  ::google::protobuf::uint32 height_;\n  friend void BCP_API protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_AssignDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_ShutdownFile_bitcoin_2fprotocol_2finterface_2eproto();\n\n  void InitAsDefaultInstance();\n  static block_id *default_instance_;\n};\n// -------------------------------------------------------------------\n\nclass BCP_API block_location : public ::google::protobuf::Message\n{\npublic:\n  block_location();\n  virtual ~block_location();\n\n  block_location(const block_location &from);\n\n  inline block_location &operator=(const block_location &from)\n  {\n    CopyFrom(from);\n    return *this;\n  }\n\n  inline const ::google::protobuf::UnknownFieldSet &unknown_fields() const\n  {\n    return _unknown_fields_;\n  }\n\n  inline ::google::protobuf::UnknownFieldSet *mutable_unknown_fields()\n  {\n    return &_unknown_fields_;\n  }\n\n  static const ::google::protobuf::Descriptor *descriptor();\n  static const block_location &default_instance();\n\n  void Swap(block_location *other);\n\n  // implements Message ----------------------------------------------\n\n  block_location *New() const;\n  void CopyFrom(const ::google::protobuf::Message &from);\n  void MergeFrom(const ::google::protobuf::Message &from);\n  void CopyFrom(const block_location &from);\n  void MergeFrom(const block_location &from);\n  void Clear();\n  bool IsInitialized() const;\n\n  int ByteSize() const;\n  bool MergePartialFromCodedStream(\n      ::google::protobuf::io::CodedInputStream *input);\n  void SerializeWithCachedSizes(\n      ::google::protobuf::io::CodedOutputStream *output) const;\n  ::google::protobuf::uint8 *SerializeWithCachedSizesToArray(::google::protobuf::uint8 *output) const;\n  int GetCachedSize() const { return _cached_size_; }\n\nprivate:\n  void SharedCtor();\n  void SharedDtor();\n  void SetCachedSize(int size) const;\n\npublic:\n  ::google::protobuf::Metadata GetMetadata() const;\n\n  // nested types ----------------------------------------------------\n\n  // accessors -------------------------------------------------------\n\n  // optional .libbitcoin.protocol.block_id identity = 1;\n  inline bool has_identity() const;\n  inline void clear_identity();\n  static const int kIdentityFieldNumber = 1;\n  inline const ::libbitcoin::protocol::block_id &identity() const;\n  inline ::libbitcoin::protocol::block_id *mutable_identity();\n  inline ::libbitcoin::protocol::block_id *release_identity();\n  inline void set_allocated_identity(::libbitcoin::protocol::block_id *identity);\n\n  // optional uint64 index = 2;\n  inline bool has_index() const;\n  inline void clear_index();\n  static const int kIndexFieldNumber = 2;\n  inline ::google::protobuf::uint64 index() const;\n  inline void set_index(::google::protobuf::uint64 value);\n\n  // repeated bytes branch = 3;\n  inline int branch_size() const;\n  inline void clear_branch();\n  static const int kBranchFieldNumber = 3;\n  inline const ::std::string &branch(int index) const;\n  inline ::std::string *mutable_branch(int index);\n  inline void set_branch(int index, const ::std::string &value);\n  inline void set_branch(int index, const char *value);\n  inline void set_branch(int index, const void *value, size_t size);\n  inline ::std::string *add_branch();\n  inline void add_branch(const ::std::string &value);\n  inline void add_branch(const char *value);\n  inline void add_branch(const void *value, size_t size);\n  inline const ::google::protobuf::RepeatedPtrField<::std::string> &branch() const;\n  inline ::google::protobuf::RepeatedPtrField<::std::string> *mutable_branch();\n\n  // @@protoc_insertion_point(class_scope:libbitcoin.protocol.block_location)\nprivate:\n  inline void set_has_identity();\n  inline void clear_has_identity();\n  inline void set_has_index();\n  inline void clear_has_index();\n\n  ::google::protobuf::UnknownFieldSet _unknown_fields_;\n\n  ::google::protobuf::uint32 _has_bits_[1];\n  mutable int _cached_size_;\n  ::libbitcoin::protocol::block_id *identity_;\n  ::google::protobuf::uint64 index_;\n  ::google::protobuf::RepeatedPtrField<::std::string> branch_;\n  friend void BCP_API protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_AssignDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_ShutdownFile_bitcoin_2fprotocol_2finterface_2eproto();\n\n  void InitAsDefaultInstance();\n  static block_location *default_instance_;\n};\n// -------------------------------------------------------------------\n\nclass BCP_API tx_hash_result : public ::google::protobuf::Message\n{\npublic:\n  tx_hash_result();\n  virtual ~tx_hash_result();\n\n  tx_hash_result(const tx_hash_result &from);\n\n  inline tx_hash_result &operator=(const tx_hash_result &from)\n  {\n    CopyFrom(from);\n    return *this;\n  }\n\n  inline const ::google::protobuf::UnknownFieldSet &unknown_fields() const\n  {\n    return _unknown_fields_;\n  }\n\n  inline ::google::protobuf::UnknownFieldSet *mutable_unknown_fields()\n  {\n    return &_unknown_fields_;\n  }\n\n  static const ::google::protobuf::Descriptor *descriptor();\n  static const tx_hash_result &default_instance();\n\n  void Swap(tx_hash_result *other);\n\n  // implements Message ----------------------------------------------\n\n  tx_hash_result *New() const;\n  void CopyFrom(const ::google::protobuf::Message &from);\n  void MergeFrom(const ::google::protobuf::Message &from);\n  void CopyFrom(const tx_hash_result &from);\n  void MergeFrom(const tx_hash_result &from);\n  void Clear();\n  bool IsInitialized() const;\n\n  int ByteSize() const;\n  bool MergePartialFromCodedStream(\n      ::google::protobuf::io::CodedInputStream *input);\n  void SerializeWithCachedSizes(\n      ::google::protobuf::io::CodedOutputStream *output) const;\n  ::google::protobuf::uint8 *SerializeWithCachedSizesToArray(::google::protobuf::uint8 *output) const;\n  int GetCachedSize() const { return _cached_size_; }\n\nprivate:\n  void SharedCtor();\n  void SharedDtor();\n  void SetCachedSize(int size) const;\n\npublic:\n  ::google::protobuf::Metadata GetMetadata() const;\n\n  // nested types ----------------------------------------------------\n\n  // accessors -------------------------------------------------------\n\n  // required bytes hash = 1;\n  inline bool has_hash() const;\n  inline void clear_hash();\n  static const int kHashFieldNumber = 1;\n  inline const ::std::string &hash() const;\n  inline void set_hash(const ::std::string &value);\n  inline void set_hash(const char *value);\n  inline void set_hash(const void *value, size_t size);\n  inline ::std::string *mutable_hash();\n  inline ::std::string *release_hash();\n  inline void set_allocated_hash(::std::string *hash);\n\n  // required .libbitcoin.protocol.block_location location = 2;\n  inline bool has_location() const;\n  inline void clear_location();\n  static const int kLocationFieldNumber = 2;\n  inline const ::libbitcoin::protocol::block_location &location() const;\n  inline ::libbitcoin::protocol::block_location *mutable_location();\n  inline ::libbitcoin::protocol::block_location *release_location();\n  inline void set_allocated_location(::libbitcoin::protocol::block_location *location);\n\n  // @@protoc_insertion_point(class_scope:libbitcoin.protocol.tx_hash_result)\nprivate:\n  inline void set_has_hash();\n  inline void clear_has_hash();\n  inline void set_has_location();\n  inline void clear_has_location();\n\n  ::google::protobuf::UnknownFieldSet _unknown_fields_;\n\n  ::google::protobuf::uint32 _has_bits_[1];\n  mutable int _cached_size_;\n  ::std::string *hash_;\n  ::libbitcoin::protocol::block_location *location_;\n  friend void BCP_API protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_AssignDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_ShutdownFile_bitcoin_2fprotocol_2finterface_2eproto();\n\n  void InitAsDefaultInstance();\n  static tx_hash_result *default_instance_;\n};\n// -------------------------------------------------------------------\n\nclass BCP_API tx_result : public ::google::protobuf::Message\n{\npublic:\n  tx_result();\n  virtual ~tx_result();\n\n  tx_result(const tx_result &from);\n\n  inline tx_result &operator=(const tx_result &from)\n  {\n    CopyFrom(from);\n    return *this;\n  }\n\n  inline const ::google::protobuf::UnknownFieldSet &unknown_fields() const\n  {\n    return _unknown_fields_;\n  }\n\n  inline ::google::protobuf::UnknownFieldSet *mutable_unknown_fields()\n  {\n    return &_unknown_fields_;\n  }\n\n  static const ::google::protobuf::Descriptor *descriptor();\n  static const tx_result &default_instance();\n\n  void Swap(tx_result *other);\n\n  // implements Message ----------------------------------------------\n\n  tx_result *New() const;\n  void CopyFrom(const ::google::protobuf::Message &from);\n  void MergeFrom(const ::google::protobuf::Message &from);\n  void CopyFrom(const tx_result &from);\n  void MergeFrom(const tx_result &from);\n  void Clear();\n  bool IsInitialized() const;\n\n  int ByteSize() const;\n  bool MergePartialFromCodedStream(\n      ::google::protobuf::io::CodedInputStream *input);\n  void SerializeWithCachedSizes(\n      ::google::protobuf::io::CodedOutputStream *output) const;\n  ::google::protobuf::uint8 *SerializeWithCachedSizesToArray(::google::protobuf::uint8 *output) const;\n  int GetCachedSize() const { return _cached_size_; }\n\nprivate:\n  void SharedCtor();\n  void SharedDtor();\n  void SetCachedSize(int size) const;\n\npublic:\n  ::google::protobuf::Metadata GetMetadata() const;\n\n  // nested types ----------------------------------------------------\n\n  // accessors -------------------------------------------------------\n\n  // required .libbitcoin.protocol.tx transaction = 1;\n  inline bool has_transaction() const;\n  inline void clear_transaction();\n  static const int kTransactionFieldNumber = 1;\n  inline const ::libbitcoin::protocol::tx &transaction() const;\n  inline ::libbitcoin::protocol::tx *mutable_transaction();\n  inline ::libbitcoin::protocol::tx *release_transaction();\n  inline void set_allocated_transaction(::libbitcoin::protocol::tx *transaction);\n\n  // required .libbitcoin.protocol.block_location location = 2;\n  inline bool has_location() const;\n  inline void clear_location();\n  static const int kLocationFieldNumber = 2;\n  inline const ::libbitcoin::protocol::block_location &location() const;\n  inline ::libbitcoin::protocol::block_location *mutable_location();\n  inline ::libbitcoin::protocol::block_location *release_location();\n  inline void set_allocated_location(::libbitcoin::protocol::block_location *location);\n\n  // @@protoc_insertion_point(class_scope:libbitcoin.protocol.tx_result)\nprivate:\n  inline void set_has_transaction();\n  inline void clear_has_transaction();\n  inline void set_has_location();\n  inline void clear_has_location();\n\n  ::google::protobuf::UnknownFieldSet _unknown_fields_;\n\n  ::google::protobuf::uint32 _has_bits_[1];\n  mutable int _cached_size_;\n  ::libbitcoin::protocol::tx *transaction_;\n  ::libbitcoin::protocol::block_location *location_;\n  friend void BCP_API protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_AssignDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_ShutdownFile_bitcoin_2fprotocol_2finterface_2eproto();\n\n  void InitAsDefaultInstance();\n  static tx_result *default_instance_;\n};\n// -------------------------------------------------------------------\n\nclass BCP_API output : public ::google::protobuf::Message\n{\npublic:\n  output();\n  virtual ~output();\n\n  output(const output &from);\n\n  inline output &operator=(const output &from)\n  {\n    CopyFrom(from);\n    return *this;\n  }\n\n  inline const ::google::protobuf::UnknownFieldSet &unknown_fields() const\n  {\n    return _unknown_fields_;\n  }\n\n  inline ::google::protobuf::UnknownFieldSet *mutable_unknown_fields()\n  {\n    return &_unknown_fields_;\n  }\n\n  static const ::google::protobuf::Descriptor *descriptor();\n  static const output &default_instance();\n\n  void Swap(output *other);\n\n  // implements Message ----------------------------------------------\n\n  output *New() const;\n  void CopyFrom(const ::google::protobuf::Message &from);\n  void MergeFrom(const ::google::protobuf::Message &from);\n  void CopyFrom(const output &from);\n  void MergeFrom(const output &from);\n  void Clear();\n  bool IsInitialized() const;\n\n  int ByteSize() const;\n  bool MergePartialFromCodedStream(\n      ::google::protobuf::io::CodedInputStream *input);\n  void SerializeWithCachedSizes(\n      ::google::protobuf::io::CodedOutputStream *output) const;\n  ::google::protobuf::uint8 *SerializeWithCachedSizesToArray(::google::protobuf::uint8 *output) const;\n  int GetCachedSize() const { return _cached_size_; }\n\nprivate:\n  void SharedCtor();\n  void SharedDtor();\n  void SetCachedSize(int size) const;\n\npublic:\n  ::google::protobuf::Metadata GetMetadata() const;\n\n  // nested types ----------------------------------------------------\n\n  // accessors -------------------------------------------------------\n\n  // required uint32 index = 1;\n  inline bool has_index() const;\n  inline void clear_index();\n  static const int kIndexFieldNumber = 1;\n  inline ::google::protobuf::uint32 index() const;\n  inline void set_index(::google::protobuf::uint32 value);\n\n  // required uint64 satoshis = 2;\n  inline bool has_satoshis() const;\n  inline void clear_satoshis();\n  static const int kSatoshisFieldNumber = 2;\n  inline ::google::protobuf::uint64 satoshis() const;\n  inline void set_satoshis(::google::protobuf::uint64 value);\n\n  // required bytes script = 3;\n  inline bool has_script() const;\n  inline void clear_script();\n  static const int kScriptFieldNumber = 3;\n  inline const ::std::string &script() const;\n  inline void set_script(const ::std::string &value);\n  inline void set_script(const char *value);\n  inline void set_script(const void *value, size_t size);\n  inline ::std::string *mutable_script();\n  inline ::std::string *release_script();\n  inline void set_allocated_script(::std::string *script);\n\n  // @@protoc_insertion_point(class_scope:libbitcoin.protocol.output)\nprivate:\n  inline void set_has_index();\n  inline void clear_has_index();\n  inline void set_has_satoshis();\n  inline void clear_has_satoshis();\n  inline void set_has_script();\n  inline void clear_has_script();\n\n  ::google::protobuf::UnknownFieldSet _unknown_fields_;\n\n  ::google::protobuf::uint32 _has_bits_[1];\n  mutable int _cached_size_;\n  ::google::protobuf::uint64 satoshis_;\n  ::std::string *script_;\n  ::google::protobuf::uint32 index_;\n  friend void BCP_API protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_AssignDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_ShutdownFile_bitcoin_2fprotocol_2finterface_2eproto();\n\n  void InitAsDefaultInstance();\n  static output *default_instance_;\n};\n// -------------------------------------------------------------------\n\nclass BCP_API utxo_result : public ::google::protobuf::Message\n{\npublic:\n  utxo_result();\n  virtual ~utxo_result();\n\n  utxo_result(const utxo_result &from);\n\n  inline utxo_result &operator=(const utxo_result &from)\n  {\n    CopyFrom(from);\n    return *this;\n  }\n\n  inline const ::google::protobuf::UnknownFieldSet &unknown_fields() const\n  {\n    return _unknown_fields_;\n  }\n\n  inline ::google::protobuf::UnknownFieldSet *mutable_unknown_fields()\n  {\n    return &_unknown_fields_;\n  }\n\n  static const ::google::protobuf::Descriptor *descriptor();\n  static const utxo_result &default_instance();\n\n  void Swap(utxo_result *other);\n\n  // implements Message ----------------------------------------------\n\n  utxo_result *New() const;\n  void CopyFrom(const ::google::protobuf::Message &from);\n  void MergeFrom(const ::google::protobuf::Message &from);\n  void CopyFrom(const utxo_result &from);\n  void MergeFrom(const utxo_result &from);\n  void Clear();\n  bool IsInitialized() const;\n\n  int ByteSize() const;\n  bool MergePartialFromCodedStream(\n      ::google::protobuf::io::CodedInputStream *input);\n  void SerializeWithCachedSizes(\n      ::google::protobuf::io::CodedOutputStream *output) const;\n  ::google::protobuf::uint8 *SerializeWithCachedSizesToArray(::google::protobuf::uint8 *output) const;\n  int GetCachedSize() const { return _cached_size_; }\n\nprivate:\n  void SharedCtor();\n  void SharedDtor();\n  void SetCachedSize(int size) const;\n\npublic:\n  ::google::protobuf::Metadata GetMetadata() const;\n\n  // nested types ----------------------------------------------------\n\n  // accessors -------------------------------------------------------\n\n  // required bytes tx_hash = 1;\n  inline bool has_tx_hash() const;\n  inline void clear_tx_hash();\n  static const int kTxHashFieldNumber = 1;\n  inline const ::std::string &tx_hash() const;\n  inline void set_tx_hash(const ::std::string &value);\n  inline void set_tx_hash(const char *value);\n  inline void set_tx_hash(const void *value, size_t size);\n  inline ::std::string *mutable_tx_hash();\n  inline ::std::string *release_tx_hash();\n  inline void set_allocated_tx_hash(::std::string *tx_hash);\n\n  // required .libbitcoin.protocol.block_location location = 2;\n  inline bool has_location() const;\n  inline void clear_location();\n  static const int kLocationFieldNumber = 2;\n  inline const ::libbitcoin::protocol::block_location &location() const;\n  inline ::libbitcoin::protocol::block_location *mutable_location();\n  inline ::libbitcoin::protocol::block_location *release_location();\n  inline void set_allocated_location(::libbitcoin::protocol::block_location *location);\n\n  // repeated .libbitcoin.protocol.output outputs = 3;\n  inline int outputs_size() const;\n  inline void clear_outputs();\n  static const int kOutputsFieldNumber = 3;\n  inline const ::libbitcoin::protocol::output &outputs(int index) const;\n  inline ::libbitcoin::protocol::output *mutable_outputs(int index);\n  inline ::libbitcoin::protocol::output *add_outputs();\n  inline const ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::output> &\n  outputs() const;\n  inline ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::output> *\n  mutable_outputs();\n\n  // @@protoc_insertion_point(class_scope:libbitcoin.protocol.utxo_result)\nprivate:\n  inline void set_has_tx_hash();\n  inline void clear_has_tx_hash();\n  inline void set_has_location();\n  inline void clear_has_location();\n\n  ::google::protobuf::UnknownFieldSet _unknown_fields_;\n\n  ::google::protobuf::uint32 _has_bits_[1];\n  mutable int _cached_size_;\n  ::std::string *tx_hash_;\n  ::libbitcoin::protocol::block_location *location_;\n  ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::output> outputs_;\n  friend void BCP_API protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_AssignDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_ShutdownFile_bitcoin_2fprotocol_2finterface_2eproto();\n\n  void InitAsDefaultInstance();\n  static utxo_result *default_instance_;\n};\n// -------------------------------------------------------------------\n\nclass BCP_API block_headers_request : public ::google::protobuf::Message\n{\npublic:\n  block_headers_request();\n  virtual ~block_headers_request();\n\n  block_headers_request(const block_headers_request &from);\n\n  inline block_headers_request &operator=(const block_headers_request &from)\n  {\n    CopyFrom(from);\n    return *this;\n  }\n\n  inline const ::google::protobuf::UnknownFieldSet &unknown_fields() const\n  {\n    return _unknown_fields_;\n  }\n\n  inline ::google::protobuf::UnknownFieldSet *mutable_unknown_fields()\n  {\n    return &_unknown_fields_;\n  }\n\n  static const ::google::protobuf::Descriptor *descriptor();\n  static const block_headers_request &default_instance();\n\n  void Swap(block_headers_request *other);\n\n  // implements Message ----------------------------------------------\n\n  block_headers_request *New() const;\n  void CopyFrom(const ::google::protobuf::Message &from);\n  void MergeFrom(const ::google::protobuf::Message &from);\n  void CopyFrom(const block_headers_request &from);\n  void MergeFrom(const block_headers_request &from);\n  void Clear();\n  bool IsInitialized() const;\n\n  int ByteSize() const;\n  bool MergePartialFromCodedStream(\n      ::google::protobuf::io::CodedInputStream *input);\n  void SerializeWithCachedSizes(\n      ::google::protobuf::io::CodedOutputStream *output) const;\n  ::google::protobuf::uint8 *SerializeWithCachedSizesToArray(::google::protobuf::uint8 *output) const;\n  int GetCachedSize() const { return _cached_size_; }\n\nprivate:\n  void SharedCtor();\n  void SharedDtor();\n  void SetCachedSize(int size) const;\n\npublic:\n  ::google::protobuf::Metadata GetMetadata() const;\n\n  // nested types ----------------------------------------------------\n\n  // accessors -------------------------------------------------------\n\n  // optional .libbitcoin.protocol.block_id start = 1;\n  inline bool has_start() const;\n  inline void clear_start();\n  static const int kStartFieldNumber = 1;\n  inline const ::libbitcoin::protocol::block_id &start() const;\n  inline ::libbitcoin::protocol::block_id *mutable_start();\n  inline ::libbitcoin::protocol::block_id *release_start();\n  inline void set_allocated_start(::libbitcoin::protocol::block_id *start);\n\n  // optional uint32 results_per_page = 2;\n  inline bool has_results_per_page() const;\n  inline void clear_results_per_page();\n  static const int kResultsPerPageFieldNumber = 2;\n  inline ::google::protobuf::uint32 results_per_page() const;\n  inline void set_results_per_page(::google::protobuf::uint32 value);\n\n  // @@protoc_insertion_point(class_scope:libbitcoin.protocol.block_headers_request)\nprivate:\n  inline void set_has_start();\n  inline void clear_has_start();\n  inline void set_has_results_per_page();\n  inline void clear_has_results_per_page();\n\n  ::google::protobuf::UnknownFieldSet _unknown_fields_;\n\n  ::google::protobuf::uint32 _has_bits_[1];\n  mutable int _cached_size_;\n  ::libbitcoin::protocol::block_id *start_;\n  ::google::protobuf::uint32 results_per_page_;\n  friend void BCP_API protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_AssignDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_ShutdownFile_bitcoin_2fprotocol_2finterface_2eproto();\n\n  void InitAsDefaultInstance();\n  static block_headers_request *default_instance_;\n};\n// -------------------------------------------------------------------\n\nclass BCP_API transactions_request : public ::google::protobuf::Message\n{\npublic:\n  transactions_request();\n  virtual ~transactions_request();\n\n  transactions_request(const transactions_request &from);\n\n  inline transactions_request &operator=(const transactions_request &from)\n  {\n    CopyFrom(from);\n    return *this;\n  }\n\n  inline const ::google::protobuf::UnknownFieldSet &unknown_fields() const\n  {\n    return _unknown_fields_;\n  }\n\n  inline ::google::protobuf::UnknownFieldSet *mutable_unknown_fields()\n  {\n    return &_unknown_fields_;\n  }\n\n  static const ::google::protobuf::Descriptor *descriptor();\n  static const transactions_request &default_instance();\n\n  void Swap(transactions_request *other);\n\n  // implements Message ----------------------------------------------\n\n  transactions_request *New() const;\n  void CopyFrom(const ::google::protobuf::Message &from);\n  void MergeFrom(const ::google::protobuf::Message &from);\n  void CopyFrom(const transactions_request &from);\n  void MergeFrom(const transactions_request &from);\n  void Clear();\n  bool IsInitialized() const;\n\n  int ByteSize() const;\n  bool MergePartialFromCodedStream(\n      ::google::protobuf::io::CodedInputStream *input);\n  void SerializeWithCachedSizes(\n      ::google::protobuf::io::CodedOutputStream *output) const;\n  ::google::protobuf::uint8 *SerializeWithCachedSizesToArray(::google::protobuf::uint8 *output) const;\n  int GetCachedSize() const { return _cached_size_; }\n\nprivate:\n  void SharedCtor();\n  void SharedDtor();\n  void SetCachedSize(int size) const;\n\npublic:\n  ::google::protobuf::Metadata GetMetadata() const;\n\n  // nested types ----------------------------------------------------\n\n  // accessors -------------------------------------------------------\n\n  // optional .libbitcoin.protocol.block_id start = 1;\n  inline bool has_start() const;\n  inline void clear_start();\n  static const int kStartFieldNumber = 1;\n  inline const ::libbitcoin::protocol::block_id &start() const;\n  inline ::libbitcoin::protocol::block_id *mutable_start();\n  inline ::libbitcoin::protocol::block_id *release_start();\n  inline void set_allocated_start(::libbitcoin::protocol::block_id *start);\n\n  // optional uint32 results_per_page = 2;\n  inline bool has_results_per_page() const;\n  inline void clear_results_per_page();\n  static const int kResultsPerPageFieldNumber = 2;\n  inline ::google::protobuf::uint32 results_per_page() const;\n  inline void set_results_per_page(::google::protobuf::uint32 value);\n\n  // repeated .libbitcoin.protocol.filter query = 3;\n  inline int query_size() const;\n  inline void clear_query();\n  static const int kQueryFieldNumber = 3;\n  inline const ::libbitcoin::protocol::filter &query(int index) const;\n  inline ::libbitcoin::protocol::filter *mutable_query(int index);\n  inline ::libbitcoin::protocol::filter *add_query();\n  inline const ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::filter> &\n  query() const;\n  inline ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::filter> *\n  mutable_query();\n\n  // optional .libbitcoin.protocol.tx_results result_type = 4 [default = TX_HASH];\n  inline bool has_result_type() const;\n  inline void clear_result_type();\n  static const int kResultTypeFieldNumber = 4;\n  inline ::libbitcoin::protocol::tx_results result_type() const;\n  inline void set_result_type(::libbitcoin::protocol::tx_results value);\n\n  // optional .libbitcoin.protocol.locations location_type = 5 [default = NONE];\n  inline bool has_location_type() const;\n  inline void clear_location_type();\n  static const int kLocationTypeFieldNumber = 5;\n  inline ::libbitcoin::protocol::locations location_type() const;\n  inline void set_location_type(::libbitcoin::protocol::locations value);\n\n  // @@protoc_insertion_point(class_scope:libbitcoin.protocol.transactions_request)\nprivate:\n  inline void set_has_start();\n  inline void clear_has_start();\n  inline void set_has_results_per_page();\n  inline void clear_has_results_per_page();\n  inline void set_has_result_type();\n  inline void clear_has_result_type();\n  inline void set_has_location_type();\n  inline void clear_has_location_type();\n\n  ::google::protobuf::UnknownFieldSet _unknown_fields_;\n\n  ::google::protobuf::uint32 _has_bits_[1];\n  mutable int _cached_size_;\n  ::libbitcoin::protocol::block_id *start_;\n  ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::filter> query_;\n  ::google::protobuf::uint32 results_per_page_;\n  int result_type_;\n  int location_type_;\n  friend void BCP_API protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_AssignDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_ShutdownFile_bitcoin_2fprotocol_2finterface_2eproto();\n\n  void InitAsDefaultInstance();\n  static transactions_request *default_instance_;\n};\n// -------------------------------------------------------------------\n\nclass BCP_API request : public ::google::protobuf::Message\n{\npublic:\n  request();\n  virtual ~request();\n\n  request(const request &from);\n\n  inline request &operator=(const request &from)\n  {\n    CopyFrom(from);\n    return *this;\n  }\n\n  inline const ::google::protobuf::UnknownFieldSet &unknown_fields() const\n  {\n    return _unknown_fields_;\n  }\n\n  inline ::google::protobuf::UnknownFieldSet *mutable_unknown_fields()\n  {\n    return &_unknown_fields_;\n  }\n\n  static const ::google::protobuf::Descriptor *descriptor();\n  static const request &default_instance();\n\n  enum RequestTypeCase\n  {\n    kGetBlockHeaders = 2,\n    kGetTransactions = 3,\n    kPostTransaction = 4,\n    kValidateTransaction = 5,\n    kPostBlock = 6,\n    kValidateBlock = 7,\n    REQUEST_TYPE_NOT_SET = 0,\n  };\n\n  void Swap(request *other);\n\n  // implements Message ----------------------------------------------\n\n  request *New() const;\n  void CopyFrom(const ::google::protobuf::Message &from);\n  void MergeFrom(const ::google::protobuf::Message &from);\n  void CopyFrom(const request &from);\n  void MergeFrom(const request &from);\n  void Clear();\n  bool IsInitialized() const;\n\n  int ByteSize() const;\n  bool MergePartialFromCodedStream(\n      ::google::protobuf::io::CodedInputStream *input);\n  void SerializeWithCachedSizes(\n      ::google::protobuf::io::CodedOutputStream *output) const;\n  ::google::protobuf::uint8 *SerializeWithCachedSizesToArray(::google::protobuf::uint8 *output) const;\n  int GetCachedSize() const { return _cached_size_; }\n\nprivate:\n  void SharedCtor();\n  void SharedDtor();\n  void SetCachedSize(int size) const;\n\npublic:\n  ::google::protobuf::Metadata GetMetadata() const;\n\n  // nested types ----------------------------------------------------\n\n  // accessors -------------------------------------------------------\n\n  // required uint32 id = 1;\n  inline bool has_id() const;\n  inline void clear_id();\n  static const int kIdFieldNumber = 1;\n  inline ::google::protobuf::uint32 id() const;\n  inline void set_id(::google::protobuf::uint32 value);\n\n  // optional .libbitcoin.protocol.block_headers_request get_block_headers = 2;\n  inline bool has_get_block_headers() const;\n  inline void clear_get_block_headers();\n  static const int kGetBlockHeadersFieldNumber = 2;\n  inline const ::libbitcoin::protocol::block_headers_request &get_block_headers() const;\n  inline ::libbitcoin::protocol::block_headers_request *mutable_get_block_headers();\n  inline ::libbitcoin::protocol::block_headers_request *release_get_block_headers();\n  inline void set_allocated_get_block_headers(::libbitcoin::protocol::block_headers_request *get_block_headers);\n\n  // optional .libbitcoin.protocol.transactions_request get_transactions = 3;\n  inline bool has_get_transactions() const;\n  inline void clear_get_transactions();\n  static const int kGetTransactionsFieldNumber = 3;\n  inline const ::libbitcoin::protocol::transactions_request &get_transactions() const;\n  inline ::libbitcoin::protocol::transactions_request *mutable_get_transactions();\n  inline ::libbitcoin::protocol::transactions_request *release_get_transactions();\n  inline void set_allocated_get_transactions(::libbitcoin::protocol::transactions_request *get_transactions);\n\n  // optional .libbitcoin.protocol.tx post_transaction = 4;\n  inline bool has_post_transaction() const;\n  inline void clear_post_transaction();\n  static const int kPostTransactionFieldNumber = 4;\n  inline const ::libbitcoin::protocol::tx &post_transaction() const;\n  inline ::libbitcoin::protocol::tx *mutable_post_transaction();\n  inline ::libbitcoin::protocol::tx *release_post_transaction();\n  inline void set_allocated_post_transaction(::libbitcoin::protocol::tx *post_transaction);\n\n  // optional .libbitcoin.protocol.tx validate_tx_engine = 5;\n  inline bool has_validate_tx_engine() const;\n  inline void clear_validate_tx_engine();\n  static const int kValidateTransactionFieldNumber = 5;\n  inline const ::libbitcoin::protocol::tx &validate_tx_engine() const;\n  inline ::libbitcoin::protocol::tx *mutable_validate_tx_engine();\n  inline ::libbitcoin::protocol::tx *release_validate_tx_engine();\n  inline void set_allocated_validate_tx_engine(::libbitcoin::protocol::tx *validate_tx_engine);\n\n  // optional .libbitcoin.protocol.block post_block = 6;\n  inline bool has_post_block() const;\n  inline void clear_post_block();\n  static const int kPostBlockFieldNumber = 6;\n  inline const ::libbitcoin::protocol::block &post_block() const;\n  inline ::libbitcoin::protocol::block *mutable_post_block();\n  inline ::libbitcoin::protocol::block *release_post_block();\n  inline void set_allocated_post_block(::libbitcoin::protocol::block *post_block);\n\n  // optional .libbitcoin.protocol.block validate_block = 7;\n  inline bool has_validate_block() const;\n  inline void clear_validate_block();\n  static const int kValidateBlockFieldNumber = 7;\n  inline const ::libbitcoin::protocol::block &validate_block() const;\n  inline ::libbitcoin::protocol::block *mutable_validate_block();\n  inline ::libbitcoin::protocol::block *release_validate_block();\n  inline void set_allocated_validate_block(::libbitcoin::protocol::block *validate_block);\n\n  GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(request)\n  inline RequestTypeCase request_type_case() const;\n  // @@protoc_insertion_point(class_scope:libbitcoin.protocol.request)\nprivate:\n  inline void set_has_id();\n  inline void clear_has_id();\n  inline void set_has_get_block_headers();\n  inline void set_has_get_transactions();\n  inline void set_has_post_transaction();\n  inline void set_has_validate_tx_engine();\n  inline void set_has_post_block();\n  inline void set_has_validate_block();\n\n  inline bool has_request_type();\n  void clear_request_type();\n  inline void clear_has_request_type();\n\n  ::google::protobuf::internal::ExtensionSet _extensions_;\n\n  ::google::protobuf::UnknownFieldSet _unknown_fields_;\n\n  ::google::protobuf::uint32 _has_bits_[1];\n  mutable int _cached_size_;\n  ::google::protobuf::uint32 id_;\n  union RequestTypeUnion {\n    ::libbitcoin::protocol::block_headers_request *get_block_headers_;\n    ::libbitcoin::protocol::transactions_request *get_transactions_;\n    ::libbitcoin::protocol::tx *post_transaction_;\n    ::libbitcoin::protocol::tx *validate_tx_engine_;\n    ::libbitcoin::protocol::block *post_block_;\n    ::libbitcoin::protocol::block *validate_block_;\n  } request_type_;\n  ::google::protobuf::uint32 _oneof_case_[1];\n\n  friend void BCP_API protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_AssignDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_ShutdownFile_bitcoin_2fprotocol_2finterface_2eproto();\n\n  void InitAsDefaultInstance();\n  static request *default_instance_;\n};\n// -------------------------------------------------------------------\n\nclass BCP_API response_block_headers : public ::google::protobuf::Message\n{\npublic:\n  response_block_headers();\n  virtual ~response_block_headers();\n\n  response_block_headers(const response_block_headers &from);\n\n  inline response_block_headers &operator=(const response_block_headers &from)\n  {\n    CopyFrom(from);\n    return *this;\n  }\n\n  inline const ::google::protobuf::UnknownFieldSet &unknown_fields() const\n  {\n    return _unknown_fields_;\n  }\n\n  inline ::google::protobuf::UnknownFieldSet *mutable_unknown_fields()\n  {\n    return &_unknown_fields_;\n  }\n\n  static const ::google::protobuf::Descriptor *descriptor();\n  static const response_block_headers &default_instance();\n\n  void Swap(response_block_headers *other);\n\n  // implements Message ----------------------------------------------\n\n  response_block_headers *New() const;\n  void CopyFrom(const ::google::protobuf::Message &from);\n  void MergeFrom(const ::google::protobuf::Message &from);\n  void CopyFrom(const response_block_headers &from);\n  void MergeFrom(const response_block_headers &from);\n  void Clear();\n  bool IsInitialized() const;\n\n  int ByteSize() const;\n  bool MergePartialFromCodedStream(\n      ::google::protobuf::io::CodedInputStream *input);\n  void SerializeWithCachedSizes(\n      ::google::protobuf::io::CodedOutputStream *output) const;\n  ::google::protobuf::uint8 *SerializeWithCachedSizesToArray(::google::protobuf::uint8 *output) const;\n  int GetCachedSize() const { return _cached_size_; }\n\nprivate:\n  void SharedCtor();\n  void SharedDtor();\n  void SetCachedSize(int size) const;\n\npublic:\n  ::google::protobuf::Metadata GetMetadata() const;\n\n  // nested types ----------------------------------------------------\n\n  // accessors -------------------------------------------------------\n\n  // optional .libbitcoin.protocol.block_id next = 1;\n  inline bool has_next() const;\n  inline void clear_next();\n  static const int kNextFieldNumber = 1;\n  inline const ::libbitcoin::protocol::block_id &next() const;\n  inline ::libbitcoin::protocol::block_id *mutable_next();\n  inline ::libbitcoin::protocol::block_id *release_next();\n  inline void set_allocated_next(::libbitcoin::protocol::block_id *next);\n\n  // optional .libbitcoin.protocol.block_id top = 2;\n  inline bool has_top() const;\n  inline void clear_top();\n  static const int kTopFieldNumber = 2;\n  inline const ::libbitcoin::protocol::block_id &top() const;\n  inline ::libbitcoin::protocol::block_id *mutable_top();\n  inline ::libbitcoin::protocol::block_id *release_top();\n  inline void set_allocated_top(::libbitcoin::protocol::block_id *top);\n\n  // repeated .libbitcoin.protocol.block_header headers = 3;\n  inline int headers_size() const;\n  inline void clear_headers();\n  static const int kHeadersFieldNumber = 3;\n  inline const ::libbitcoin::protocol::block_header &headers(int index) const;\n  inline ::libbitcoin::protocol::block_header *mutable_headers(int index);\n  inline ::libbitcoin::protocol::block_header *add_headers();\n  inline const ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::block_header> &\n  headers() const;\n  inline ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::block_header> *\n  mutable_headers();\n\n  // @@protoc_insertion_point(class_scope:libbitcoin.protocol.response.block_headers)\nprivate:\n  inline void set_has_next();\n  inline void clear_has_next();\n  inline void set_has_top();\n  inline void clear_has_top();\n\n  ::google::protobuf::UnknownFieldSet _unknown_fields_;\n\n  ::google::protobuf::uint32 _has_bits_[1];\n  mutable int _cached_size_;\n  ::libbitcoin::protocol::block_id *next_;\n  ::libbitcoin::protocol::block_id *top_;\n  ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::block_header> headers_;\n  friend void BCP_API protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_AssignDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_ShutdownFile_bitcoin_2fprotocol_2finterface_2eproto();\n\n  void InitAsDefaultInstance();\n  static response_block_headers *default_instance_;\n};\n// -------------------------------------------------------------------\n\nclass BCP_API response_transactions : public ::google::protobuf::Message\n{\npublic:\n  response_transactions();\n  virtual ~response_transactions();\n\n  response_transactions(const response_transactions &from);\n\n  inline response_transactions &operator=(const response_transactions &from)\n  {\n    CopyFrom(from);\n    return *this;\n  }\n\n  inline const ::google::protobuf::UnknownFieldSet &unknown_fields() const\n  {\n    return _unknown_fields_;\n  }\n\n  inline ::google::protobuf::UnknownFieldSet *mutable_unknown_fields()\n  {\n    return &_unknown_fields_;\n  }\n\n  static const ::google::protobuf::Descriptor *descriptor();\n  static const response_transactions &default_instance();\n\n  void Swap(response_transactions *other);\n\n  // implements Message ----------------------------------------------\n\n  response_transactions *New() const;\n  void CopyFrom(const ::google::protobuf::Message &from);\n  void MergeFrom(const ::google::protobuf::Message &from);\n  void CopyFrom(const response_transactions &from);\n  void MergeFrom(const response_transactions &from);\n  void Clear();\n  bool IsInitialized() const;\n\n  int ByteSize() const;\n  bool MergePartialFromCodedStream(\n      ::google::protobuf::io::CodedInputStream *input);\n  void SerializeWithCachedSizes(\n      ::google::protobuf::io::CodedOutputStream *output) const;\n  ::google::protobuf::uint8 *SerializeWithCachedSizesToArray(::google::protobuf::uint8 *output) const;\n  int GetCachedSize() const { return _cached_size_; }\n\nprivate:\n  void SharedCtor();\n  void SharedDtor();\n  void SetCachedSize(int size) const;\n\npublic:\n  ::google::protobuf::Metadata GetMetadata() const;\n\n  // nested types ----------------------------------------------------\n\n  // accessors -------------------------------------------------------\n\n  // optional .libbitcoin.protocol.block_id next = 1;\n  inline bool has_next() const;\n  inline void clear_next();\n  static const int kNextFieldNumber = 1;\n  inline const ::libbitcoin::protocol::block_id &next() const;\n  inline ::libbitcoin::protocol::block_id *mutable_next();\n  inline ::libbitcoin::protocol::block_id *release_next();\n  inline void set_allocated_next(::libbitcoin::protocol::block_id *next);\n\n  // optional .libbitcoin.protocol.block_id top = 2;\n  inline bool has_top() const;\n  inline void clear_top();\n  static const int kTopFieldNumber = 2;\n  inline const ::libbitcoin::protocol::block_id &top() const;\n  inline ::libbitcoin::protocol::block_id *mutable_top();\n  inline ::libbitcoin::protocol::block_id *release_top();\n  inline void set_allocated_top(::libbitcoin::protocol::block_id *top);\n\n  // repeated .libbitcoin.protocol.tx_hash_result hashes = 3;\n  inline int hashes_size() const;\n  inline void clear_hashes();\n  static const int kHashesFieldNumber = 3;\n  inline const ::libbitcoin::protocol::tx_hash_result &hashes(int index) const;\n  inline ::libbitcoin::protocol::tx_hash_result *mutable_hashes(int index);\n  inline ::libbitcoin::protocol::tx_hash_result *add_hashes();\n  inline const ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::tx_hash_result> &\n  hashes() const;\n  inline ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::tx_hash_result> *\n  mutable_hashes();\n\n  // repeated .libbitcoin.protocol.tx_result transactions = 4;\n  inline int transactions_size() const;\n  inline void clear_transactions();\n  static const int kTransactionsFieldNumber = 4;\n  inline const ::libbitcoin::protocol::tx_result &transactions(int index) const;\n  inline ::libbitcoin::protocol::tx_result *mutable_transactions(int index);\n  inline ::libbitcoin::protocol::tx_result *add_transactions();\n  inline const ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::tx_result> &\n  transactions() const;\n  inline ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::tx_result> *\n  mutable_transactions();\n\n  // repeated .libbitcoin.protocol.utxo_result utxos = 5;\n  inline int utxos_size() const;\n  inline void clear_utxos();\n  static const int kUtxosFieldNumber = 5;\n  inline const ::libbitcoin::protocol::utxo_result &utxos(int index) const;\n  inline ::libbitcoin::protocol::utxo_result *mutable_utxos(int index);\n  inline ::libbitcoin::protocol::utxo_result *add_utxos();\n  inline const ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::utxo_result> &\n  utxos() const;\n  inline ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::utxo_result> *\n  mutable_utxos();\n\n  // @@protoc_insertion_point(class_scope:libbitcoin.protocol.response.transactions)\nprivate:\n  inline void set_has_next();\n  inline void clear_has_next();\n  inline void set_has_top();\n  inline void clear_has_top();\n\n  ::google::protobuf::UnknownFieldSet _unknown_fields_;\n\n  ::google::protobuf::uint32 _has_bits_[1];\n  mutable int _cached_size_;\n  ::libbitcoin::protocol::block_id *next_;\n  ::libbitcoin::protocol::block_id *top_;\n  ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::tx_hash_result> hashes_;\n  ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::tx_result> transactions_;\n  ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::utxo_result> utxos_;\n  friend void BCP_API protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_AssignDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_ShutdownFile_bitcoin_2fprotocol_2finterface_2eproto();\n\n  void InitAsDefaultInstance();\n  static response_transactions *default_instance_;\n};\n// -------------------------------------------------------------------\n\nclass BCP_API response : public ::google::protobuf::Message\n{\npublic:\n  response();\n  virtual ~response();\n\n  response(const response &from);\n\n  inline response &operator=(const response &from)\n  {\n    CopyFrom(from);\n    return *this;\n  }\n\n  inline const ::google::protobuf::UnknownFieldSet &unknown_fields() const\n  {\n    return _unknown_fields_;\n  }\n\n  inline ::google::protobuf::UnknownFieldSet *mutable_unknown_fields()\n  {\n    return &_unknown_fields_;\n  }\n\n  static const ::google::protobuf::Descriptor *descriptor();\n  static const response &default_instance();\n\n  enum ResponseTypeCase\n  {\n    kGetBlockHeadersResponse = 3,\n    kGetTransactionsResponse = 4,\n    kPostTransactionSucceeded = 5,\n    kValidateTransactionSucceeded = 6,\n    kPostBlockSucceeded = 7,\n    kValidateBlockSucceeded = 8,\n    RESPONSE_TYPE_NOT_SET = 0,\n  };\n\n  void Swap(response *other);\n\n  // implements Message ----------------------------------------------\n\n  response *New() const;\n  void CopyFrom(const ::google::protobuf::Message &from);\n  void MergeFrom(const ::google::protobuf::Message &from);\n  void CopyFrom(const response &from);\n  void MergeFrom(const response &from);\n  void Clear();\n  bool IsInitialized() const;\n\n  int ByteSize() const;\n  bool MergePartialFromCodedStream(\n      ::google::protobuf::io::CodedInputStream *input);\n  void SerializeWithCachedSizes(\n      ::google::protobuf::io::CodedOutputStream *output) const;\n  ::google::protobuf::uint8 *SerializeWithCachedSizesToArray(::google::protobuf::uint8 *output) const;\n  int GetCachedSize() const { return _cached_size_; }\n\nprivate:\n  void SharedCtor();\n  void SharedDtor();\n  void SetCachedSize(int size) const;\n\npublic:\n  ::google::protobuf::Metadata GetMetadata() const;\n\n  // nested types ----------------------------------------------------\n\n  typedef response_block_headers block_headers;\n  typedef response_transactions transactions;\n\n  // accessors -------------------------------------------------------\n\n  // required uint32 id = 1;\n  inline bool has_id() const;\n  inline void clear_id();\n  static const int kIdFieldNumber = 1;\n  inline ::google::protobuf::uint32 id() const;\n  inline void set_id(::google::protobuf::uint32 value);\n\n  // optional sint32 status = 2;\n  inline bool has_status() const;\n  inline void clear_status();\n  static const int kStatusFieldNumber = 2;\n  inline ::google::protobuf::int32 status() const;\n  inline void set_status(::google::protobuf::int32 value);\n\n  // optional .libbitcoin.protocol.response.block_headers get_block_headers_response = 3;\n  inline bool has_get_block_headers_response() const;\n  inline void clear_get_block_headers_response();\n  static const int kGetBlockHeadersResponseFieldNumber = 3;\n  inline const ::libbitcoin::protocol::response_block_headers &get_block_headers_response() const;\n  inline ::libbitcoin::protocol::response_block_headers *mutable_get_block_headers_response();\n  inline ::libbitcoin::protocol::response_block_headers *release_get_block_headers_response();\n  inline void set_allocated_get_block_headers_response(::libbitcoin::protocol::response_block_headers *get_block_headers_response);\n\n  // optional .libbitcoin.protocol.response.transactions get_transactions_response = 4;\n  inline bool has_get_transactions_response() const;\n  inline void clear_get_transactions_response();\n  static const int kGetTransactionsResponseFieldNumber = 4;\n  inline const ::libbitcoin::protocol::response_transactions &get_transactions_response() const;\n  inline ::libbitcoin::protocol::response_transactions *mutable_get_transactions_response();\n  inline ::libbitcoin::protocol::response_transactions *release_get_transactions_response();\n  inline void set_allocated_get_transactions_response(::libbitcoin::protocol::response_transactions *get_transactions_response);\n\n  // optional bool post_transaction_succeeded = 5;\n  inline bool has_post_transaction_succeeded() const;\n  inline void clear_post_transaction_succeeded();\n  static const int kPostTransactionSucceededFieldNumber = 5;\n  inline bool post_transaction_succeeded() const;\n  inline void set_post_transaction_succeeded(bool value);\n\n  // optional bool validate_tx_engine_succeeded = 6;\n  inline bool has_validate_tx_engine_succeeded() const;\n  inline void clear_validate_tx_engine_succeeded();\n  static const int kValidateTransactionSucceededFieldNumber = 6;\n  inline bool validate_tx_engine_succeeded() const;\n  inline void set_validate_tx_engine_succeeded(bool value);\n\n  // optional bool post_block_succeeded = 7;\n  inline bool has_post_block_succeeded() const;\n  inline void clear_post_block_succeeded();\n  static const int kPostBlockSucceededFieldNumber = 7;\n  inline bool post_block_succeeded() const;\n  inline void set_post_block_succeeded(bool value);\n\n  // optional bool validate_block_succeeded = 8;\n  inline bool has_validate_block_succeeded() const;\n  inline void clear_validate_block_succeeded();\n  static const int kValidateBlockSucceededFieldNumber = 8;\n  inline bool validate_block_succeeded() const;\n  inline void set_validate_block_succeeded(bool value);\n\n  GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(response)\n  inline ResponseTypeCase response_type_case() const;\n  // @@protoc_insertion_point(class_scope:libbitcoin.protocol.response)\nprivate:\n  inline void set_has_id();\n  inline void clear_has_id();\n  inline void set_has_status();\n  inline void clear_has_status();\n  inline void set_has_get_block_headers_response();\n  inline void set_has_get_transactions_response();\n  inline void set_has_post_transaction_succeeded();\n  inline void set_has_validate_tx_engine_succeeded();\n  inline void set_has_post_block_succeeded();\n  inline void set_has_validate_block_succeeded();\n\n  inline bool has_response_type();\n  void clear_response_type();\n  inline void clear_has_response_type();\n\n  ::google::protobuf::internal::ExtensionSet _extensions_;\n\n  ::google::protobuf::UnknownFieldSet _unknown_fields_;\n\n  ::google::protobuf::uint32 _has_bits_[1];\n  mutable int _cached_size_;\n  ::google::protobuf::uint32 id_;\n  ::google::protobuf::int32 status_;\n  union ResponseTypeUnion {\n    ::libbitcoin::protocol::response_block_headers *get_block_headers_response_;\n    ::libbitcoin::protocol::response_transactions *get_transactions_response_;\n    bool post_transaction_succeeded_;\n    bool validate_tx_engine_succeeded_;\n    bool post_block_succeeded_;\n    bool validate_block_succeeded_;\n  } response_type_;\n  ::google::protobuf::uint32 _oneof_case_[1];\n\n  friend void BCP_API protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_AssignDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  friend void protobuf_ShutdownFile_bitcoin_2fprotocol_2finterface_2eproto();\n\n  void InitAsDefaultInstance();\n  static response *default_instance_;\n};\n// ===================================================================\n\n// ===================================================================\n\n// block_header\n\n// required uint32 version = 1;\ninline bool block_header::has_version() const\n{\n  return (_has_bits_[0] & 0x00000001u) != 0;\n}\ninline void block_header::set_has_version()\n{\n  _has_bits_[0] |= 0x00000001u;\n}\ninline void block_header::clear_has_version()\n{\n  _has_bits_[0] &= ~0x00000001u;\n}\ninline void block_header::clear_version()\n{\n  version_ = 0u;\n  clear_has_version();\n}\ninline ::google::protobuf::uint32 block_header::version() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.block_header.version)\n  return version_;\n}\ninline void block_header::set_version(::google::protobuf::uint32 value)\n{\n  set_has_version();\n  version_ = value;\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.block_header.version)\n}\n\n// required bytes previous_block_hash = 2;\ninline bool block_header::has_previous_block_hash() const\n{\n  return (_has_bits_[0] & 0x00000002u) != 0;\n}\ninline void block_header::set_has_previous_block_hash()\n{\n  _has_bits_[0] |= 0x00000002u;\n}\ninline void block_header::clear_has_previous_block_hash()\n{\n  _has_bits_[0] &= ~0x00000002u;\n}\ninline void block_header::clear_previous_block_hash()\n{\n  if (previous_block_hash_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    previous_block_hash_->clear();\n  }\n  clear_has_previous_block_hash();\n}\ninline const ::std::string &block_header::previous_block_hash() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.block_header.previous_block_hash)\n  return *previous_block_hash_;\n}\ninline void block_header::set_previous_block_hash(const ::std::string &value)\n{\n  set_has_previous_block_hash();\n  if (previous_block_hash_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    previous_block_hash_ = new ::std::string;\n  }\n  previous_block_hash_->assign(value);\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.block_header.previous_block_hash)\n}\ninline void block_header::set_previous_block_hash(const char *value)\n{\n  set_has_previous_block_hash();\n  if (previous_block_hash_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    previous_block_hash_ = new ::std::string;\n  }\n  previous_block_hash_->assign(value);\n  // @@protoc_insertion_point(field_set_char:libbitcoin.protocol.block_header.previous_block_hash)\n}\ninline void block_header::set_previous_block_hash(const void *value, size_t size)\n{\n  set_has_previous_block_hash();\n  if (previous_block_hash_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    previous_block_hash_ = new ::std::string;\n  }\n  previous_block_hash_->assign(reinterpret_cast<const char *>(value), size);\n  // @@protoc_insertion_point(field_set_pointer:libbitcoin.protocol.block_header.previous_block_hash)\n}\ninline ::std::string *block_header::mutable_previous_block_hash()\n{\n  set_has_previous_block_hash();\n  if (previous_block_hash_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    previous_block_hash_ = new ::std::string;\n  }\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.block_header.previous_block_hash)\n  return previous_block_hash_;\n}\ninline ::std::string *block_header::release_previous_block_hash()\n{\n  clear_has_previous_block_hash();\n  if (previous_block_hash_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    return NULL;\n  }\n  else\n  {\n    ::std::string *temp = previous_block_hash_;\n    previous_block_hash_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n    return temp;\n  }\n}\ninline void block_header::set_allocated_previous_block_hash(::std::string *previous_block_hash)\n{\n  if (previous_block_hash_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    delete previous_block_hash_;\n  }\n  if (previous_block_hash)\n  {\n    set_has_previous_block_hash();\n    previous_block_hash_ = previous_block_hash;\n  }\n  else\n  {\n    clear_has_previous_block_hash();\n    previous_block_hash_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n  }\n  // @@protoc_insertion_point(field_set_allocated:libbitcoin.protocol.block_header.previous_block_hash)\n}\n\n// required bytes merkle_root = 3;\ninline bool block_header::has_merkle_root() const\n{\n  return (_has_bits_[0] & 0x00000004u) != 0;\n}\ninline void block_header::set_has_merkle_root()\n{\n  _has_bits_[0] |= 0x00000004u;\n}\ninline void block_header::clear_has_merkle_root()\n{\n  _has_bits_[0] &= ~0x00000004u;\n}\ninline void block_header::clear_merkle_root()\n{\n  if (merkle_root_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    merkle_root_->clear();\n  }\n  clear_has_merkle_root();\n}\ninline const ::std::string &block_header::merkle_root() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.block_header.merkle_root)\n  return *merkle_root_;\n}\ninline void block_header::set_merkle_root(const ::std::string &value)\n{\n  set_has_merkle_root();\n  if (merkle_root_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    merkle_root_ = new ::std::string;\n  }\n  merkle_root_->assign(value);\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.block_header.merkle_root)\n}\ninline void block_header::set_merkle_root(const char *value)\n{\n  set_has_merkle_root();\n  if (merkle_root_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    merkle_root_ = new ::std::string;\n  }\n  merkle_root_->assign(value);\n  // @@protoc_insertion_point(field_set_char:libbitcoin.protocol.block_header.merkle_root)\n}\ninline void block_header::set_merkle_root(const void *value, size_t size)\n{\n  set_has_merkle_root();\n  if (merkle_root_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    merkle_root_ = new ::std::string;\n  }\n  merkle_root_->assign(reinterpret_cast<const char *>(value), size);\n  // @@protoc_insertion_point(field_set_pointer:libbitcoin.protocol.block_header.merkle_root)\n}\ninline ::std::string *block_header::mutable_merkle_root()\n{\n  set_has_merkle_root();\n  if (merkle_root_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    merkle_root_ = new ::std::string;\n  }\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.block_header.merkle_root)\n  return merkle_root_;\n}\ninline ::std::string *block_header::release_merkle_root()\n{\n  clear_has_merkle_root();\n  if (merkle_root_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    return NULL;\n  }\n  else\n  {\n    ::std::string *temp = merkle_root_;\n    merkle_root_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n    return temp;\n  }\n}\ninline void block_header::set_allocated_merkle_root(::std::string *merkle_root)\n{\n  if (merkle_root_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    delete merkle_root_;\n  }\n  if (merkle_root)\n  {\n    set_has_merkle_root();\n    merkle_root_ = merkle_root;\n  }\n  else\n  {\n    clear_has_merkle_root();\n    merkle_root_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n  }\n  // @@protoc_insertion_point(field_set_allocated:libbitcoin.protocol.block_header.merkle_root)\n}\n\n// required uint32 timestamp = 4;\ninline bool block_header::has_timestamp() const\n{\n  return (_has_bits_[0] & 0x00000008u) != 0;\n}\ninline void block_header::set_has_timestamp()\n{\n  _has_bits_[0] |= 0x00000008u;\n}\ninline void block_header::clear_has_timestamp()\n{\n  _has_bits_[0] &= ~0x00000008u;\n}\ninline void block_header::clear_timestamp()\n{\n  timestamp_ = 0u;\n  clear_has_timestamp();\n}\ninline ::google::protobuf::uint32 block_header::timestamp() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.block_header.timestamp)\n  return timestamp_;\n}\ninline void block_header::set_timestamp(::google::protobuf::uint32 value)\n{\n  set_has_timestamp();\n  timestamp_ = value;\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.block_header.timestamp)\n}\n\n// required uint32 bits = 5;\ninline bool block_header::has_bits() const\n{\n  return (_has_bits_[0] & 0x00000010u) != 0;\n}\ninline void block_header::set_has_bits()\n{\n  _has_bits_[0] |= 0x00000010u;\n}\ninline void block_header::clear_has_bits()\n{\n  _has_bits_[0] &= ~0x00000010u;\n}\ninline void block_header::clear_bits()\n{\n  bits_ = 0u;\n  clear_has_bits();\n}\ninline ::google::protobuf::uint32 block_header::bits() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.block_header.bits)\n  return bits_;\n}\ninline void block_header::set_bits(::google::protobuf::uint32 value)\n{\n  set_has_bits();\n  bits_ = value;\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.block_header.bits)\n}\n\n// required uint32 nonce = 6;\ninline bool block_header::has_nonce() const\n{\n  return (_has_bits_[0] & 0x00000020u) != 0;\n}\ninline void block_header::set_has_nonce()\n{\n  _has_bits_[0] |= 0x00000020u;\n}\ninline void block_header::clear_has_nonce()\n{\n  _has_bits_[0] &= ~0x00000020u;\n}\ninline void block_header::clear_nonce()\n{\n  nonce_ = 0u;\n  clear_has_nonce();\n}\ninline ::google::protobuf::uint32 block_header::nonce() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.block_header.nonce)\n  return nonce_;\n}\ninline void block_header::set_nonce(::google::protobuf::uint32 value)\n{\n  set_has_nonce();\n  nonce_ = value;\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.block_header.nonce)\n}\n\n// required uint64 tx_count = 7;\ninline bool block_header::has_tx_count() const\n{\n  return (_has_bits_[0] & 0x00000040u) != 0;\n}\ninline void block_header::set_has_tx_count()\n{\n  _has_bits_[0] |= 0x00000040u;\n}\ninline void block_header::clear_has_tx_count()\n{\n  _has_bits_[0] &= ~0x00000040u;\n}\ninline void block_header::clear_tx_count()\n{\n  tx_count_ = GOOGLE_ULONGLONG(0);\n  clear_has_tx_count();\n}\ninline ::google::protobuf::uint64 block_header::tx_count() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.block_header.tx_count)\n  return tx_count_;\n}\ninline void block_header::set_tx_count(::google::protobuf::uint64 value)\n{\n  set_has_tx_count();\n  tx_count_ = value;\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.block_header.tx_count)\n}\n\n// -------------------------------------------------------------------\n\n// point\n\n// required bytes hash = 1;\ninline bool point::has_hash() const\n{\n  return (_has_bits_[0] & 0x00000001u) != 0;\n}\ninline void point::set_has_hash()\n{\n  _has_bits_[0] |= 0x00000001u;\n}\ninline void point::clear_has_hash()\n{\n  _has_bits_[0] &= ~0x00000001u;\n}\ninline void point::clear_hash()\n{\n  if (hash_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    hash_->clear();\n  }\n  clear_has_hash();\n}\ninline const ::std::string &point::hash() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.point.hash)\n  return *hash_;\n}\ninline void point::set_hash(const ::std::string &value)\n{\n  set_has_hash();\n  if (hash_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    hash_ = new ::std::string;\n  }\n  hash_->assign(value);\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.point.hash)\n}\ninline void point::set_hash(const char *value)\n{\n  set_has_hash();\n  if (hash_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    hash_ = new ::std::string;\n  }\n  hash_->assign(value);\n  // @@protoc_insertion_point(field_set_char:libbitcoin.protocol.point.hash)\n}\ninline void point::set_hash(const void *value, size_t size)\n{\n  set_has_hash();\n  if (hash_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    hash_ = new ::std::string;\n  }\n  hash_->assign(reinterpret_cast<const char *>(value), size);\n  // @@protoc_insertion_point(field_set_pointer:libbitcoin.protocol.point.hash)\n}\ninline ::std::string *point::mutable_hash()\n{\n  set_has_hash();\n  if (hash_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    hash_ = new ::std::string;\n  }\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.point.hash)\n  return hash_;\n}\ninline ::std::string *point::release_hash()\n{\n  clear_has_hash();\n  if (hash_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    return NULL;\n  }\n  else\n  {\n    ::std::string *temp = hash_;\n    hash_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n    return temp;\n  }\n}\ninline void point::set_allocated_hash(::std::string *hash)\n{\n  if (hash_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    delete hash_;\n  }\n  if (hash)\n  {\n    set_has_hash();\n    hash_ = hash;\n  }\n  else\n  {\n    clear_has_hash();\n    hash_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n  }\n  // @@protoc_insertion_point(field_set_allocated:libbitcoin.protocol.point.hash)\n}\n\n// required uint32 index = 2;\ninline bool point::has_index() const\n{\n  return (_has_bits_[0] & 0x00000002u) != 0;\n}\ninline void point::set_has_index()\n{\n  _has_bits_[0] |= 0x00000002u;\n}\ninline void point::clear_has_index()\n{\n  _has_bits_[0] &= ~0x00000002u;\n}\ninline void point::clear_index()\n{\n  index_ = 0u;\n  clear_has_index();\n}\ninline ::google::protobuf::uint32 point::index() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.point.index)\n  return index_;\n}\ninline void point::set_index(::google::protobuf::uint32 value)\n{\n  set_has_index();\n  index_ = value;\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.point.index)\n}\n\n// -------------------------------------------------------------------\n\n// tx_input\n\n// required .libbitcoin.protocol.point previous_output = 1;\ninline bool tx_input::has_previous_output() const\n{\n  return (_has_bits_[0] & 0x00000001u) != 0;\n}\ninline void tx_input::set_has_previous_output()\n{\n  _has_bits_[0] |= 0x00000001u;\n}\ninline void tx_input::clear_has_previous_output()\n{\n  _has_bits_[0] &= ~0x00000001u;\n}\ninline void tx_input::clear_previous_output()\n{\n  if (previous_output_ != NULL)\n    previous_output_->::libbitcoin::protocol::point::Clear();\n  clear_has_previous_output();\n}\ninline const ::libbitcoin::protocol::point &tx_input::previous_output() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.tx_input.previous_output)\n  return previous_output_ != NULL ? *previous_output_ : *default_instance_->previous_output_;\n}\ninline ::libbitcoin::protocol::point *tx_input::mutable_previous_output()\n{\n  set_has_previous_output();\n  if (previous_output_ == NULL)\n    previous_output_ = new ::libbitcoin::protocol::point;\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.tx_input.previous_output)\n  return previous_output_;\n}\ninline ::libbitcoin::protocol::point *tx_input::release_previous_output()\n{\n  clear_has_previous_output();\n  ::libbitcoin::protocol::point *temp = previous_output_;\n  previous_output_ = NULL;\n  return temp;\n}\ninline void tx_input::set_allocated_previous_output(::libbitcoin::protocol::point *previous_output)\n{\n  delete previous_output_;\n  previous_output_ = previous_output;\n  if (previous_output)\n  {\n    set_has_previous_output();\n  }\n  else\n  {\n    clear_has_previous_output();\n  }\n  // @@protoc_insertion_point(field_set_allocated:libbitcoin.protocol.tx_input.previous_output)\n}\n\n// required bytes script = 2;\ninline bool tx_input::has_script() const\n{\n  return (_has_bits_[0] & 0x00000002u) != 0;\n}\ninline void tx_input::set_has_script()\n{\n  _has_bits_[0] |= 0x00000002u;\n}\ninline void tx_input::clear_has_script()\n{\n  _has_bits_[0] &= ~0x00000002u;\n}\ninline void tx_input::clear_script()\n{\n  if (script_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    script_->clear();\n  }\n  clear_has_script();\n}\ninline const ::std::string &tx_input::script() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.tx_input.script)\n  return *script_;\n}\ninline void tx_input::set_script(const ::std::string &value)\n{\n  set_has_script();\n  if (script_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    script_ = new ::std::string;\n  }\n  script_->assign(value);\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.tx_input.script)\n}\ninline void tx_input::set_script(const char *value)\n{\n  set_has_script();\n  if (script_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    script_ = new ::std::string;\n  }\n  script_->assign(value);\n  // @@protoc_insertion_point(field_set_char:libbitcoin.protocol.tx_input.script)\n}\ninline void tx_input::set_script(const void *value, size_t size)\n{\n  set_has_script();\n  if (script_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    script_ = new ::std::string;\n  }\n  script_->assign(reinterpret_cast<const char *>(value), size);\n  // @@protoc_insertion_point(field_set_pointer:libbitcoin.protocol.tx_input.script)\n}\ninline ::std::string *tx_input::mutable_script()\n{\n  set_has_script();\n  if (script_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    script_ = new ::std::string;\n  }\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.tx_input.script)\n  return script_;\n}\ninline ::std::string *tx_input::release_script()\n{\n  clear_has_script();\n  if (script_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    return NULL;\n  }\n  else\n  {\n    ::std::string *temp = script_;\n    script_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n    return temp;\n  }\n}\ninline void tx_input::set_allocated_script(::std::string *script)\n{\n  if (script_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    delete script_;\n  }\n  if (script)\n  {\n    set_has_script();\n    script_ = script;\n  }\n  else\n  {\n    clear_has_script();\n    script_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n  }\n  // @@protoc_insertion_point(field_set_allocated:libbitcoin.protocol.tx_input.script)\n}\n\n// required uint32 sequence = 3;\ninline bool tx_input::has_sequence() const\n{\n  return (_has_bits_[0] & 0x00000004u) != 0;\n}\ninline void tx_input::set_has_sequence()\n{\n  _has_bits_[0] |= 0x00000004u;\n}\ninline void tx_input::clear_has_sequence()\n{\n  _has_bits_[0] &= ~0x00000004u;\n}\ninline void tx_input::clear_sequence()\n{\n  sequence_ = 0u;\n  clear_has_sequence();\n}\ninline ::google::protobuf::uint32 tx_input::sequence() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.tx_input.sequence)\n  return sequence_;\n}\ninline void tx_input::set_sequence(::google::protobuf::uint32 value)\n{\n  set_has_sequence();\n  sequence_ = value;\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.tx_input.sequence)\n}\n\n// -------------------------------------------------------------------\n\n// tx_output\n\n// required uint64 value = 1;\ninline bool tx_output::has_value() const\n{\n  return (_has_bits_[0] & 0x00000001u) != 0;\n}\ninline void tx_output::set_has_value()\n{\n  _has_bits_[0] |= 0x00000001u;\n}\ninline void tx_output::clear_has_value()\n{\n  _has_bits_[0] &= ~0x00000001u;\n}\ninline void tx_output::clear_value()\n{\n  value_ = GOOGLE_ULONGLONG(0);\n  clear_has_value();\n}\ninline ::google::protobuf::uint64 tx_output::value() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.tx_output.value)\n  return value_;\n}\ninline void tx_output::set_value(::google::protobuf::uint64 value)\n{\n  set_has_value();\n  value_ = value;\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.tx_output.value)\n}\n\n// required bytes script = 2;\ninline bool tx_output::has_script() const\n{\n  return (_has_bits_[0] & 0x00000002u) != 0;\n}\ninline void tx_output::set_has_script()\n{\n  _has_bits_[0] |= 0x00000002u;\n}\ninline void tx_output::clear_has_script()\n{\n  _has_bits_[0] &= ~0x00000002u;\n}\ninline void tx_output::clear_script()\n{\n  if (script_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    script_->clear();\n  }\n  clear_has_script();\n}\ninline const ::std::string &tx_output::script() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.tx_output.script)\n  return *script_;\n}\ninline void tx_output::set_script(const ::std::string &value)\n{\n  set_has_script();\n  if (script_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    script_ = new ::std::string;\n  }\n  script_->assign(value);\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.tx_output.script)\n}\ninline void tx_output::set_script(const char *value)\n{\n  set_has_script();\n  if (script_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    script_ = new ::std::string;\n  }\n  script_->assign(value);\n  // @@protoc_insertion_point(field_set_char:libbitcoin.protocol.tx_output.script)\n}\ninline void tx_output::set_script(const void *value, size_t size)\n{\n  set_has_script();\n  if (script_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    script_ = new ::std::string;\n  }\n  script_->assign(reinterpret_cast<const char *>(value), size);\n  // @@protoc_insertion_point(field_set_pointer:libbitcoin.protocol.tx_output.script)\n}\ninline ::std::string *tx_output::mutable_script()\n{\n  set_has_script();\n  if (script_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    script_ = new ::std::string;\n  }\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.tx_output.script)\n  return script_;\n}\ninline ::std::string *tx_output::release_script()\n{\n  clear_has_script();\n  if (script_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    return NULL;\n  }\n  else\n  {\n    ::std::string *temp = script_;\n    script_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n    return temp;\n  }\n}\ninline void tx_output::set_allocated_script(::std::string *script)\n{\n  if (script_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    delete script_;\n  }\n  if (script)\n  {\n    set_has_script();\n    script_ = script;\n  }\n  else\n  {\n    clear_has_script();\n    script_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n  }\n  // @@protoc_insertion_point(field_set_allocated:libbitcoin.protocol.tx_output.script)\n}\n\n// -------------------------------------------------------------------\n\n// tx\n\n// required uint32 version = 1;\ninline bool tx::has_version() const\n{\n  return (_has_bits_[0] & 0x00000001u) != 0;\n}\ninline void tx::set_has_version()\n{\n  _has_bits_[0] |= 0x00000001u;\n}\ninline void tx::clear_has_version()\n{\n  _has_bits_[0] &= ~0x00000001u;\n}\ninline void tx::clear_version()\n{\n  version_ = 0u;\n  clear_has_version();\n}\ninline ::google::protobuf::uint32 tx::version() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.tx.version)\n  return version_;\n}\ninline void tx::set_version(::google::protobuf::uint32 value)\n{\n  set_has_version();\n  version_ = value;\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.tx.version)\n}\n\n// required uint32 locktime = 2;\ninline bool tx::has_locktime() const\n{\n  return (_has_bits_[0] & 0x00000002u) != 0;\n}\ninline void tx::set_has_locktime()\n{\n  _has_bits_[0] |= 0x00000002u;\n}\ninline void tx::clear_has_locktime()\n{\n  _has_bits_[0] &= ~0x00000002u;\n}\ninline void tx::clear_locktime()\n{\n  locktime_ = 0u;\n  clear_has_locktime();\n}\ninline ::google::protobuf::uint32 tx::locktime() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.tx.locktime)\n  return locktime_;\n}\ninline void tx::set_locktime(::google::protobuf::uint32 value)\n{\n  set_has_locktime();\n  locktime_ = value;\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.tx.locktime)\n}\n\n// repeated .libbitcoin.protocol.tx_input inputs = 3;\ninline int tx::inputs_size() const\n{\n  return inputs_.size();\n}\ninline void tx::clear_inputs()\n{\n  inputs_.Clear();\n}\ninline const ::libbitcoin::protocol::tx_input &tx::inputs(int index) const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.tx.inputs)\n  return inputs_.Get(index);\n}\ninline ::libbitcoin::protocol::tx_input *tx::mutable_inputs(int index)\n{\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.tx.inputs)\n  return inputs_.Mutable(index);\n}\ninline ::libbitcoin::protocol::tx_input *tx::add_inputs()\n{\n  // @@protoc_insertion_point(field_add:libbitcoin.protocol.tx.inputs)\n  return inputs_.Add();\n}\ninline const ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::tx_input> &\ntx::inputs() const\n{\n  // @@protoc_insertion_point(field_list:libbitcoin.protocol.tx.inputs)\n  return inputs_;\n}\ninline ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::tx_input> *\ntx::mutable_inputs()\n{\n  // @@protoc_insertion_point(field_mutable_list:libbitcoin.protocol.tx.inputs)\n  return &inputs_;\n}\n\n// repeated .libbitcoin.protocol.tx_output outputs = 4;\ninline int tx::outputs_size() const\n{\n  return outputs_.size();\n}\ninline void tx::clear_outputs()\n{\n  outputs_.Clear();\n}\ninline const ::libbitcoin::protocol::tx_output &tx::outputs(int index) const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.tx.outputs)\n  return outputs_.Get(index);\n}\ninline ::libbitcoin::protocol::tx_output *tx::mutable_outputs(int index)\n{\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.tx.outputs)\n  return outputs_.Mutable(index);\n}\ninline ::libbitcoin::protocol::tx_output *tx::add_outputs()\n{\n  // @@protoc_insertion_point(field_add:libbitcoin.protocol.tx.outputs)\n  return outputs_.Add();\n}\ninline const ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::tx_output> &\ntx::outputs() const\n{\n  // @@protoc_insertion_point(field_list:libbitcoin.protocol.tx.outputs)\n  return outputs_;\n}\ninline ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::tx_output> *\ntx::mutable_outputs()\n{\n  // @@protoc_insertion_point(field_mutable_list:libbitcoin.protocol.tx.outputs)\n  return &outputs_;\n}\n\n// -------------------------------------------------------------------\n\n// block\n\n// required .libbitcoin.protocol.block_header header = 1;\ninline bool block::has_header() const\n{\n  return (_has_bits_[0] & 0x00000001u) != 0;\n}\ninline void block::set_has_header()\n{\n  _has_bits_[0] |= 0x00000001u;\n}\ninline void block::clear_has_header()\n{\n  _has_bits_[0] &= ~0x00000001u;\n}\ninline void block::clear_header()\n{\n  if (header_ != NULL)\n    header_->::libbitcoin::protocol::block_header::Clear();\n  clear_has_header();\n}\ninline const ::libbitcoin::protocol::block_header &block::header() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.block.header)\n  return header_ != NULL ? *header_ : *default_instance_->header_;\n}\ninline ::libbitcoin::protocol::block_header *block::mutable_header()\n{\n  set_has_header();\n  if (header_ == NULL)\n    header_ = new ::libbitcoin::protocol::block_header;\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.block.header)\n  return header_;\n}\ninline ::libbitcoin::protocol::block_header *block::release_header()\n{\n  clear_has_header();\n  ::libbitcoin::protocol::block_header *temp = header_;\n  header_ = NULL;\n  return temp;\n}\ninline void block::set_allocated_header(::libbitcoin::protocol::block_header *header)\n{\n  delete header_;\n  header_ = header;\n  if (header)\n  {\n    set_has_header();\n  }\n  else\n  {\n    clear_has_header();\n  }\n  // @@protoc_insertion_point(field_set_allocated:libbitcoin.protocol.block.header)\n}\n\n// repeated .libbitcoin.protocol.tx transactions = 2;\ninline int block::transactions_size() const\n{\n  return transactions_.size();\n}\ninline void block::clear_transactions()\n{\n  transactions_.Clear();\n}\ninline const ::libbitcoin::protocol::tx &block::transactions(int index) const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.block.transactions)\n  return transactions_.Get(index);\n}\ninline ::libbitcoin::protocol::tx *block::mutable_transactions(int index)\n{\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.block.transactions)\n  return transactions_.Mutable(index);\n}\ninline ::libbitcoin::protocol::tx *block::add_transactions()\n{\n  // @@protoc_insertion_point(field_add:libbitcoin.protocol.block.transactions)\n  return transactions_.Add();\n}\ninline const ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::tx> &\nblock::transactions() const\n{\n  // @@protoc_insertion_point(field_list:libbitcoin.protocol.block.transactions)\n  return transactions_;\n}\ninline ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::tx> *\nblock::mutable_transactions()\n{\n  // @@protoc_insertion_point(field_mutable_list:libbitcoin.protocol.block.transactions)\n  return &transactions_;\n}\n\n// repeated bytes tree = 3;\ninline int block::tree_size() const\n{\n  return tree_.size();\n}\ninline void block::clear_tree()\n{\n  tree_.Clear();\n}\ninline const ::std::string &block::tree(int index) const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.block.tree)\n  return tree_.Get(index);\n}\ninline ::std::string *block::mutable_tree(int index)\n{\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.block.tree)\n  return tree_.Mutable(index);\n}\ninline void block::set_tree(int index, const ::std::string &value)\n{\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.block.tree)\n  tree_.Mutable(index)->assign(value);\n}\ninline void block::set_tree(int index, const char *value)\n{\n  tree_.Mutable(index)->assign(value);\n  // @@protoc_insertion_point(field_set_char:libbitcoin.protocol.block.tree)\n}\ninline void block::set_tree(int index, const void *value, size_t size)\n{\n  tree_.Mutable(index)->assign(\n      reinterpret_cast<const char *>(value), size);\n  // @@protoc_insertion_point(field_set_pointer:libbitcoin.protocol.block.tree)\n}\ninline ::std::string *block::add_tree()\n{\n  return tree_.Add();\n}\ninline void block::add_tree(const ::std::string &value)\n{\n  tree_.Add()->assign(value);\n  // @@protoc_insertion_point(field_add:libbitcoin.protocol.block.tree)\n}\ninline void block::add_tree(const char *value)\n{\n  tree_.Add()->assign(value);\n  // @@protoc_insertion_point(field_add_char:libbitcoin.protocol.block.tree)\n}\ninline void block::add_tree(const void *value, size_t size)\n{\n  tree_.Add()->assign(reinterpret_cast<const char *>(value), size);\n  // @@protoc_insertion_point(field_add_pointer:libbitcoin.protocol.block.tree)\n}\ninline const ::google::protobuf::RepeatedPtrField<::std::string> &\nblock::tree() const\n{\n  // @@protoc_insertion_point(field_list:libbitcoin.protocol.block.tree)\n  return tree_;\n}\ninline ::google::protobuf::RepeatedPtrField<::std::string> *\nblock::mutable_tree()\n{\n  // @@protoc_insertion_point(field_mutable_list:libbitcoin.protocol.block.tree)\n  return &tree_;\n}\n\n// -------------------------------------------------------------------\n\n// filter\n\n// required .libbitcoin.protocol.filters filter_type = 1;\ninline bool filter::has_filter_type() const\n{\n  return (_has_bits_[0] & 0x00000001u) != 0;\n}\ninline void filter::set_has_filter_type()\n{\n  _has_bits_[0] |= 0x00000001u;\n}\ninline void filter::clear_has_filter_type()\n{\n  _has_bits_[0] &= ~0x00000001u;\n}\ninline void filter::clear_filter_type()\n{\n  filter_type_ = 1;\n  clear_has_filter_type();\n}\ninline ::libbitcoin::protocol::filters filter::filter_type() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.filter.filter_type)\n  return static_cast<::libbitcoin::protocol::filters>(filter_type_);\n}\ninline void filter::set_filter_type(::libbitcoin::protocol::filters value)\n{\n  assert(::libbitcoin::protocol::filters_IsValid(value));\n  set_has_filter_type();\n  filter_type_ = value;\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.filter.filter_type)\n}\n\n// optional uint32 bits = 2;\ninline bool filter::has_bits() const\n{\n  return (_has_bits_[0] & 0x00000002u) != 0;\n}\ninline void filter::set_has_bits()\n{\n  _has_bits_[0] |= 0x00000002u;\n}\ninline void filter::clear_has_bits()\n{\n  _has_bits_[0] &= ~0x00000002u;\n}\ninline void filter::clear_bits()\n{\n  bits_ = 0u;\n  clear_has_bits();\n}\ninline ::google::protobuf::uint32 filter::bits() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.filter.bits)\n  return bits_;\n}\ninline void filter::set_bits(::google::protobuf::uint32 value)\n{\n  set_has_bits();\n  bits_ = value;\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.filter.bits)\n}\n\n// required bytes prefix = 3;\ninline bool filter::has_prefix() const\n{\n  return (_has_bits_[0] & 0x00000004u) != 0;\n}\ninline void filter::set_has_prefix()\n{\n  _has_bits_[0] |= 0x00000004u;\n}\ninline void filter::clear_has_prefix()\n{\n  _has_bits_[0] &= ~0x00000004u;\n}\ninline void filter::clear_prefix()\n{\n  if (prefix_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    prefix_->clear();\n  }\n  clear_has_prefix();\n}\ninline const ::std::string &filter::prefix() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.filter.prefix)\n  return *prefix_;\n}\ninline void filter::set_prefix(const ::std::string &value)\n{\n  set_has_prefix();\n  if (prefix_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    prefix_ = new ::std::string;\n  }\n  prefix_->assign(value);\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.filter.prefix)\n}\ninline void filter::set_prefix(const char *value)\n{\n  set_has_prefix();\n  if (prefix_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    prefix_ = new ::std::string;\n  }\n  prefix_->assign(value);\n  // @@protoc_insertion_point(field_set_char:libbitcoin.protocol.filter.prefix)\n}\ninline void filter::set_prefix(const void *value, size_t size)\n{\n  set_has_prefix();\n  if (prefix_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    prefix_ = new ::std::string;\n  }\n  prefix_->assign(reinterpret_cast<const char *>(value), size);\n  // @@protoc_insertion_point(field_set_pointer:libbitcoin.protocol.filter.prefix)\n}\ninline ::std::string *filter::mutable_prefix()\n{\n  set_has_prefix();\n  if (prefix_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    prefix_ = new ::std::string;\n  }\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.filter.prefix)\n  return prefix_;\n}\ninline ::std::string *filter::release_prefix()\n{\n  clear_has_prefix();\n  if (prefix_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    return NULL;\n  }\n  else\n  {\n    ::std::string *temp = prefix_;\n    prefix_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n    return temp;\n  }\n}\ninline void filter::set_allocated_prefix(::std::string *prefix)\n{\n  if (prefix_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    delete prefix_;\n  }\n  if (prefix)\n  {\n    set_has_prefix();\n    prefix_ = prefix;\n  }\n  else\n  {\n    clear_has_prefix();\n    prefix_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n  }\n  // @@protoc_insertion_point(field_set_allocated:libbitcoin.protocol.filter.prefix)\n}\n\n// -------------------------------------------------------------------\n\n// block_id\n\n// optional uint32 height = 1;\ninline bool block_id::has_height() const\n{\n  return (_has_bits_[0] & 0x00000001u) != 0;\n}\ninline void block_id::set_has_height()\n{\n  _has_bits_[0] |= 0x00000001u;\n}\ninline void block_id::clear_has_height()\n{\n  _has_bits_[0] &= ~0x00000001u;\n}\ninline void block_id::clear_height()\n{\n  height_ = 0u;\n  clear_has_height();\n}\ninline ::google::protobuf::uint32 block_id::height() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.block_id.height)\n  return height_;\n}\ninline void block_id::set_height(::google::protobuf::uint32 value)\n{\n  set_has_height();\n  height_ = value;\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.block_id.height)\n}\n\n// optional bytes hash = 2;\ninline bool block_id::has_hash() const\n{\n  return (_has_bits_[0] & 0x00000002u) != 0;\n}\ninline void block_id::set_has_hash()\n{\n  _has_bits_[0] |= 0x00000002u;\n}\ninline void block_id::clear_has_hash()\n{\n  _has_bits_[0] &= ~0x00000002u;\n}\ninline void block_id::clear_hash()\n{\n  if (hash_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    hash_->clear();\n  }\n  clear_has_hash();\n}\ninline const ::std::string &block_id::hash() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.block_id.hash)\n  return *hash_;\n}\ninline void block_id::set_hash(const ::std::string &value)\n{\n  set_has_hash();\n  if (hash_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    hash_ = new ::std::string;\n  }\n  hash_->assign(value);\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.block_id.hash)\n}\ninline void block_id::set_hash(const char *value)\n{\n  set_has_hash();\n  if (hash_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    hash_ = new ::std::string;\n  }\n  hash_->assign(value);\n  // @@protoc_insertion_point(field_set_char:libbitcoin.protocol.block_id.hash)\n}\ninline void block_id::set_hash(const void *value, size_t size)\n{\n  set_has_hash();\n  if (hash_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    hash_ = new ::std::string;\n  }\n  hash_->assign(reinterpret_cast<const char *>(value), size);\n  // @@protoc_insertion_point(field_set_pointer:libbitcoin.protocol.block_id.hash)\n}\ninline ::std::string *block_id::mutable_hash()\n{\n  set_has_hash();\n  if (hash_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    hash_ = new ::std::string;\n  }\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.block_id.hash)\n  return hash_;\n}\ninline ::std::string *block_id::release_hash()\n{\n  clear_has_hash();\n  if (hash_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    return NULL;\n  }\n  else\n  {\n    ::std::string *temp = hash_;\n    hash_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n    return temp;\n  }\n}\ninline void block_id::set_allocated_hash(::std::string *hash)\n{\n  if (hash_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    delete hash_;\n  }\n  if (hash)\n  {\n    set_has_hash();\n    hash_ = hash;\n  }\n  else\n  {\n    clear_has_hash();\n    hash_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n  }\n  // @@protoc_insertion_point(field_set_allocated:libbitcoin.protocol.block_id.hash)\n}\n\n// -------------------------------------------------------------------\n\n// block_location\n\n// optional .libbitcoin.protocol.block_id identity = 1;\ninline bool block_location::has_identity() const\n{\n  return (_has_bits_[0] & 0x00000001u) != 0;\n}\ninline void block_location::set_has_identity()\n{\n  _has_bits_[0] |= 0x00000001u;\n}\ninline void block_location::clear_has_identity()\n{\n  _has_bits_[0] &= ~0x00000001u;\n}\ninline void block_location::clear_identity()\n{\n  if (identity_ != NULL)\n    identity_->::libbitcoin::protocol::block_id::Clear();\n  clear_has_identity();\n}\ninline const ::libbitcoin::protocol::block_id &block_location::identity() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.block_location.identity)\n  return identity_ != NULL ? *identity_ : *default_instance_->identity_;\n}\ninline ::libbitcoin::protocol::block_id *block_location::mutable_identity()\n{\n  set_has_identity();\n  if (identity_ == NULL)\n    identity_ = new ::libbitcoin::protocol::block_id;\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.block_location.identity)\n  return identity_;\n}\ninline ::libbitcoin::protocol::block_id *block_location::release_identity()\n{\n  clear_has_identity();\n  ::libbitcoin::protocol::block_id *temp = identity_;\n  identity_ = NULL;\n  return temp;\n}\ninline void block_location::set_allocated_identity(::libbitcoin::protocol::block_id *identity)\n{\n  delete identity_;\n  identity_ = identity;\n  if (identity)\n  {\n    set_has_identity();\n  }\n  else\n  {\n    clear_has_identity();\n  }\n  // @@protoc_insertion_point(field_set_allocated:libbitcoin.protocol.block_location.identity)\n}\n\n// optional uint64 index = 2;\ninline bool block_location::has_index() const\n{\n  return (_has_bits_[0] & 0x00000002u) != 0;\n}\ninline void block_location::set_has_index()\n{\n  _has_bits_[0] |= 0x00000002u;\n}\ninline void block_location::clear_has_index()\n{\n  _has_bits_[0] &= ~0x00000002u;\n}\ninline void block_location::clear_index()\n{\n  index_ = GOOGLE_ULONGLONG(0);\n  clear_has_index();\n}\ninline ::google::protobuf::uint64 block_location::index() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.block_location.index)\n  return index_;\n}\ninline void block_location::set_index(::google::protobuf::uint64 value)\n{\n  set_has_index();\n  index_ = value;\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.block_location.index)\n}\n\n// repeated bytes branch = 3;\ninline int block_location::branch_size() const\n{\n  return branch_.size();\n}\ninline void block_location::clear_branch()\n{\n  branch_.Clear();\n}\ninline const ::std::string &block_location::branch(int index) const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.block_location.branch)\n  return branch_.Get(index);\n}\ninline ::std::string *block_location::mutable_branch(int index)\n{\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.block_location.branch)\n  return branch_.Mutable(index);\n}\ninline void block_location::set_branch(int index, const ::std::string &value)\n{\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.block_location.branch)\n  branch_.Mutable(index)->assign(value);\n}\ninline void block_location::set_branch(int index, const char *value)\n{\n  branch_.Mutable(index)->assign(value);\n  // @@protoc_insertion_point(field_set_char:libbitcoin.protocol.block_location.branch)\n}\ninline void block_location::set_branch(int index, const void *value, size_t size)\n{\n  branch_.Mutable(index)->assign(\n      reinterpret_cast<const char *>(value), size);\n  // @@protoc_insertion_point(field_set_pointer:libbitcoin.protocol.block_location.branch)\n}\ninline ::std::string *block_location::add_branch()\n{\n  return branch_.Add();\n}\ninline void block_location::add_branch(const ::std::string &value)\n{\n  branch_.Add()->assign(value);\n  // @@protoc_insertion_point(field_add:libbitcoin.protocol.block_location.branch)\n}\ninline void block_location::add_branch(const char *value)\n{\n  branch_.Add()->assign(value);\n  // @@protoc_insertion_point(field_add_char:libbitcoin.protocol.block_location.branch)\n}\ninline void block_location::add_branch(const void *value, size_t size)\n{\n  branch_.Add()->assign(reinterpret_cast<const char *>(value), size);\n  // @@protoc_insertion_point(field_add_pointer:libbitcoin.protocol.block_location.branch)\n}\ninline const ::google::protobuf::RepeatedPtrField<::std::string> &\nblock_location::branch() const\n{\n  // @@protoc_insertion_point(field_list:libbitcoin.protocol.block_location.branch)\n  return branch_;\n}\ninline ::google::protobuf::RepeatedPtrField<::std::string> *\nblock_location::mutable_branch()\n{\n  // @@protoc_insertion_point(field_mutable_list:libbitcoin.protocol.block_location.branch)\n  return &branch_;\n}\n\n// -------------------------------------------------------------------\n\n// tx_hash_result\n\n// required bytes hash = 1;\ninline bool tx_hash_result::has_hash() const\n{\n  return (_has_bits_[0] & 0x00000001u) != 0;\n}\ninline void tx_hash_result::set_has_hash()\n{\n  _has_bits_[0] |= 0x00000001u;\n}\ninline void tx_hash_result::clear_has_hash()\n{\n  _has_bits_[0] &= ~0x00000001u;\n}\ninline void tx_hash_result::clear_hash()\n{\n  if (hash_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    hash_->clear();\n  }\n  clear_has_hash();\n}\ninline const ::std::string &tx_hash_result::hash() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.tx_hash_result.hash)\n  return *hash_;\n}\ninline void tx_hash_result::set_hash(const ::std::string &value)\n{\n  set_has_hash();\n  if (hash_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    hash_ = new ::std::string;\n  }\n  hash_->assign(value);\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.tx_hash_result.hash)\n}\ninline void tx_hash_result::set_hash(const char *value)\n{\n  set_has_hash();\n  if (hash_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    hash_ = new ::std::string;\n  }\n  hash_->assign(value);\n  // @@protoc_insertion_point(field_set_char:libbitcoin.protocol.tx_hash_result.hash)\n}\ninline void tx_hash_result::set_hash(const void *value, size_t size)\n{\n  set_has_hash();\n  if (hash_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    hash_ = new ::std::string;\n  }\n  hash_->assign(reinterpret_cast<const char *>(value), size);\n  // @@protoc_insertion_point(field_set_pointer:libbitcoin.protocol.tx_hash_result.hash)\n}\ninline ::std::string *tx_hash_result::mutable_hash()\n{\n  set_has_hash();\n  if (hash_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    hash_ = new ::std::string;\n  }\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.tx_hash_result.hash)\n  return hash_;\n}\ninline ::std::string *tx_hash_result::release_hash()\n{\n  clear_has_hash();\n  if (hash_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    return NULL;\n  }\n  else\n  {\n    ::std::string *temp = hash_;\n    hash_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n    return temp;\n  }\n}\ninline void tx_hash_result::set_allocated_hash(::std::string *hash)\n{\n  if (hash_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    delete hash_;\n  }\n  if (hash)\n  {\n    set_has_hash();\n    hash_ = hash;\n  }\n  else\n  {\n    clear_has_hash();\n    hash_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n  }\n  // @@protoc_insertion_point(field_set_allocated:libbitcoin.protocol.tx_hash_result.hash)\n}\n\n// required .libbitcoin.protocol.block_location location = 2;\ninline bool tx_hash_result::has_location() const\n{\n  return (_has_bits_[0] & 0x00000002u) != 0;\n}\ninline void tx_hash_result::set_has_location()\n{\n  _has_bits_[0] |= 0x00000002u;\n}\ninline void tx_hash_result::clear_has_location()\n{\n  _has_bits_[0] &= ~0x00000002u;\n}\ninline void tx_hash_result::clear_location()\n{\n  if (location_ != NULL)\n    location_->::libbitcoin::protocol::block_location::Clear();\n  clear_has_location();\n}\ninline const ::libbitcoin::protocol::block_location &tx_hash_result::location() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.tx_hash_result.location)\n  return location_ != NULL ? *location_ : *default_instance_->location_;\n}\ninline ::libbitcoin::protocol::block_location *tx_hash_result::mutable_location()\n{\n  set_has_location();\n  if (location_ == NULL)\n    location_ = new ::libbitcoin::protocol::block_location;\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.tx_hash_result.location)\n  return location_;\n}\ninline ::libbitcoin::protocol::block_location *tx_hash_result::release_location()\n{\n  clear_has_location();\n  ::libbitcoin::protocol::block_location *temp = location_;\n  location_ = NULL;\n  return temp;\n}\ninline void tx_hash_result::set_allocated_location(::libbitcoin::protocol::block_location *location)\n{\n  delete location_;\n  location_ = location;\n  if (location)\n  {\n    set_has_location();\n  }\n  else\n  {\n    clear_has_location();\n  }\n  // @@protoc_insertion_point(field_set_allocated:libbitcoin.protocol.tx_hash_result.location)\n}\n\n// -------------------------------------------------------------------\n\n// tx_result\n\n// required .libbitcoin.protocol.tx transaction = 1;\ninline bool tx_result::has_transaction() const\n{\n  return (_has_bits_[0] & 0x00000001u) != 0;\n}\ninline void tx_result::set_has_transaction()\n{\n  _has_bits_[0] |= 0x00000001u;\n}\ninline void tx_result::clear_has_transaction()\n{\n  _has_bits_[0] &= ~0x00000001u;\n}\ninline void tx_result::clear_transaction()\n{\n  if (transaction_ != NULL)\n    transaction_->::libbitcoin::protocol::tx::Clear();\n  clear_has_transaction();\n}\ninline const ::libbitcoin::protocol::tx &tx_result::transaction() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.tx_result.transaction)\n  return transaction_ != NULL ? *transaction_ : *default_instance_->transaction_;\n}\ninline ::libbitcoin::protocol::tx *tx_result::mutable_transaction()\n{\n  set_has_transaction();\n  if (transaction_ == NULL)\n    transaction_ = new ::libbitcoin::protocol::tx;\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.tx_result.transaction)\n  return transaction_;\n}\ninline ::libbitcoin::protocol::tx *tx_result::release_transaction()\n{\n  clear_has_transaction();\n  ::libbitcoin::protocol::tx *temp = transaction_;\n  transaction_ = NULL;\n  return temp;\n}\ninline void tx_result::set_allocated_transaction(::libbitcoin::protocol::tx *transaction)\n{\n  delete transaction_;\n  transaction_ = transaction;\n  if (transaction)\n  {\n    set_has_transaction();\n  }\n  else\n  {\n    clear_has_transaction();\n  }\n  // @@protoc_insertion_point(field_set_allocated:libbitcoin.protocol.tx_result.transaction)\n}\n\n// required .libbitcoin.protocol.block_location location = 2;\ninline bool tx_result::has_location() const\n{\n  return (_has_bits_[0] & 0x00000002u) != 0;\n}\ninline void tx_result::set_has_location()\n{\n  _has_bits_[0] |= 0x00000002u;\n}\ninline void tx_result::clear_has_location()\n{\n  _has_bits_[0] &= ~0x00000002u;\n}\ninline void tx_result::clear_location()\n{\n  if (location_ != NULL)\n    location_->::libbitcoin::protocol::block_location::Clear();\n  clear_has_location();\n}\ninline const ::libbitcoin::protocol::block_location &tx_result::location() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.tx_result.location)\n  return location_ != NULL ? *location_ : *default_instance_->location_;\n}\ninline ::libbitcoin::protocol::block_location *tx_result::mutable_location()\n{\n  set_has_location();\n  if (location_ == NULL)\n    location_ = new ::libbitcoin::protocol::block_location;\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.tx_result.location)\n  return location_;\n}\ninline ::libbitcoin::protocol::block_location *tx_result::release_location()\n{\n  clear_has_location();\n  ::libbitcoin::protocol::block_location *temp = location_;\n  location_ = NULL;\n  return temp;\n}\ninline void tx_result::set_allocated_location(::libbitcoin::protocol::block_location *location)\n{\n  delete location_;\n  location_ = location;\n  if (location)\n  {\n    set_has_location();\n  }\n  else\n  {\n    clear_has_location();\n  }\n  // @@protoc_insertion_point(field_set_allocated:libbitcoin.protocol.tx_result.location)\n}\n\n// -------------------------------------------------------------------\n\n// output\n\n// required uint32 index = 1;\ninline bool output::has_index() const\n{\n  return (_has_bits_[0] & 0x00000001u) != 0;\n}\ninline void output::set_has_index()\n{\n  _has_bits_[0] |= 0x00000001u;\n}\ninline void output::clear_has_index()\n{\n  _has_bits_[0] &= ~0x00000001u;\n}\ninline void output::clear_index()\n{\n  index_ = 0u;\n  clear_has_index();\n}\ninline ::google::protobuf::uint32 output::index() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.output.index)\n  return index_;\n}\ninline void output::set_index(::google::protobuf::uint32 value)\n{\n  set_has_index();\n  index_ = value;\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.output.index)\n}\n\n// required uint64 satoshis = 2;\ninline bool output::has_satoshis() const\n{\n  return (_has_bits_[0] & 0x00000002u) != 0;\n}\ninline void output::set_has_satoshis()\n{\n  _has_bits_[0] |= 0x00000002u;\n}\ninline void output::clear_has_satoshis()\n{\n  _has_bits_[0] &= ~0x00000002u;\n}\ninline void output::clear_satoshis()\n{\n  satoshis_ = GOOGLE_ULONGLONG(0);\n  clear_has_satoshis();\n}\ninline ::google::protobuf::uint64 output::satoshis() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.output.satoshis)\n  return satoshis_;\n}\ninline void output::set_satoshis(::google::protobuf::uint64 value)\n{\n  set_has_satoshis();\n  satoshis_ = value;\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.output.satoshis)\n}\n\n// required bytes script = 3;\ninline bool output::has_script() const\n{\n  return (_has_bits_[0] & 0x00000004u) != 0;\n}\ninline void output::set_has_script()\n{\n  _has_bits_[0] |= 0x00000004u;\n}\ninline void output::clear_has_script()\n{\n  _has_bits_[0] &= ~0x00000004u;\n}\ninline void output::clear_script()\n{\n  if (script_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    script_->clear();\n  }\n  clear_has_script();\n}\ninline const ::std::string &output::script() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.output.script)\n  return *script_;\n}\ninline void output::set_script(const ::std::string &value)\n{\n  set_has_script();\n  if (script_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    script_ = new ::std::string;\n  }\n  script_->assign(value);\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.output.script)\n}\ninline void output::set_script(const char *value)\n{\n  set_has_script();\n  if (script_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    script_ = new ::std::string;\n  }\n  script_->assign(value);\n  // @@protoc_insertion_point(field_set_char:libbitcoin.protocol.output.script)\n}\ninline void output::set_script(const void *value, size_t size)\n{\n  set_has_script();\n  if (script_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    script_ = new ::std::string;\n  }\n  script_->assign(reinterpret_cast<const char *>(value), size);\n  // @@protoc_insertion_point(field_set_pointer:libbitcoin.protocol.output.script)\n}\ninline ::std::string *output::mutable_script()\n{\n  set_has_script();\n  if (script_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    script_ = new ::std::string;\n  }\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.output.script)\n  return script_;\n}\ninline ::std::string *output::release_script()\n{\n  clear_has_script();\n  if (script_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    return NULL;\n  }\n  else\n  {\n    ::std::string *temp = script_;\n    script_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n    return temp;\n  }\n}\ninline void output::set_allocated_script(::std::string *script)\n{\n  if (script_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    delete script_;\n  }\n  if (script)\n  {\n    set_has_script();\n    script_ = script;\n  }\n  else\n  {\n    clear_has_script();\n    script_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n  }\n  // @@protoc_insertion_point(field_set_allocated:libbitcoin.protocol.output.script)\n}\n\n// -------------------------------------------------------------------\n\n// utxo_result\n\n// required bytes tx_hash = 1;\ninline bool utxo_result::has_tx_hash() const\n{\n  return (_has_bits_[0] & 0x00000001u) != 0;\n}\ninline void utxo_result::set_has_tx_hash()\n{\n  _has_bits_[0] |= 0x00000001u;\n}\ninline void utxo_result::clear_has_tx_hash()\n{\n  _has_bits_[0] &= ~0x00000001u;\n}\ninline void utxo_result::clear_tx_hash()\n{\n  if (tx_hash_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    tx_hash_->clear();\n  }\n  clear_has_tx_hash();\n}\ninline const ::std::string &utxo_result::tx_hash() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.utxo_result.tx_hash)\n  return *tx_hash_;\n}\ninline void utxo_result::set_tx_hash(const ::std::string &value)\n{\n  set_has_tx_hash();\n  if (tx_hash_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    tx_hash_ = new ::std::string;\n  }\n  tx_hash_->assign(value);\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.utxo_result.tx_hash)\n}\ninline void utxo_result::set_tx_hash(const char *value)\n{\n  set_has_tx_hash();\n  if (tx_hash_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    tx_hash_ = new ::std::string;\n  }\n  tx_hash_->assign(value);\n  // @@protoc_insertion_point(field_set_char:libbitcoin.protocol.utxo_result.tx_hash)\n}\ninline void utxo_result::set_tx_hash(const void *value, size_t size)\n{\n  set_has_tx_hash();\n  if (tx_hash_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    tx_hash_ = new ::std::string;\n  }\n  tx_hash_->assign(reinterpret_cast<const char *>(value), size);\n  // @@protoc_insertion_point(field_set_pointer:libbitcoin.protocol.utxo_result.tx_hash)\n}\ninline ::std::string *utxo_result::mutable_tx_hash()\n{\n  set_has_tx_hash();\n  if (tx_hash_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    tx_hash_ = new ::std::string;\n  }\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.utxo_result.tx_hash)\n  return tx_hash_;\n}\ninline ::std::string *utxo_result::release_tx_hash()\n{\n  clear_has_tx_hash();\n  if (tx_hash_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    return NULL;\n  }\n  else\n  {\n    ::std::string *temp = tx_hash_;\n    tx_hash_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n    return temp;\n  }\n}\ninline void utxo_result::set_allocated_tx_hash(::std::string *tx_hash)\n{\n  if (tx_hash_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    delete tx_hash_;\n  }\n  if (tx_hash)\n  {\n    set_has_tx_hash();\n    tx_hash_ = tx_hash;\n  }\n  else\n  {\n    clear_has_tx_hash();\n    tx_hash_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n  }\n  // @@protoc_insertion_point(field_set_allocated:libbitcoin.protocol.utxo_result.tx_hash)\n}\n\n// required .libbitcoin.protocol.block_location location = 2;\ninline bool utxo_result::has_location() const\n{\n  return (_has_bits_[0] & 0x00000002u) != 0;\n}\ninline void utxo_result::set_has_location()\n{\n  _has_bits_[0] |= 0x00000002u;\n}\ninline void utxo_result::clear_has_location()\n{\n  _has_bits_[0] &= ~0x00000002u;\n}\ninline void utxo_result::clear_location()\n{\n  if (location_ != NULL)\n    location_->::libbitcoin::protocol::block_location::Clear();\n  clear_has_location();\n}\ninline const ::libbitcoin::protocol::block_location &utxo_result::location() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.utxo_result.location)\n  return location_ != NULL ? *location_ : *default_instance_->location_;\n}\ninline ::libbitcoin::protocol::block_location *utxo_result::mutable_location()\n{\n  set_has_location();\n  if (location_ == NULL)\n    location_ = new ::libbitcoin::protocol::block_location;\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.utxo_result.location)\n  return location_;\n}\ninline ::libbitcoin::protocol::block_location *utxo_result::release_location()\n{\n  clear_has_location();\n  ::libbitcoin::protocol::block_location *temp = location_;\n  location_ = NULL;\n  return temp;\n}\ninline void utxo_result::set_allocated_location(::libbitcoin::protocol::block_location *location)\n{\n  delete location_;\n  location_ = location;\n  if (location)\n  {\n    set_has_location();\n  }\n  else\n  {\n    clear_has_location();\n  }\n  // @@protoc_insertion_point(field_set_allocated:libbitcoin.protocol.utxo_result.location)\n}\n\n// repeated .libbitcoin.protocol.output outputs = 3;\ninline int utxo_result::outputs_size() const\n{\n  return outputs_.size();\n}\ninline void utxo_result::clear_outputs()\n{\n  outputs_.Clear();\n}\ninline const ::libbitcoin::protocol::output &utxo_result::outputs(int index) const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.utxo_result.outputs)\n  return outputs_.Get(index);\n}\ninline ::libbitcoin::protocol::output *utxo_result::mutable_outputs(int index)\n{\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.utxo_result.outputs)\n  return outputs_.Mutable(index);\n}\ninline ::libbitcoin::protocol::output *utxo_result::add_outputs()\n{\n  // @@protoc_insertion_point(field_add:libbitcoin.protocol.utxo_result.outputs)\n  return outputs_.Add();\n}\ninline const ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::output> &\nutxo_result::outputs() const\n{\n  // @@protoc_insertion_point(field_list:libbitcoin.protocol.utxo_result.outputs)\n  return outputs_;\n}\ninline ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::output> *\nutxo_result::mutable_outputs()\n{\n  // @@protoc_insertion_point(field_mutable_list:libbitcoin.protocol.utxo_result.outputs)\n  return &outputs_;\n}\n\n// -------------------------------------------------------------------\n\n// block_headers_request\n\n// optional .libbitcoin.protocol.block_id start = 1;\ninline bool block_headers_request::has_start() const\n{\n  return (_has_bits_[0] & 0x00000001u) != 0;\n}\ninline void block_headers_request::set_has_start()\n{\n  _has_bits_[0] |= 0x00000001u;\n}\ninline void block_headers_request::clear_has_start()\n{\n  _has_bits_[0] &= ~0x00000001u;\n}\ninline void block_headers_request::clear_start()\n{\n  if (start_ != NULL)\n    start_->::libbitcoin::protocol::block_id::Clear();\n  clear_has_start();\n}\ninline const ::libbitcoin::protocol::block_id &block_headers_request::start() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.block_headers_request.start)\n  return start_ != NULL ? *start_ : *default_instance_->start_;\n}\ninline ::libbitcoin::protocol::block_id *block_headers_request::mutable_start()\n{\n  set_has_start();\n  if (start_ == NULL)\n    start_ = new ::libbitcoin::protocol::block_id;\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.block_headers_request.start)\n  return start_;\n}\ninline ::libbitcoin::protocol::block_id *block_headers_request::release_start()\n{\n  clear_has_start();\n  ::libbitcoin::protocol::block_id *temp = start_;\n  start_ = NULL;\n  return temp;\n}\ninline void block_headers_request::set_allocated_start(::libbitcoin::protocol::block_id *start)\n{\n  delete start_;\n  start_ = start;\n  if (start)\n  {\n    set_has_start();\n  }\n  else\n  {\n    clear_has_start();\n  }\n  // @@protoc_insertion_point(field_set_allocated:libbitcoin.protocol.block_headers_request.start)\n}\n\n// optional uint32 results_per_page = 2;\ninline bool block_headers_request::has_results_per_page() const\n{\n  return (_has_bits_[0] & 0x00000002u) != 0;\n}\ninline void block_headers_request::set_has_results_per_page()\n{\n  _has_bits_[0] |= 0x00000002u;\n}\ninline void block_headers_request::clear_has_results_per_page()\n{\n  _has_bits_[0] &= ~0x00000002u;\n}\ninline void block_headers_request::clear_results_per_page()\n{\n  results_per_page_ = 0u;\n  clear_has_results_per_page();\n}\ninline ::google::protobuf::uint32 block_headers_request::results_per_page() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.block_headers_request.results_per_page)\n  return results_per_page_;\n}\ninline void block_headers_request::set_results_per_page(::google::protobuf::uint32 value)\n{\n  set_has_results_per_page();\n  results_per_page_ = value;\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.block_headers_request.results_per_page)\n}\n\n// -------------------------------------------------------------------\n\n// transactions_request\n\n// optional .libbitcoin.protocol.block_id start = 1;\ninline bool transactions_request::has_start() const\n{\n  return (_has_bits_[0] & 0x00000001u) != 0;\n}\ninline void transactions_request::set_has_start()\n{\n  _has_bits_[0] |= 0x00000001u;\n}\ninline void transactions_request::clear_has_start()\n{\n  _has_bits_[0] &= ~0x00000001u;\n}\ninline void transactions_request::clear_start()\n{\n  if (start_ != NULL)\n    start_->::libbitcoin::protocol::block_id::Clear();\n  clear_has_start();\n}\ninline const ::libbitcoin::protocol::block_id &transactions_request::start() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.transactions_request.start)\n  return start_ != NULL ? *start_ : *default_instance_->start_;\n}\ninline ::libbitcoin::protocol::block_id *transactions_request::mutable_start()\n{\n  set_has_start();\n  if (start_ == NULL)\n    start_ = new ::libbitcoin::protocol::block_id;\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.transactions_request.start)\n  return start_;\n}\ninline ::libbitcoin::protocol::block_id *transactions_request::release_start()\n{\n  clear_has_start();\n  ::libbitcoin::protocol::block_id *temp = start_;\n  start_ = NULL;\n  return temp;\n}\ninline void transactions_request::set_allocated_start(::libbitcoin::protocol::block_id *start)\n{\n  delete start_;\n  start_ = start;\n  if (start)\n  {\n    set_has_start();\n  }\n  else\n  {\n    clear_has_start();\n  }\n  // @@protoc_insertion_point(field_set_allocated:libbitcoin.protocol.transactions_request.start)\n}\n\n// optional uint32 results_per_page = 2;\ninline bool transactions_request::has_results_per_page() const\n{\n  return (_has_bits_[0] & 0x00000002u) != 0;\n}\ninline void transactions_request::set_has_results_per_page()\n{\n  _has_bits_[0] |= 0x00000002u;\n}\ninline void transactions_request::clear_has_results_per_page()\n{\n  _has_bits_[0] &= ~0x00000002u;\n}\ninline void transactions_request::clear_results_per_page()\n{\n  results_per_page_ = 0u;\n  clear_has_results_per_page();\n}\ninline ::google::protobuf::uint32 transactions_request::results_per_page() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.transactions_request.results_per_page)\n  return results_per_page_;\n}\ninline void transactions_request::set_results_per_page(::google::protobuf::uint32 value)\n{\n  set_has_results_per_page();\n  results_per_page_ = value;\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.transactions_request.results_per_page)\n}\n\n// repeated .libbitcoin.protocol.filter query = 3;\ninline int transactions_request::query_size() const\n{\n  return query_.size();\n}\ninline void transactions_request::clear_query()\n{\n  query_.Clear();\n}\ninline const ::libbitcoin::protocol::filter &transactions_request::query(int index) const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.transactions_request.query)\n  return query_.Get(index);\n}\ninline ::libbitcoin::protocol::filter *transactions_request::mutable_query(int index)\n{\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.transactions_request.query)\n  return query_.Mutable(index);\n}\ninline ::libbitcoin::protocol::filter *transactions_request::add_query()\n{\n  // @@protoc_insertion_point(field_add:libbitcoin.protocol.transactions_request.query)\n  return query_.Add();\n}\ninline const ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::filter> &\ntransactions_request::query() const\n{\n  // @@protoc_insertion_point(field_list:libbitcoin.protocol.transactions_request.query)\n  return query_;\n}\ninline ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::filter> *\ntransactions_request::mutable_query()\n{\n  // @@protoc_insertion_point(field_mutable_list:libbitcoin.protocol.transactions_request.query)\n  return &query_;\n}\n\n// optional .libbitcoin.protocol.tx_results result_type = 4 [default = TX_HASH];\ninline bool transactions_request::has_result_type() const\n{\n  return (_has_bits_[0] & 0x00000008u) != 0;\n}\ninline void transactions_request::set_has_result_type()\n{\n  _has_bits_[0] |= 0x00000008u;\n}\ninline void transactions_request::clear_has_result_type()\n{\n  _has_bits_[0] &= ~0x00000008u;\n}\ninline void transactions_request::clear_result_type()\n{\n  result_type_ = 1;\n  clear_has_result_type();\n}\ninline ::libbitcoin::protocol::tx_results transactions_request::result_type() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.transactions_request.result_type)\n  return static_cast<::libbitcoin::protocol::tx_results>(result_type_);\n}\ninline void transactions_request::set_result_type(::libbitcoin::protocol::tx_results value)\n{\n  assert(::libbitcoin::protocol::tx_results_IsValid(value));\n  set_has_result_type();\n  result_type_ = value;\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.transactions_request.result_type)\n}\n\n// optional .libbitcoin.protocol.locations location_type = 5 [default = NONE];\ninline bool transactions_request::has_location_type() const\n{\n  return (_has_bits_[0] & 0x00000010u) != 0;\n}\ninline void transactions_request::set_has_location_type()\n{\n  _has_bits_[0] |= 0x00000010u;\n}\ninline void transactions_request::clear_has_location_type()\n{\n  _has_bits_[0] &= ~0x00000010u;\n}\ninline void transactions_request::clear_location_type()\n{\n  location_type_ = 0;\n  clear_has_location_type();\n}\ninline ::libbitcoin::protocol::locations transactions_request::location_type() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.transactions_request.location_type)\n  return static_cast<::libbitcoin::protocol::locations>(location_type_);\n}\ninline void transactions_request::set_location_type(::libbitcoin::protocol::locations value)\n{\n  assert(::libbitcoin::protocol::locations_IsValid(value));\n  set_has_location_type();\n  location_type_ = value;\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.transactions_request.location_type)\n}\n\n// -------------------------------------------------------------------\n\n// request\n\n// required uint32 id = 1;\ninline bool request::has_id() const\n{\n  return (_has_bits_[0] & 0x00000001u) != 0;\n}\ninline void request::set_has_id()\n{\n  _has_bits_[0] |= 0x00000001u;\n}\ninline void request::clear_has_id()\n{\n  _has_bits_[0] &= ~0x00000001u;\n}\ninline void request::clear_id()\n{\n  id_ = 0u;\n  clear_has_id();\n}\ninline ::google::protobuf::uint32 request::id() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.request.id)\n  return id_;\n}\ninline void request::set_id(::google::protobuf::uint32 value)\n{\n  set_has_id();\n  id_ = value;\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.request.id)\n}\n\n// optional .libbitcoin.protocol.block_headers_request get_block_headers = 2;\ninline bool request::has_get_block_headers() const\n{\n  return request_type_case() == kGetBlockHeaders;\n}\ninline void request::set_has_get_block_headers()\n{\n  _oneof_case_[0] = kGetBlockHeaders;\n}\ninline void request::clear_get_block_headers()\n{\n  if (has_get_block_headers())\n  {\n    delete request_type_.get_block_headers_;\n    clear_has_request_type();\n  }\n}\ninline const ::libbitcoin::protocol::block_headers_request &request::get_block_headers() const\n{\n  return has_get_block_headers() ? *request_type_.get_block_headers_\n                                 : ::libbitcoin::protocol::block_headers_request::default_instance();\n}\ninline ::libbitcoin::protocol::block_headers_request *request::mutable_get_block_headers()\n{\n  if (!has_get_block_headers())\n  {\n    clear_request_type();\n    set_has_get_block_headers();\n    request_type_.get_block_headers_ = new ::libbitcoin::protocol::block_headers_request;\n  }\n  return request_type_.get_block_headers_;\n}\ninline ::libbitcoin::protocol::block_headers_request *request::release_get_block_headers()\n{\n  if (has_get_block_headers())\n  {\n    clear_has_request_type();\n    ::libbitcoin::protocol::block_headers_request *temp = request_type_.get_block_headers_;\n    request_type_.get_block_headers_ = NULL;\n    return temp;\n  }\n  else\n  {\n    return NULL;\n  }\n}\ninline void request::set_allocated_get_block_headers(::libbitcoin::protocol::block_headers_request *get_block_headers)\n{\n  clear_request_type();\n  if (get_block_headers)\n  {\n    set_has_get_block_headers();\n    request_type_.get_block_headers_ = get_block_headers;\n  }\n}\n\n// optional .libbitcoin.protocol.transactions_request get_transactions = 3;\ninline bool request::has_get_transactions() const\n{\n  return request_type_case() == kGetTransactions;\n}\ninline void request::set_has_get_transactions()\n{\n  _oneof_case_[0] = kGetTransactions;\n}\ninline void request::clear_get_transactions()\n{\n  if (has_get_transactions())\n  {\n    delete request_type_.get_transactions_;\n    clear_has_request_type();\n  }\n}\ninline const ::libbitcoin::protocol::transactions_request &request::get_transactions() const\n{\n  return has_get_transactions() ? *request_type_.get_transactions_\n                                : ::libbitcoin::protocol::transactions_request::default_instance();\n}\ninline ::libbitcoin::protocol::transactions_request *request::mutable_get_transactions()\n{\n  if (!has_get_transactions())\n  {\n    clear_request_type();\n    set_has_get_transactions();\n    request_type_.get_transactions_ = new ::libbitcoin::protocol::transactions_request;\n  }\n  return request_type_.get_transactions_;\n}\ninline ::libbitcoin::protocol::transactions_request *request::release_get_transactions()\n{\n  if (has_get_transactions())\n  {\n    clear_has_request_type();\n    ::libbitcoin::protocol::transactions_request *temp = request_type_.get_transactions_;\n    request_type_.get_transactions_ = NULL;\n    return temp;\n  }\n  else\n  {\n    return NULL;\n  }\n}\ninline void request::set_allocated_get_transactions(::libbitcoin::protocol::transactions_request *get_transactions)\n{\n  clear_request_type();\n  if (get_transactions)\n  {\n    set_has_get_transactions();\n    request_type_.get_transactions_ = get_transactions;\n  }\n}\n\n// optional .libbitcoin.protocol.tx post_transaction = 4;\ninline bool request::has_post_transaction() const\n{\n  return request_type_case() == kPostTransaction;\n}\ninline void request::set_has_post_transaction()\n{\n  _oneof_case_[0] = kPostTransaction;\n}\ninline void request::clear_post_transaction()\n{\n  if (has_post_transaction())\n  {\n    delete request_type_.post_transaction_;\n    clear_has_request_type();\n  }\n}\ninline const ::libbitcoin::protocol::tx &request::post_transaction() const\n{\n  return has_post_transaction() ? *request_type_.post_transaction_\n                                : ::libbitcoin::protocol::tx::default_instance();\n}\ninline ::libbitcoin::protocol::tx *request::mutable_post_transaction()\n{\n  if (!has_post_transaction())\n  {\n    clear_request_type();\n    set_has_post_transaction();\n    request_type_.post_transaction_ = new ::libbitcoin::protocol::tx;\n  }\n  return request_type_.post_transaction_;\n}\ninline ::libbitcoin::protocol::tx *request::release_post_transaction()\n{\n  if (has_post_transaction())\n  {\n    clear_has_request_type();\n    ::libbitcoin::protocol::tx *temp = request_type_.post_transaction_;\n    request_type_.post_transaction_ = NULL;\n    return temp;\n  }\n  else\n  {\n    return NULL;\n  }\n}\ninline void request::set_allocated_post_transaction(::libbitcoin::protocol::tx *post_transaction)\n{\n  clear_request_type();\n  if (post_transaction)\n  {\n    set_has_post_transaction();\n    request_type_.post_transaction_ = post_transaction;\n  }\n}\n\n// optional .libbitcoin.protocol.tx validate_tx_engine = 5;\ninline bool request::has_validate_tx_engine() const\n{\n  return request_type_case() == kValidateTransaction;\n}\ninline void request::set_has_validate_tx_engine()\n{\n  _oneof_case_[0] = kValidateTransaction;\n}\ninline void request::clear_validate_tx_engine()\n{\n  if (has_validate_tx_engine())\n  {\n    delete request_type_.validate_tx_engine_;\n    clear_has_request_type();\n  }\n}\ninline const ::libbitcoin::protocol::tx &request::validate_tx_engine() const\n{\n  return has_validate_tx_engine() ? *request_type_.validate_tx_engine_\n                                    : ::libbitcoin::protocol::tx::default_instance();\n}\ninline ::libbitcoin::protocol::tx *request::mutable_validate_tx_engine()\n{\n  if (!has_validate_tx_engine())\n  {\n    clear_request_type();\n    set_has_validate_tx_engine();\n    request_type_.validate_tx_engine_ = new ::libbitcoin::protocol::tx;\n  }\n  return request_type_.validate_tx_engine_;\n}\ninline ::libbitcoin::protocol::tx *request::release_validate_tx_engine()\n{\n  if (has_validate_tx_engine())\n  {\n    clear_has_request_type();\n    ::libbitcoin::protocol::tx *temp = request_type_.validate_tx_engine_;\n    request_type_.validate_tx_engine_ = NULL;\n    return temp;\n  }\n  else\n  {\n    return NULL;\n  }\n}\ninline void request::set_allocated_validate_tx_engine(::libbitcoin::protocol::tx *validate_tx_engine)\n{\n  clear_request_type();\n  if (validate_tx_engine)\n  {\n    set_has_validate_tx_engine();\n    request_type_.validate_tx_engine_ = validate_tx_engine;\n  }\n}\n\n// optional .libbitcoin.protocol.block post_block = 6;\ninline bool request::has_post_block() const\n{\n  return request_type_case() == kPostBlock;\n}\ninline void request::set_has_post_block()\n{\n  _oneof_case_[0] = kPostBlock;\n}\ninline void request::clear_post_block()\n{\n  if (has_post_block())\n  {\n    delete request_type_.post_block_;\n    clear_has_request_type();\n  }\n}\ninline const ::libbitcoin::protocol::block &request::post_block() const\n{\n  return has_post_block() ? *request_type_.post_block_\n                          : ::libbitcoin::protocol::block::default_instance();\n}\ninline ::libbitcoin::protocol::block *request::mutable_post_block()\n{\n  if (!has_post_block())\n  {\n    clear_request_type();\n    set_has_post_block();\n    request_type_.post_block_ = new ::libbitcoin::protocol::block;\n  }\n  return request_type_.post_block_;\n}\ninline ::libbitcoin::protocol::block *request::release_post_block()\n{\n  if (has_post_block())\n  {\n    clear_has_request_type();\n    ::libbitcoin::protocol::block *temp = request_type_.post_block_;\n    request_type_.post_block_ = NULL;\n    return temp;\n  }\n  else\n  {\n    return NULL;\n  }\n}\ninline void request::set_allocated_post_block(::libbitcoin::protocol::block *post_block)\n{\n  clear_request_type();\n  if (post_block)\n  {\n    set_has_post_block();\n    request_type_.post_block_ = post_block;\n  }\n}\n\n// optional .libbitcoin.protocol.block validate_block = 7;\ninline bool request::has_validate_block() const\n{\n  return request_type_case() == kValidateBlock;\n}\ninline void request::set_has_validate_block()\n{\n  _oneof_case_[0] = kValidateBlock;\n}\ninline void request::clear_validate_block()\n{\n  if (has_validate_block())\n  {\n    delete request_type_.validate_block_;\n    clear_has_request_type();\n  }\n}\ninline const ::libbitcoin::protocol::block &request::validate_block() const\n{\n  return has_validate_block() ? *request_type_.validate_block_\n                              : ::libbitcoin::protocol::block::default_instance();\n}\ninline ::libbitcoin::protocol::block *request::mutable_validate_block()\n{\n  if (!has_validate_block())\n  {\n    clear_request_type();\n    set_has_validate_block();\n    request_type_.validate_block_ = new ::libbitcoin::protocol::block;\n  }\n  return request_type_.validate_block_;\n}\ninline ::libbitcoin::protocol::block *request::release_validate_block()\n{\n  if (has_validate_block())\n  {\n    clear_has_request_type();\n    ::libbitcoin::protocol::block *temp = request_type_.validate_block_;\n    request_type_.validate_block_ = NULL;\n    return temp;\n  }\n  else\n  {\n    return NULL;\n  }\n}\ninline void request::set_allocated_validate_block(::libbitcoin::protocol::block *validate_block)\n{\n  clear_request_type();\n  if (validate_block)\n  {\n    set_has_validate_block();\n    request_type_.validate_block_ = validate_block;\n  }\n}\n\ninline bool request::has_request_type()\n{\n  return request_type_case() != REQUEST_TYPE_NOT_SET;\n}\ninline void request::clear_has_request_type()\n{\n  _oneof_case_[0] = REQUEST_TYPE_NOT_SET;\n}\ninline request::RequestTypeCase request::request_type_case() const\n{\n  return request::RequestTypeCase(_oneof_case_[0]);\n}\n// -------------------------------------------------------------------\n\n// response_block_headers\n\n// optional .libbitcoin.protocol.block_id next = 1;\ninline bool response_block_headers::has_next() const\n{\n  return (_has_bits_[0] & 0x00000001u) != 0;\n}\ninline void response_block_headers::set_has_next()\n{\n  _has_bits_[0] |= 0x00000001u;\n}\ninline void response_block_headers::clear_has_next()\n{\n  _has_bits_[0] &= ~0x00000001u;\n}\ninline void response_block_headers::clear_next()\n{\n  if (next_ != NULL)\n    next_->::libbitcoin::protocol::block_id::Clear();\n  clear_has_next();\n}\ninline const ::libbitcoin::protocol::block_id &response_block_headers::next() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.response.block_headers.next)\n  return next_ != NULL ? *next_ : *default_instance_->next_;\n}\ninline ::libbitcoin::protocol::block_id *response_block_headers::mutable_next()\n{\n  set_has_next();\n  if (next_ == NULL)\n    next_ = new ::libbitcoin::protocol::block_id;\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.response.block_headers.next)\n  return next_;\n}\ninline ::libbitcoin::protocol::block_id *response_block_headers::release_next()\n{\n  clear_has_next();\n  ::libbitcoin::protocol::block_id *temp = next_;\n  next_ = NULL;\n  return temp;\n}\ninline void response_block_headers::set_allocated_next(::libbitcoin::protocol::block_id *next)\n{\n  delete next_;\n  next_ = next;\n  if (next)\n  {\n    set_has_next();\n  }\n  else\n  {\n    clear_has_next();\n  }\n  // @@protoc_insertion_point(field_set_allocated:libbitcoin.protocol.response.block_headers.next)\n}\n\n// optional .libbitcoin.protocol.block_id top = 2;\ninline bool response_block_headers::has_top() const\n{\n  return (_has_bits_[0] & 0x00000002u) != 0;\n}\ninline void response_block_headers::set_has_top()\n{\n  _has_bits_[0] |= 0x00000002u;\n}\ninline void response_block_headers::clear_has_top()\n{\n  _has_bits_[0] &= ~0x00000002u;\n}\ninline void response_block_headers::clear_top()\n{\n  if (top_ != NULL)\n    top_->::libbitcoin::protocol::block_id::Clear();\n  clear_has_top();\n}\ninline const ::libbitcoin::protocol::block_id &response_block_headers::top() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.response.block_headers.top)\n  return top_ != NULL ? *top_ : *default_instance_->top_;\n}\ninline ::libbitcoin::protocol::block_id *response_block_headers::mutable_top()\n{\n  set_has_top();\n  if (top_ == NULL)\n    top_ = new ::libbitcoin::protocol::block_id;\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.response.block_headers.top)\n  return top_;\n}\ninline ::libbitcoin::protocol::block_id *response_block_headers::release_top()\n{\n  clear_has_top();\n  ::libbitcoin::protocol::block_id *temp = top_;\n  top_ = NULL;\n  return temp;\n}\ninline void response_block_headers::set_allocated_top(::libbitcoin::protocol::block_id *top)\n{\n  delete top_;\n  top_ = top;\n  if (top)\n  {\n    set_has_top();\n  }\n  else\n  {\n    clear_has_top();\n  }\n  // @@protoc_insertion_point(field_set_allocated:libbitcoin.protocol.response.block_headers.top)\n}\n\n// repeated .libbitcoin.protocol.block_header headers = 3;\ninline int response_block_headers::headers_size() const\n{\n  return headers_.size();\n}\ninline void response_block_headers::clear_headers()\n{\n  headers_.Clear();\n}\ninline const ::libbitcoin::protocol::block_header &response_block_headers::headers(int index) const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.response.block_headers.headers)\n  return headers_.Get(index);\n}\ninline ::libbitcoin::protocol::block_header *response_block_headers::mutable_headers(int index)\n{\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.response.block_headers.headers)\n  return headers_.Mutable(index);\n}\ninline ::libbitcoin::protocol::block_header *response_block_headers::add_headers()\n{\n  // @@protoc_insertion_point(field_add:libbitcoin.protocol.response.block_headers.headers)\n  return headers_.Add();\n}\ninline const ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::block_header> &\nresponse_block_headers::headers() const\n{\n  // @@protoc_insertion_point(field_list:libbitcoin.protocol.response.block_headers.headers)\n  return headers_;\n}\ninline ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::block_header> *\nresponse_block_headers::mutable_headers()\n{\n  // @@protoc_insertion_point(field_mutable_list:libbitcoin.protocol.response.block_headers.headers)\n  return &headers_;\n}\n\n// -------------------------------------------------------------------\n\n// response_transactions\n\n// optional .libbitcoin.protocol.block_id next = 1;\ninline bool response_transactions::has_next() const\n{\n  return (_has_bits_[0] & 0x00000001u) != 0;\n}\ninline void response_transactions::set_has_next()\n{\n  _has_bits_[0] |= 0x00000001u;\n}\ninline void response_transactions::clear_has_next()\n{\n  _has_bits_[0] &= ~0x00000001u;\n}\ninline void response_transactions::clear_next()\n{\n  if (next_ != NULL)\n    next_->::libbitcoin::protocol::block_id::Clear();\n  clear_has_next();\n}\ninline const ::libbitcoin::protocol::block_id &response_transactions::next() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.response.transactions.next)\n  return next_ != NULL ? *next_ : *default_instance_->next_;\n}\ninline ::libbitcoin::protocol::block_id *response_transactions::mutable_next()\n{\n  set_has_next();\n  if (next_ == NULL)\n    next_ = new ::libbitcoin::protocol::block_id;\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.response.transactions.next)\n  return next_;\n}\ninline ::libbitcoin::protocol::block_id *response_transactions::release_next()\n{\n  clear_has_next();\n  ::libbitcoin::protocol::block_id *temp = next_;\n  next_ = NULL;\n  return temp;\n}\ninline void response_transactions::set_allocated_next(::libbitcoin::protocol::block_id *next)\n{\n  delete next_;\n  next_ = next;\n  if (next)\n  {\n    set_has_next();\n  }\n  else\n  {\n    clear_has_next();\n  }\n  // @@protoc_insertion_point(field_set_allocated:libbitcoin.protocol.response.transactions.next)\n}\n\n// optional .libbitcoin.protocol.block_id top = 2;\ninline bool response_transactions::has_top() const\n{\n  return (_has_bits_[0] & 0x00000002u) != 0;\n}\ninline void response_transactions::set_has_top()\n{\n  _has_bits_[0] |= 0x00000002u;\n}\ninline void response_transactions::clear_has_top()\n{\n  _has_bits_[0] &= ~0x00000002u;\n}\ninline void response_transactions::clear_top()\n{\n  if (top_ != NULL)\n    top_->::libbitcoin::protocol::block_id::Clear();\n  clear_has_top();\n}\ninline const ::libbitcoin::protocol::block_id &response_transactions::top() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.response.transactions.top)\n  return top_ != NULL ? *top_ : *default_instance_->top_;\n}\ninline ::libbitcoin::protocol::block_id *response_transactions::mutable_top()\n{\n  set_has_top();\n  if (top_ == NULL)\n    top_ = new ::libbitcoin::protocol::block_id;\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.response.transactions.top)\n  return top_;\n}\ninline ::libbitcoin::protocol::block_id *response_transactions::release_top()\n{\n  clear_has_top();\n  ::libbitcoin::protocol::block_id *temp = top_;\n  top_ = NULL;\n  return temp;\n}\ninline void response_transactions::set_allocated_top(::libbitcoin::protocol::block_id *top)\n{\n  delete top_;\n  top_ = top;\n  if (top)\n  {\n    set_has_top();\n  }\n  else\n  {\n    clear_has_top();\n  }\n  // @@protoc_insertion_point(field_set_allocated:libbitcoin.protocol.response.transactions.top)\n}\n\n// repeated .libbitcoin.protocol.tx_hash_result hashes = 3;\ninline int response_transactions::hashes_size() const\n{\n  return hashes_.size();\n}\ninline void response_transactions::clear_hashes()\n{\n  hashes_.Clear();\n}\ninline const ::libbitcoin::protocol::tx_hash_result &response_transactions::hashes(int index) const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.response.transactions.hashes)\n  return hashes_.Get(index);\n}\ninline ::libbitcoin::protocol::tx_hash_result *response_transactions::mutable_hashes(int index)\n{\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.response.transactions.hashes)\n  return hashes_.Mutable(index);\n}\ninline ::libbitcoin::protocol::tx_hash_result *response_transactions::add_hashes()\n{\n  // @@protoc_insertion_point(field_add:libbitcoin.protocol.response.transactions.hashes)\n  return hashes_.Add();\n}\ninline const ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::tx_hash_result> &\nresponse_transactions::hashes() const\n{\n  // @@protoc_insertion_point(field_list:libbitcoin.protocol.response.transactions.hashes)\n  return hashes_;\n}\ninline ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::tx_hash_result> *\nresponse_transactions::mutable_hashes()\n{\n  // @@protoc_insertion_point(field_mutable_list:libbitcoin.protocol.response.transactions.hashes)\n  return &hashes_;\n}\n\n// repeated .libbitcoin.protocol.tx_result transactions = 4;\ninline int response_transactions::transactions_size() const\n{\n  return transactions_.size();\n}\ninline void response_transactions::clear_transactions()\n{\n  transactions_.Clear();\n}\ninline const ::libbitcoin::protocol::tx_result &response_transactions::transactions(int index) const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.response.transactions.transactions)\n  return transactions_.Get(index);\n}\ninline ::libbitcoin::protocol::tx_result *response_transactions::mutable_transactions(int index)\n{\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.response.transactions.transactions)\n  return transactions_.Mutable(index);\n}\ninline ::libbitcoin::protocol::tx_result *response_transactions::add_transactions()\n{\n  // @@protoc_insertion_point(field_add:libbitcoin.protocol.response.transactions.transactions)\n  return transactions_.Add();\n}\ninline const ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::tx_result> &\nresponse_transactions::transactions() const\n{\n  // @@protoc_insertion_point(field_list:libbitcoin.protocol.response.transactions.transactions)\n  return transactions_;\n}\ninline ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::tx_result> *\nresponse_transactions::mutable_transactions()\n{\n  // @@protoc_insertion_point(field_mutable_list:libbitcoin.protocol.response.transactions.transactions)\n  return &transactions_;\n}\n\n// repeated .libbitcoin.protocol.utxo_result utxos = 5;\ninline int response_transactions::utxos_size() const\n{\n  return utxos_.size();\n}\ninline void response_transactions::clear_utxos()\n{\n  utxos_.Clear();\n}\ninline const ::libbitcoin::protocol::utxo_result &response_transactions::utxos(int index) const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.response.transactions.utxos)\n  return utxos_.Get(index);\n}\ninline ::libbitcoin::protocol::utxo_result *response_transactions::mutable_utxos(int index)\n{\n  // @@protoc_insertion_point(field_mutable:libbitcoin.protocol.response.transactions.utxos)\n  return utxos_.Mutable(index);\n}\ninline ::libbitcoin::protocol::utxo_result *response_transactions::add_utxos()\n{\n  // @@protoc_insertion_point(field_add:libbitcoin.protocol.response.transactions.utxos)\n  return utxos_.Add();\n}\ninline const ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::utxo_result> &\nresponse_transactions::utxos() const\n{\n  // @@protoc_insertion_point(field_list:libbitcoin.protocol.response.transactions.utxos)\n  return utxos_;\n}\ninline ::google::protobuf::RepeatedPtrField<::libbitcoin::protocol::utxo_result> *\nresponse_transactions::mutable_utxos()\n{\n  // @@protoc_insertion_point(field_mutable_list:libbitcoin.protocol.response.transactions.utxos)\n  return &utxos_;\n}\n\n// -------------------------------------------------------------------\n\n// response\n\n// required uint32 id = 1;\ninline bool response::has_id() const\n{\n  return (_has_bits_[0] & 0x00000001u) != 0;\n}\ninline void response::set_has_id()\n{\n  _has_bits_[0] |= 0x00000001u;\n}\ninline void response::clear_has_id()\n{\n  _has_bits_[0] &= ~0x00000001u;\n}\ninline void response::clear_id()\n{\n  id_ = 0u;\n  clear_has_id();\n}\ninline ::google::protobuf::uint32 response::id() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.response.id)\n  return id_;\n}\ninline void response::set_id(::google::protobuf::uint32 value)\n{\n  set_has_id();\n  id_ = value;\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.response.id)\n}\n\n// optional sint32 status = 2;\ninline bool response::has_status() const\n{\n  return (_has_bits_[0] & 0x00000002u) != 0;\n}\ninline void response::set_has_status()\n{\n  _has_bits_[0] |= 0x00000002u;\n}\ninline void response::clear_has_status()\n{\n  _has_bits_[0] &= ~0x00000002u;\n}\ninline void response::clear_status()\n{\n  status_ = 0;\n  clear_has_status();\n}\ninline ::google::protobuf::int32 response::status() const\n{\n  // @@protoc_insertion_point(field_get:libbitcoin.protocol.response.status)\n  return status_;\n}\ninline void response::set_status(::google::protobuf::int32 value)\n{\n  set_has_status();\n  status_ = value;\n  // @@protoc_insertion_point(field_set:libbitcoin.protocol.response.status)\n}\n\n// optional .libbitcoin.protocol.response.block_headers get_block_headers_response = 3;\ninline bool response::has_get_block_headers_response() const\n{\n  return response_type_case() == kGetBlockHeadersResponse;\n}\ninline void response::set_has_get_block_headers_response()\n{\n  _oneof_case_[0] = kGetBlockHeadersResponse;\n}\ninline void response::clear_get_block_headers_response()\n{\n  if (has_get_block_headers_response())\n  {\n    delete response_type_.get_block_headers_response_;\n    clear_has_response_type();\n  }\n}\ninline const ::libbitcoin::protocol::response_block_headers &response::get_block_headers_response() const\n{\n  return has_get_block_headers_response() ? *response_type_.get_block_headers_response_\n                                          : ::libbitcoin::protocol::response_block_headers::default_instance();\n}\ninline ::libbitcoin::protocol::response_block_headers *response::mutable_get_block_headers_response()\n{\n  if (!has_get_block_headers_response())\n  {\n    clear_response_type();\n    set_has_get_block_headers_response();\n    response_type_.get_block_headers_response_ = new ::libbitcoin::protocol::response_block_headers;\n  }\n  return response_type_.get_block_headers_response_;\n}\ninline ::libbitcoin::protocol::response_block_headers *response::release_get_block_headers_response()\n{\n  if (has_get_block_headers_response())\n  {\n    clear_has_response_type();\n    ::libbitcoin::protocol::response_block_headers *temp = response_type_.get_block_headers_response_;\n    response_type_.get_block_headers_response_ = NULL;\n    return temp;\n  }\n  else\n  {\n    return NULL;\n  }\n}\ninline void response::set_allocated_get_block_headers_response(::libbitcoin::protocol::response_block_headers *get_block_headers_response)\n{\n  clear_response_type();\n  if (get_block_headers_response)\n  {\n    set_has_get_block_headers_response();\n    response_type_.get_block_headers_response_ = get_block_headers_response;\n  }\n}\n\n// optional .libbitcoin.protocol.response.transactions get_transactions_response = 4;\ninline bool response::has_get_transactions_response() const\n{\n  return response_type_case() == kGetTransactionsResponse;\n}\ninline void response::set_has_get_transactions_response()\n{\n  _oneof_case_[0] = kGetTransactionsResponse;\n}\ninline void response::clear_get_transactions_response()\n{\n  if (has_get_transactions_response())\n  {\n    delete response_type_.get_transactions_response_;\n    clear_has_response_type();\n  }\n}\ninline const ::libbitcoin::protocol::response_transactions &response::get_transactions_response() const\n{\n  return has_get_transactions_response() ? *response_type_.get_transactions_response_\n                                         : ::libbitcoin::protocol::response_transactions::default_instance();\n}\ninline ::libbitcoin::protocol::response_transactions *response::mutable_get_transactions_response()\n{\n  if (!has_get_transactions_response())\n  {\n    clear_response_type();\n    set_has_get_transactions_response();\n    response_type_.get_transactions_response_ = new ::libbitcoin::protocol::response_transactions;\n  }\n  return response_type_.get_transactions_response_;\n}\ninline ::libbitcoin::protocol::response_transactions *response::release_get_transactions_response()\n{\n  if (has_get_transactions_response())\n  {\n    clear_has_response_type();\n    ::libbitcoin::protocol::response_transactions *temp = response_type_.get_transactions_response_;\n    response_type_.get_transactions_response_ = NULL;\n    return temp;\n  }\n  else\n  {\n    return NULL;\n  }\n}\ninline void response::set_allocated_get_transactions_response(::libbitcoin::protocol::response_transactions *get_transactions_response)\n{\n  clear_response_type();\n  if (get_transactions_response)\n  {\n    set_has_get_transactions_response();\n    response_type_.get_transactions_response_ = get_transactions_response;\n  }\n}\n\n// optional bool post_transaction_succeeded = 5;\ninline bool response::has_post_transaction_succeeded() const\n{\n  return response_type_case() == kPostTransactionSucceeded;\n}\ninline void response::set_has_post_transaction_succeeded()\n{\n  _oneof_case_[0] = kPostTransactionSucceeded;\n}\ninline void response::clear_post_transaction_succeeded()\n{\n  if (has_post_transaction_succeeded())\n  {\n    response_type_.post_transaction_succeeded_ = false;\n    clear_has_response_type();\n  }\n}\ninline bool response::post_transaction_succeeded() const\n{\n  if (has_post_transaction_succeeded())\n  {\n    return response_type_.post_transaction_succeeded_;\n  }\n  return false;\n}\ninline void response::set_post_transaction_succeeded(bool value)\n{\n  if (!has_post_transaction_succeeded())\n  {\n    clear_response_type();\n    set_has_post_transaction_succeeded();\n  }\n  response_type_.post_transaction_succeeded_ = value;\n}\n\n// optional bool validate_tx_engine_succeeded = 6;\ninline bool response::has_validate_tx_engine_succeeded() const\n{\n  return response_type_case() == kValidateTransactionSucceeded;\n}\ninline void response::set_has_validate_tx_engine_succeeded()\n{\n  _oneof_case_[0] = kValidateTransactionSucceeded;\n}\ninline void response::clear_validate_tx_engine_succeeded()\n{\n  if (has_validate_tx_engine_succeeded())\n  {\n    response_type_.validate_tx_engine_succeeded_ = false;\n    clear_has_response_type();\n  }\n}\ninline bool response::validate_tx_engine_succeeded() const\n{\n  if (has_validate_tx_engine_succeeded())\n  {\n    return response_type_.validate_tx_engine_succeeded_;\n  }\n  return false;\n}\ninline void response::set_validate_tx_engine_succeeded(bool value)\n{\n  if (!has_validate_tx_engine_succeeded())\n  {\n    clear_response_type();\n    set_has_validate_tx_engine_succeeded();\n  }\n  response_type_.validate_tx_engine_succeeded_ = value;\n}\n\n// optional bool post_block_succeeded = 7;\ninline bool response::has_post_block_succeeded() const\n{\n  return response_type_case() == kPostBlockSucceeded;\n}\ninline void response::set_has_post_block_succeeded()\n{\n  _oneof_case_[0] = kPostBlockSucceeded;\n}\ninline void response::clear_post_block_succeeded()\n{\n  if (has_post_block_succeeded())\n  {\n    response_type_.post_block_succeeded_ = false;\n    clear_has_response_type();\n  }\n}\ninline bool response::post_block_succeeded() const\n{\n  if (has_post_block_succeeded())\n  {\n    return response_type_.post_block_succeeded_;\n  }\n  return false;\n}\ninline void response::set_post_block_succeeded(bool value)\n{\n  if (!has_post_block_succeeded())\n  {\n    clear_response_type();\n    set_has_post_block_succeeded();\n  }\n  response_type_.post_block_succeeded_ = value;\n}\n\n// optional bool validate_block_succeeded = 8;\ninline bool response::has_validate_block_succeeded() const\n{\n  return response_type_case() == kValidateBlockSucceeded;\n}\ninline void response::set_has_validate_block_succeeded()\n{\n  _oneof_case_[0] = kValidateBlockSucceeded;\n}\ninline void response::clear_validate_block_succeeded()\n{\n  if (has_validate_block_succeeded())\n  {\n    response_type_.validate_block_succeeded_ = false;\n    clear_has_response_type();\n  }\n}\ninline bool response::validate_block_succeeded() const\n{\n  if (has_validate_block_succeeded())\n  {\n    return response_type_.validate_block_succeeded_;\n  }\n  return false;\n}\ninline void response::set_validate_block_succeeded(bool value)\n{\n  if (!has_validate_block_succeeded())\n  {\n    clear_response_type();\n    set_has_validate_block_succeeded();\n  }\n  response_type_.validate_block_succeeded_ = value;\n}\n\ninline bool response::has_response_type()\n{\n  return response_type_case() != RESPONSE_TYPE_NOT_SET;\n}\ninline void response::clear_has_response_type()\n{\n  _oneof_case_[0] = RESPONSE_TYPE_NOT_SET;\n}\ninline response::ResponseTypeCase response::response_type_case() const\n{\n  return response::ResponseTypeCase(_oneof_case_[0]);\n}\n\n// @@protoc_insertion_point(namespace_scope)\n\n} // namespace protocol\n} // namespace libbitcoin\n\n#ifndef SWIG\nnamespace google\n{\nnamespace protobuf\n{\n\ntemplate <>\nstruct is_proto_enum<::libbitcoin::protocol::filters> : ::google::protobuf::internal::true_type\n{\n};\ntemplate <>\ninline const EnumDescriptor *GetEnumDescriptor<::libbitcoin::protocol::filters>()\n{\n  return ::libbitcoin::protocol::filters_descriptor();\n}\ntemplate <>\nstruct is_proto_enum<::libbitcoin::protocol::tx_results> : ::google::protobuf::internal::true_type\n{\n};\ntemplate <>\ninline const EnumDescriptor *GetEnumDescriptor<::libbitcoin::protocol::tx_results>()\n{\n  return ::libbitcoin::protocol::tx_results_descriptor();\n}\ntemplate <>\nstruct is_proto_enum<::libbitcoin::protocol::locations> : ::google::protobuf::internal::true_type\n{\n};\ntemplate <>\ninline const EnumDescriptor *GetEnumDescriptor<::libbitcoin::protocol::locations>()\n{\n  return ::libbitcoin::protocol::locations_descriptor();\n}\n\n} // namespace protobuf\n} // namespace google\n#endif // SWIG\n\n// @@protoc_insertion_point(global_scope)\n\n#endif // PROTOBUF_bitcoin_2fprotocol_2finterface_2eproto__INCLUDED\n\n#endif"
  },
  {
    "path": "include/UChain/protocol/packet.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UC_PROTOCOL_PACKET\n#define UC_PROTOCOL_PACKET\n\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/protocol/define.hpp>\n#include <UChain/protocol/zmq/msg.hpp>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\n\nclass BCP_API packet\n{\n  public:\n    packet();\n\n    const data_chunk origin() const;\n    const data_chunk destination() const;\n    void set_destination(const data_chunk &destination);\n\n    bool receive(zmq::socket &socket);\n    ////bool receive(const std::shared_ptr<zmq::socket>& socket);\n    bool send(zmq::socket &socket);\n    ////bool send(const std::shared_ptr<zmq::socket>& socket);\n\n  protected:\n    virtual bool encode_payload(zmq::message &message) const = 0;\n    virtual bool decode_payload(const data_chunk &payload) = 0;\n\n  private:\n    data_chunk origin_;\n    data_chunk destination_;\n};\n\n} // namespace protocol\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/protocol/primitives.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifdef UC_VERSION4\n\n#ifndef UC_PROTOCOL_PRIMITIVES_HPP\n#define UC_PROTOCOL_PRIMITIVES_HPP\n\n#include <UChain/protocol/interface.pb.h>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\n\n// typedef std::vector<bc::protocol::filter> filter_list;\ntypedef google::protobuf::RepeatedPtrField<filter> filter_list;\n\n// typedef std::vector<bc::protocol::block_header> block_header_list;\ntypedef google::protobuf::RepeatedPtrField<block_header> block_header_list;\n\n// typedef std::vector<bc::protocol::tx_result> tx_result_list;\ntypedef google::protobuf::RepeatedPtrField<tx_result> tx_result_list;\n\n// typedef std::vector<bc::protocol::tx_hash_result> transaction_hash_result_list;\ntypedef google::protobuf::RepeatedPtrField<tx_hash_result> transaction_hash_result_list;\n\n// typedef std::vector<bc::protocol::utxo_result> utxo_result_list;\ntypedef google::protobuf::RepeatedPtrField<utxo_result> utxo_result_list;\n\n} // namespace protocol\n} // namespace libbitcoin\n\n#endif\n\n#endif"
  },
  {
    "path": "include/UChain/protocol/request_packet.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifdef UC_VERSION4\n\n#ifndef UC_PROTOCOL_REQUEST_PACKET\n#define UC_PROTOCOL_REQUEST_PACKET\n\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/protocol/define.hpp>\n#include <UChain/protocol/interface.pb.h>\n#include <UChain/protocol/packet.hpp>\n#include <UChain/protocol/zmq/msg.hpp>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\n\nclass BCP_API request_packet\n    : public packet\n{\n  public:\n    request_packet();\n\n    std::shared_ptr<request> get_request() const;\n    void set_request(std::shared_ptr<request> request);\n\n  protected:\n    virtual bool encode_payload(zmq::message &message) const;\n    virtual bool decode_payload(const data_chunk &payload);\n\n  private:\n    std::shared_ptr<request> request_;\n};\n\n} // namespace protocol\n} // namespace libbitcoin\n\n#endif\n\n#endif\n"
  },
  {
    "path": "include/UChain/protocol/response_packet.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifdef UC_VERSION4\n\n#ifndef UC_PROTOCOL_RESPONSE_PACKET\n#define UC_PROTOCOL_RESPONSE_PACKET\n\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/protocol/define.hpp>\n#include <UChain/protocol/interface.pb.h>\n#include <UChain/protocol/packet.hpp>\n#include <UChain/protocol/zmq/msg.hpp>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\n\nclass BCP_API response_packet\n    : public packet\n{\n  public:\n    response_packet();\n\n    std::shared_ptr<response> get_response() const;\n    void set_response(std::shared_ptr<response> response);\n\n  protected:\n    virtual bool encode_payload(zmq::message &message) const;\n    virtual bool decode_payload(const data_chunk &payload);\n\n  private:\n    std::shared_ptr<response> response_;\n};\n\n} // namespace protocol\n} // namespace libbitcoin\n\n#endif\n\n#endif\n"
  },
  {
    "path": "include/UChain/protocol/version.hpp",
    "content": "///////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 2014-2018 libbitcoin-protocol developers (see COPYING).\n//\n//        GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY\n//\n///////////////////////////////////////////////////////////////////////////////\n#ifndef UC_PROTOCOL_VERSION_HPP\n#define UC_PROTOCOL_VERSION_HPP\n\n/**\n * The semantic version of this repository as: [major].[minor].[patch]\n * For interpretation of the versioning scheme see: http://semver.org\n */\n\n#define UC_PROTOCOL_VERSION \"0.0.6\"\n#define UC_PROTOCOL_MAJOR_VERSION 0\n#define UC_PROTOCOL_MINOR_VERSION 0\n#define UC_PROTOCOL_PATCH_VERSION 6\n\n#endif\n"
  },
  {
    "path": "include/UChain/protocol/zmq/authenticator.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_PROTOCOL_ZMQ_AUTHENTICATOR_HPP\n#define UC_PROTOCOL_ZMQ_AUTHENTICATOR_HPP\n\n#include <memory>\n#include <functional>\n#include <future>\n#include <string>\n#include <unordered_map>\n#include <unordered_set>\n#include <UChain/coin.hpp>\n#include <UChain/protocol/define.hpp>\n#include <UChain/protocol/zmq/context.hpp>\n#include <UChain/protocol/zmq/socket.hpp>\n#include <UChain/protocol/zmq/worker.hpp>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\nnamespace zmq\n{\n\n/// This class is thread safe.\nclass BCP_API authenticator\n    : public worker\n{\n  public:\n    /// A shared authenticator pointer.\n    typedef std::shared_ptr<authenticator> ptr;\n\n    /// The fixed inprocess authentication endpoint.\n    static const config::endpoint endpoint;\n\n    /// There may be only one authenticator per process.\n    authenticator(threadpool &threadpool);\n\n    /// Stop the router.\n    virtual ~authenticator();\n\n    /// Expose the authenticated context.\n    operator context &();\n\n    /// Start the ZAP router for the context.\n    virtual bool start() override;\n\n    /// Stop the router (optional).\n    virtual bool stop() override;\n\n    /// This must be called on the socket thread, empty domain allowed.\n    /// Set secure false to enable NULL mechanism, otherwise curve is required.\n    /// By not applying this method authentication is bypassed altogether.\n    /// Apply authentication to the socket for the given arbitrary domain.\n    virtual bool apply(socket &socket, const std::string &domain, bool secure);\n\n    /// Set the server private key (required for curve security).\n    virtual void set_private_key(const config::sodium &private_key);\n\n    /// Allow clients with the following public keys (whitelist).\n    virtual void allow(const hash_digest &public_key);\n\n    /// Allow clients with the following ip addresses (whitelist).\n    virtual void allow(const config::authority &address);\n\n    /// Allow clients with the following ip addresses (blacklist).\n    virtual void deny(const config::authority &address);\n\n  protected:\n    void work() override;\n\n  private:\n    bool allowed_address(const std::string &address) const;\n    bool allowed_key(const hash_digest &public_key) const;\n    bool allowed_weak(const std::string &domain) const;\n\n    // This is thread safe.\n    context context_;\n\n    // These are protected by mutex.\n    bool require_address_;\n    config::sodium private_key_;\n    std::unordered_set<hash_digest> keys_;\n    std::unordered_set<std::string> weak_domains_;\n    std::unordered_map<std::string, bool> adresses_;\n    mutable shared_mutex mutex_;\n};\n\n} // namespace zmq\n} // namespace protocol\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/protocol/zmq/certificate.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_PROTOCOL_ZMQ_CERTIFICATE_HPP\n#define UC_PROTOCOL_ZMQ_CERTIFICATE_HPP\n\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/protocol/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\nnamespace zmq\n{\n\n/// This class is not thread safe.\n/// A simplified \"certificate\" class to manage a curve key pair.\n/// If valid the class always retains a consistent key pair.\nclass BCP_API certificate\n{\n  public:\n    /// Construct an arbitary keypair as a new certificate.\n    /// This always reduces keyspace, disallowing '#' in text encoding.\n    /// Use certificate({ null_hash }) to allow full key space.\n    certificate();\n\n    /// Construct a certificate from private key (generates public key).\n    /// This generates an arbitary key pair if the parameter is uninitialized.\n    certificate(const config::sodium &private_key);\n\n    /// True if the certificate is valid.\n    operator const bool() const;\n\n    /// The public key base85 text.\n    const config::sodium &public_key() const;\n\n    /// The private key base85 text.\n    const config::sodium &private_key() const;\n\n  protected:\n    static bool derive(config::sodium &out_public,\n                       const config::sodium &private_key);\n    static bool create(config::sodium &out_public,\n                       config::sodium &out_private, bool setting);\n\n  private:\n    config::sodium public_;\n    config::sodium private_;\n};\n\n} // namespace zmq\n} // namespace protocol\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/protocol/zmq/context.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_PROTOCOL_ZMQ_CONTEXT_HPP\n#define UC_PROTOCOL_ZMQ_CONTEXT_HPP\n\n#include <cstdint>\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/protocol/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\nnamespace zmq\n{\n\n/// This class is thread safe.\nclass BCP_API context\n    : public enable_shared_from_base<context>\n{\n  public:\n    /// A shared context pointer.\n    typedef std::shared_ptr<context> ptr;\n\n    /// Construct a context.\n    context(bool started = true);\n\n    /// This class is not copyable.\n    context(const context &) = delete;\n    void operator=(const context &) = delete;\n\n    /// Blocks until all child sockets are closed.\n    /// Stops all child socket activity by closing the zeromq context.\n    virtual ~context();\n\n    /// True if the context is valid and started.\n    operator const bool() const;\n\n    /// The underlying zeromq context.\n    void *self();\n\n    /// Create the zeromq context.\n    virtual bool start();\n\n    /// Blocks until all child sockets are closed.\n    /// Stops all child socket activity by closing the zeromq context.\n    virtual bool stop();\n\n  private:\n    // The context pointer is protected by mutex.\n    void *self_;\n    mutable shared_mutex mutex_;\n};\n\n} // namespace zmq\n} // namespace protocol\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/protocol/zmq/frame.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_PROTOCOL_ZMQ_FRAME_HPP\n#define UC_PROTOCOL_ZMQ_FRAME_HPP\n\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/protocol/define.hpp>\n#include <UChain/protocol/zmq/socket.hpp>\n#include <UChain/protocol/zmq/zeromq.hpp>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\nnamespace zmq\n{\n\n/// This class is not thread safe.\nclass BCP_API frame\n    : public enable_shared_from_base<frame>\n{\n  public:\n    /// A shared frame pointer.\n    typedef std::shared_ptr<frame> ptr;\n\n    /// Construct a frame with no payload (for receiving).\n    frame();\n\n    /// Construct a frame with the specified payload (for sending).\n    frame(const data_chunk &data);\n\n    /// This class is not copyable.\n    frame(const frame &) = delete;\n    void operator=(const frame &) = delete;\n\n    /// Free the frame's allocated memory.\n    virtual ~frame();\n\n    /// True if the construction was successful.\n    operator const bool() const;\n\n    /// True if there is more data to receive.\n    bool more() const;\n\n    /// The initialized or received payload of the frame.\n    data_chunk payload();\n\n    /// Must be called on the socket thread.\n    /// Receive a frame on the socket.\n    code receive(socket &socket);\n\n    /// Must be called on the socket thread.\n    /// Send a frame on the socket.\n    code send(socket &socket, bool more);\n\n  private:\n    // zmq_msg_t alias, keeps zmq.h out of our headers.\n    typedef union {\n        unsigned char alignment[64];\n        void *pointer;\n    } zmq_msg;\n\n    static bool initialize(zmq_msg &message, const data_chunk &data);\n\n    bool set_more(socket &socket);\n    bool destroy();\n\n    bool more_;\n    const bool valid_;\n    zmq_msg message_;\n};\n\n} // namespace zmq\n} // namespace protocol\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/protocol/zmq/identifiers.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_PROTOCOL_ZMQ_IDENTIFIER_HPP\n#define UC_PROTOCOL_ZMQ_IDENTIFIER_HPP\n\n#include <cstdint>\n#include <vector>\n#include <UChain/protocol/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\nnamespace zmq\n{\n\n/// A locally unique idenfitier for this socket.\ntypedef intptr_t identifier;\n\n/// An indicator for a set of socket idenfitiers.\nclass BCP_API identifiers\n{\n    // Allow poller to push identifiers.\n    friend class poller;\n\n  public:\n    /// True if the result set contains no identifiers.\n    bool empty() const;\n\n    /// True if the result set contains the identifier.\n    bool contains(identifier value) const;\n\n  protected:\n    virtual void push(const void *socket);\n\n    std::vector<identifier> ids_;\n};\n\n} // namespace zmq\n} // namespace protocol\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/protocol/zmq/poller.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_PROTOCOL_ZMQ_POLLER_HPP\n#define UC_PROTOCOL_ZMQ_POLLER_HPP\n\n#include <algorithm>\n#include <cstdint>\n#include <memory>\n#include <vector>\n#include <UChain/protocol/define.hpp>\n#include <UChain/protocol/zmq/identifiers.hpp>\n#include <UChain/protocol/zmq/socket.hpp>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\nnamespace zmq\n{\n\n/// This class is thread safe except as noted.\nclass BCP_API poller\n    : public enable_shared_from_base<poller>\n{\n  public:\n    /// A shared poller pointer.\n    typedef std::shared_ptr<poller> ptr;\n\n    /// Construct an empty poller (sockets must be added).\n    poller();\n\n    /// This class is not copyable.\n    poller(const poller &) = delete;\n    void operator=(const poller &) = delete;\n\n    /// True if the timeout occurred.\n    bool expired() const;\n\n    /// True if the connection is closed.\n    bool terminated() const;\n\n    /// Add a socket to be polled.\n    void add(socket &sock);\n\n    /// Remove all sockets from the poller.\n    void clear();\n\n    /// This must be called on the socket thread.\n    /// Wait one second for any socket to receive.\n    identifiers wait();\n\n    /// This must be called on the socket thread.\n    /// Wait specified time for any socket to receive, -1 is forever.\n    identifiers wait(int32_t timeout_milliseconds);\n\n  private:\n    // zmq_pollitem_t alias, keeps zmq.h out of our headers.\n    typedef struct\n    {\n        void *socket;\n        file_descriptor fd;\n        short events;\n        short revents;\n    } zmq_pollitem;\n\n    typedef std::vector<zmq_pollitem> pollers;\n\n    // These values are protected by mutex.\n    bool expired_;\n    bool terminated_;\n    pollers pollers_;\n    mutable shared_mutex mutex_;\n};\n\n} // namespace zmq\n} // namespace protocol\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/protocol/zmq/socket.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_PROTOCOL_ZMQ_SOCKET_HPP\n#define UC_PROTOCOL_ZMQ_SOCKET_HPP\n\n#include <cstdint>\n#include <memory>\n#include <string>\n#include <UChain/protocol/define.hpp>\n#include <UChain/protocol/zmq/certificate.hpp>\n#include <UChain/protocol/zmq/context.hpp>\n#include <UChain/protocol/zmq/identifiers.hpp>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\nnamespace zmq\n{\n\nclass message;\nclass authenticator;\n\n/// This class is thread safe except as noted.\n/// Because the socket is only set on construct, sockets are not restartable.\nclass BCP_API socket\n    : public enable_shared_from_base<socket>\n{\n  public:\n    /// The full set of socket roles defined by zeromq.\n    enum class role\n    {\n        pair,\n        publisher,\n        subscriber,\n        requester,\n        replier,\n        dealer,\n        router,\n        puller,\n        pusher,\n        extended_publisher,\n        extended_subscriber,\n        streamer\n    };\n\n    /// A shared socket pointer.\n    typedef std::shared_ptr<socket> ptr;\n\n    /// Construct a socket from an existing zeromq socket.\n    socket(void *zmq_socket);\n\n    /// Construct a socket of the given context and role.\n    socket(context &context, role socket_role);\n\n    /// This class is not copyable.\n    socket(const socket &) = delete;\n    void operator=(const socket &) = delete;\n\n    /// Close the socket.\n    /// The object must be destroyed on the socket thread if not stopped.\n    virtual ~socket();\n\n    /// This must be called on the socket thread.\n    /// Close the socket (optional, must close or destroy before context stop).\n    virtual bool stop();\n\n    /// True if the socket is valid.\n    operator const bool() const;\n\n    /// The underlying zeromq socket.\n    void *self();\n\n    /// An opaue locally unique idenfier, valid after stop.\n    identifier id() const;\n\n    /// This must be called on the socket thread.\n    /// Bind the socket to the specified local address.\n    code bind(const config::endpoint &address);\n\n    /// This must be called on the socket thread.\n    /// Connect the socket to the specified remote address.\n    code connect(const config::endpoint &address);\n\n    /// This must be called on the socket thread.\n    /// Sets the domain for ZAP (ZMQ RFC 27) authentication.\n    bool set_authentication_domain(const std::string &domain);\n\n    /// This must be called on the socket thread.\n    /// Configure the socket as a curve server (also set the secrety key).\n    bool set_curve_server();\n\n    /// This must be called on the socket thread.\n    /// Configure the socket as client to the curve server.\n    bool set_curve_client(const config::sodium &server_public_key);\n\n    /// This must be called on the socket thread.\n    /// Apply the specified public key to the socket.\n    bool set_public_key(const config::sodium &key);\n\n    /// This must be called on the socket thread.\n    /// Apply the specified private key to the socket.\n    bool set_private_key(const config::sodium &key);\n\n    /// This must be called on the socket thread.\n    /// Apply the keys of the specified certificate to the socket.\n    bool set_certificate(const certificate &certificate);\n\n    /// Send a message on this socket.\n    code send(message &packet);\n\n    /// Receive a message from this socket.\n    code receive(message &packet);\n\n  private:\n    static int to_socket_type(role socket_role);\n\n    bool set(int32_t option, int32_t value);\n    bool set(int32_t option, const std::string &value);\n\n    // This is protected by mutex.\n    void *self_;\n    mutable shared_mutex mutex_;\n\n    const identifier identifier_;\n    const int32_t send_buffer_;\n    const int32_t receive_buffer_;\n};\n\n} // namespace zmq\n} // namespace protocol\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/protocol/zmq/worker.hpp",
    "content": "/*\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_PROTOCOL_ZMQ_WORKER_HPP\n#define UC_PROTOCOL_ZMQ_WORKER_HPP\n\n#include <atomic>\n#include <memory>\n#include <future>\n#include <UChain/coin.hpp>\n#include <UChain/protocol/define.hpp>\n#include <UChain/protocol/zmq/socket.hpp>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\nnamespace zmq\n{\n\n/// This class is thread safe.\nclass BCP_API worker\n{\n  public:\n    /// A shared worker pointer.\n    typedef std::shared_ptr<worker> ptr;\n\n    /// Construct a worker.\n    worker(threadpool &pool);\n\n    /// This class is not copyable.\n    worker(const worker &) = delete;\n    void operator=(const worker &) = delete;\n\n    /// Stop the worker.\n    virtual ~worker();\n\n    /// Start the worker.\n    virtual bool start();\n\n    /// Stop the worker (optional).\n    virtual bool stop();\n\n  protected:\n    bool stopped();\n    bool started(bool result);\n    bool finished(bool result);\n    bool forward(socket &from, socket &to);\n    void relay(socket &left, socket &right);\n\n    virtual void work() = 0;\n\n  private:\n    // These are protected by mutex.\n    dispatcher dispatch_;\n    std::atomic<bool> stopped_;\n    std::promise<bool> started_;\n    std::promise<bool> finished_;\n    mutable shared_mutex mutex_;\n};\n\n} // namespace zmq\n} // namespace protocol\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/protocol/zmq/zeromq.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_PROTOCOL_ZMQ_ZEROMQ_HPP\n#define UC_PROTOCOL_ZMQ_ZEROMQ_HPP\n\n#include <UChain/coin.hpp>\n#include <UChain/protocol/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\nnamespace zmq\n{\n\ncode BCP_API get_last_error();\n\n} // namespace zmq\n} // namespace protocol\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChain/protocol.hpp",
    "content": "///////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 2014-2018 libbitcoin-protocol developers (see COPYING).\n//\n//        GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY\n//\n///////////////////////////////////////////////////////////////////////////////\n#ifndef UC_PROTOCOL_HPP\n#define UC_PROTOCOL_HPP\n\n/**\n * API Users: Include only this header. Direct use of other headers is fragile\n * and unsupported as header organization is subject to change.\n *\n * Maintainers: Do not include this header internal to this library.\n */\n\n#include <UChain/coin.hpp>\n#include <UChain/protocol/converter.hpp>\n#include <UChain/protocol/define.hpp>\n#include <UChain/protocol/interface.pb.h>\n#include <UChain/protocol/packet.hpp>\n#include <UChain/protocol/primitives.hpp>\n#include <UChain/protocol/request_packet.hpp>\n#include <UChain/protocol/response_packet.hpp>\n#include <UChain/protocol/version.hpp>\n#include <UChain/protocol/zmq/authenticator.hpp>\n#include <UChain/protocol/zmq/certificate.hpp>\n#include <UChain/protocol/zmq/context.hpp>\n#include <UChain/protocol/zmq/frame.hpp>\n#include <UChain/protocol/zmq/identifiers.hpp>\n#include <UChain/protocol/zmq/msg.hpp>\n#include <UChain/protocol/zmq/poller.hpp>\n#include <UChain/protocol/zmq/socket.hpp>\n#include <UChain/protocol/zmq/worker.hpp>\n#include <UChain/protocol/zmq/zeromq.hpp>\n\n#endif\n"
  },
  {
    "path": "include/UChainApp/ucd/config.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SERVER_CONFIGURATION_HPP\n#define UC_SERVER_CONFIGURATION_HPP\n\n#include <UChain/node.hpp>\n#include <UChainApp/ucd/define.hpp>\n#include <UChainApp/ucd/settings.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\n// Not localizable.\n#define BS_HELP_VARIABLE \"help\"\n#define BS_SETTINGS_VARIABLE \"settings\"\n#define BS_VERSION_VARIABLE \"version\"\n#define BS_DAEMON_VARIABLE \"daemon\"\n#define BS_TESTNET_VARIABLE \"testnet\"\n#define BS_DATADIR_VARIABLE \"datadir\"\n#define BS_UI_VARIABLE \"ui\"\n\n// This must be lower case but the env var part can be any case.\n#define BS_CONFIG_VARIABLE \"config\"\n\n// This must match the case of the env var.\n#define BS_ENVIRONMENT_VARIABLE_PREFIX \"BS_\"\n\n/// Full server node configuration, thread safe.\nclass BCS_API configuration\n    : public node::configuration\n{\npublic:\n  configuration(bc::settings context);\n  configuration(const configuration &other);\n\n  /// Settings.\n  server::settings server;\n};\n\n} // namespace server\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainApp/ucd/define.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SERVER_DEFINE_HPP\n#define UC_SERVER_DEFINE_HPP\n\n#include <UChain/coin.hpp>\n\n// We use the generic helper definitions in libbitcoin to define BCS_API\n// and BCS_INTERNAL. BCS_API is used for the public API symbols. It either DLL\n// imports or DLL exports (or does nothing for static build) BCS_INTERNAL is\n// used for non-api symbols.\n\n#if defined BCS_STATIC\n#define BCS_API\n#define BCS_INTERNAL\n#elif defined BCS_DLL\n#define BCS_API BC_HELPER_DLL_EXPORT\n#define BCS_INTERNAL BC_HELPER_DLL_LOCAL\n#else\n#define BCS_API BC_HELPER_DLL_IMPORT\n#define BCS_INTERNAL BC_HELPER_DLL_LOCAL\n#endif\n\n// Log name.\n#define LOG_SERVER \"ucd\"\n\n// Avoid namespace conflict between boost::placeholders and std::placeholders.\n#define BOOST_BIND_NO_PLACEHOLDERS\n\n// Include boost only here, so placeholders exclusion works.\n#include <boost/filesystem.hpp>\n#include <boost/iostreams/stream.hpp>\n#include <boost/program_options.hpp>\n#include <boost/thread.hpp>\n\n#endif\n"
  },
  {
    "path": "include/UChainApp/ucd/interface/address.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SERVER_ADDRESS_HPP\n#define UC_SERVER_ADDRESS_HPP\n\n#include <UChainApp/ucd/define.hpp>\n#include <UChainApp/ucd/messages/msg.hpp>\n#include <UChainApp/ucd/server_node.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\n/// Address interface.\n/// Class and method names are published and mapped to the zeromq interface.\nclass BCS_API address\n{\n  public:\n    /// Fetch the blockchain and transaction pool history of a payment address.\n    static void fetch_history2(server_node &node,\n                               const message &request, send_handler handler);\n\n    /// Alias for subscribe, preserved for backward compatability.\n    static void renew(server_node &node, const message &request,\n                      send_handler handler);\n\n    /// Subscribe to payment or stealth address notifications by prefix.\n    static void subscribe(server_node &node, const message &request,\n                          send_handler handler);\n\n    /// Subscribe to payment and stealth address notifications by prefix.\n    static void subscribe2(server_node &node, const message &request,\n                           send_handler handler);\n\n    /// Unsubscribe to payment and stealth address notifications by prefix.\n    static void unsubscribe2(server_node &node, const message &request,\n                             send_handler handler);\n\n  private:\n    static bool unwrap_subscribe_args(binary &prefix_filter,\n                                      chain::subscribe_type &type, const message &request);\n\n    static bool unwrap_subscribe2_args(binary &prefix_filter,\n                                       const message &request);\n};\n\n} // namespace server\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainApp/ucd/interface/blockchain.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SERVER_BLOCKCHAIN_HPP\n#define UC_SERVER_BLOCKCHAIN_HPP\n\n#include <cstddef>\n#include <UChain/blockchain.hpp>\n#include <UChainApp/ucd/define.hpp>\n#include <UChainApp/ucd/messages/msg.hpp>\n#include <UChainApp/ucd/server_node.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\n/// Blockchain interface.\n/// These queries results do NOT include transaction pool information.\n/// Class and method names are published and mapped to the zeromq interface.\nclass BCS_API blockchain\n{\n  public:\n    /// Fetch the blockchain history of a payment address.\n    static void fetch_history(server_node &node,\n                              const message &request, send_handler handler);\n\n    /// Fetch a transaction from the blockchain by its hash.\n    static void fetch_transaction(server_node &node,\n                                  const message &request, send_handler handler);\n\n    /// Fetch the current height of the blockchain.\n    static void fetch_last_height(server_node &node,\n                                  const message &request, send_handler handler);\n\n    /// Fetch a block header by hash or height (conditional serialization).\n    static void fetch_block_header(server_node &node,\n                                   const message &request, send_handler handler);\n\n    /// Fetch tx hashes of block by hash or height (conditional serialization).\n    static void fetch_block_transaction_hashes(server_node &node,\n                                               const message &request, send_handler handler);\n\n    /// Fetch the block index of a transaction and the height of its block.\n    static void fetch_transaction_index(server_node &node,\n                                        const message &request, send_handler handler);\n\n    /// Fetch the inpoint which is spent by the specified output.\n    static void fetch_spend(server_node &node,\n                            const message &request, send_handler handler);\n\n    /// Fetch the height of a block by its hash.\n    static void fetch_block_height(server_node &node,\n                                   const message &request, send_handler handler);\n\n    /// Fetch the history of a stealth address by its prefix filter.\n    static void fetch_stealth(server_node &node,\n                              const message &request, send_handler handler);\n\n    /// Fetch the transactions of a stealth address by its prefix filter.\n    static void fetch_stealth2(server_node &node,\n                               const message &request, send_handler handler);\n\n  private:\n    static void last_height_fetched(const code &ec, size_t last_height,\n                                    const message &request, send_handler handler);\n\n    static void fetch_block_header_by_hash(server_node &node,\n                                           const message &request, send_handler handler);\n\n    static void fetch_block_header_by_height(server_node &node,\n                                             const message &request, send_handler handler);\n\n    static void fetch_block_header_by_height_range(server_node &node,\n                                                   const message &request, send_handler handler);\n\n    static void block_header_fetched(const code &ec,\n                                     const chain::header &block, const message &request,\n                                     send_handler handler);\n\n    static void block_headers_fetched(const code &ec,\n                                      const std::vector<chain::header> &blocks, const message &request,\n                                      send_handler handler);\n\n    static void fetch_block_transaction_hashes_by_hash(server_node &node,\n                                                       const message &request, send_handler handler);\n\n    static void fetch_block_transaction_hashes_by_height(server_node &node,\n                                                         const message &request, send_handler handler);\n\n    static void block_transaction_hashes_fetched(const code &ec,\n                                                 const hash_list &hashes, const message &request,\n                                                 send_handler handler);\n\n    static void transaction_index_fetched(const code &ec, size_t block_height,\n                                          size_t index, const message &request, send_handler handler);\n\n    static void spend_fetched(const code &ec,\n                              const chain::input_point &inpoint, const message &request,\n                              send_handler handler);\n\n    static void block_height_fetched(const code &ec, size_t block_height,\n                                     const message &request, send_handler handler);\n\n    static void stealth_fetched(const code &ec,\n                                const chain::stealth_compact::list &stealth_results,\n                                const message &request, send_handler handler);\n\n    static void stealth_fetched2(const code &ec,\n                                 const chain::stealth_compact::list &stealth_results,\n                                 const message &request, send_handler handler);\n};\n\n} // namespace server\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainApp/ucd/interface/protocol.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SERVER_PROTOCOL_HPP\n#define UC_SERVER_PROTOCOL_HPP\n\n#include <cstddef>\n#include <UChainApp/ucd/define.hpp>\n#include <UChainApp/ucd/messages/msg.hpp>\n#include <UChainApp/ucd/server_node.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\n/// Protocol interface.\n/// Class and method names are published and mapped to the zeromq interface.\nclass BCS_API protocol\n{\n  public:\n    /// Broadcast a transaction to all connected peers.\n    static void broadcast_transaction(server_node &node,\n                                      const message &request, send_handler handler);\n\n    /// Determine the count of all connected peers.\n    static void total_connections(server_node &node,\n                                  const message &request, send_handler handler);\n\n  private:\n    static void handle_total_connections(size_t count,\n                                         const message &request, send_handler handler);\n};\n\n} // namespace server\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainApp/ucd/interface/tx_pool.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SERVER_TRANSACTION_POOL_HPP\n#define UC_SERVER_TRANSACTION_POOL_HPP\n\n#include <UChain/coin.hpp>\n#include <UChainApp/ucd/define.hpp>\n#include <UChainApp/ucd/messages/msg.hpp>\n#include <UChainApp/ucd/server_node.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\n/// Transaction pool interface.\n/// Class and method names are published and mapped to the zeromq interface.\nclass BCS_API tx_pool\n{\n  public:\n    /// Fetch a transaction from the transaction pool (only), by its hash.\n    static void fetch_transaction(server_node &node, const message &request,\n                                  send_handler handler);\n\n    /// Broadcast a transaction with penetration subscription.\n    static void broadcast(server_node &node, const message &request,\n                          send_handler handler);\n\n    /// Validate a transaction against the transaction pool and blockchain.\n    static void validate(server_node &node, const message &request,\n                         send_handler handler);\n\n  private:\n    static void handle_validated(const code &ec,\n                                 bc::message::tx_message::ptr tx,\n                                 const chain::point::indexes &unconfirmed, const message &request,\n                                 send_handler handler);\n};\n\n} // namespace server\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainApp/ucd/messages/route.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SERVER_ROUTE\n#define UC_SERVER_ROUTE\n\n#include <cstddef>\n#include <string>\n#include <boost/functional/hash_fwd.hpp>\n#include <UChain/coin.hpp>\n#include <UChainApp/ucd/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\n/// This class is not thread safe.\n/// The route is fixed in compliance with v2/v3 limitations.\nclass BCS_API route\n{\n  public:\n    /// Construct a route.\n    route();\n\n    /// A printable address for logging only.\n    std::string display() const;\n\n    /// Equality operator.\n    bool operator==(const route &other) const;\n\n    /// The message requires a secure port.\n    bool secure;\n\n    /// The message route is delimited using an empty frame.\n    bool delimited;\n\n    /// The first address.\n    data_chunk address1;\n\n    /// The second address.\n    data_chunk address2;\n};\n\n} // namespace server\n} // namespace libbitcoin\n\nnamespace std\n{\ntemplate <>\nstruct hash<bc::server::route>\n{\n    size_t operator()(const bc::server::route &value) const\n    {\n        size_t seed = 0;\n        boost::hash_combine(seed, value.secure);\n        ////boost::hash_combine(seed, value.delimited);\n        boost::hash_combine(seed, value.address1);\n        ////boost::hash_combine(seed, value.address2);\n        return seed;\n    }\n};\n} // namespace std\n\n#endif\n"
  },
  {
    "path": "include/UChainApp/ucd/parser.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SERVER_PARSER_HPP\n#define UC_SERVER_PARSER_HPP\n\n#include <ostream>\n#include <UChain/coin.hpp>\n#include <UChainApp/ucd/define.hpp>\n#include <UChainApp/ucd/config.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\n/// Parse configurable values from environment variables, settings file, and\n/// command line positional and non-positional options.\nclass BCS_API parser\n    : public config::parser\n{\npublic:\n  parser(bc::settings context);\n  parser(const configuration defaults);\n\n  /// Parse all configuration into member settings.\n  virtual bool parse(int argc, const char *argv[], std::ostream &error);\n\n  /// Load command line options (named).\n  virtual options_metadata load_options();\n\n  /// Load command line arguments (positional).\n  virtual arguments_metadata load_arguments();\n\n  /// Load configuration file settings.\n  virtual options_metadata load_settings();\n\n  /// Load environment variable settings.\n  virtual options_metadata load_environment();\n\n  /// The populated configuration settings values.\n  configuration configured;\n};\n\n} // namespace server\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainApp/ucd/server_node.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SERVER_SERVER_NODE_HPP\n#define UC_SERVER_SERVER_NODE_HPP\n\n#include <cstdint>\n#include <atomic>\n#include <memory>\n#include <UChain/node.hpp>\n#include <UChain/protocol.hpp>\n#include <UChainApp/ucd/config.hpp>\n#include <UChainApp/ucd/define.hpp>\n#include <UChainApp/ucd/messages/msg.hpp>\n#include <UChainApp/ucd/messages/route.hpp>\n#include <UChainApp/ucd/services/block_service.hpp>\n#include <UChainApp/ucd/services/heartbeat_service.hpp>\n#include <UChainApp/ucd/services/query_service.hpp>\n#include <UChainApp/ucd/services/tx_service.hpp>\n#include <UChainApp/ucd/utility/authenticator.hpp>\n#include <UChainApp/ucd/workers/notification_worker.hpp>\n#include <UChainService/txs/utility/path.hpp>\n#include <UChainService/consensus/miner.hpp>\n\n#include <boost/shared_ptr.hpp>\n\nnamespace mgbubble\n{\nclass RestServ;\nclass WsPushServ;\n} // namespace mgbubble\nnamespace libbitcoin\n{\nnamespace server\n{\n\nclass notification_worker;\n\nclass BCS_API server_node\n    : public node::p2p_node\n{\n  public:\n    typedef std::shared_ptr<server_node> ptr;\n\n    /// Compute the minimum threadpool size required to run the server.\n    static uint32_t threads_required(const configuration &configuration);\n\n    /// Construct a server node.\n    server_node(const configuration &configuration);\n\n    /// Ensure all threads are coalesced.\n    virtual ~server_node();\n\n    // Properties.\n    // ----------------------------------------------------------------------------\n\n    /// Server configuration settings.\n    virtual const settings &server_settings() const;\n\n    // Run sequence.\n    // ------------------------------------------------------------------------\n\n    /// Synchronize the blockchain and then begin long running sessions,\n    /// call from start result handler. Call base method to skip sync.\n    virtual void run(result_handler handler) override;\n\n    // Shutdown.\n    // ------------------------------------------------------------------------\n\n    /// Idempotent call to signal work stop, start may be reinvoked after.\n    /// Returns the result of file save operation.\n    virtual bool stop() override;\n\n    /// Blocking call to coalesce all work and then terminate all threads.\n    /// Call from thread that constructed this class, or don't call at all.\n    /// This calls stop, and start may be reinvoked after calling this.\n    virtual bool close() override;\n\n    // Notification.\n    // ------------------------------------------------------------------------\n\n    /// Subscribe to address (including stealth) prefix notifications.\n    /// Stealth prefix is limited to 32 bits, address prefix to 256 bits.\n    virtual void subscribe_address(const route &reply_to, uint32_t id,\n                                   const binary &prefix_filter, chain::subscribe_type type);\n\n    /// Subscribe to transaction penetration notifications.\n    virtual void subscribe_penetration(const route &reply_to, uint32_t id,\n                                       const hash_digest &tx_hash);\n\n    /// Get miner.\n    virtual consensus::miner &miner();\n\n    bool is_blockchain_sync() const { return under_blockchain_sync_.load(std::memory_order_relaxed); }\n\n  private:\n    void handle_running(const code &ec, result_handler handler);\n\n    bool start_services();\n    bool start_authenticator();\n    bool start_query_services();\n    bool start_heartbeat_services();\n    bool start_block_services();\n    bool start_tx_services();\n    bool start_query_workers(bool secure);\n\n    bool open_ui();\n\n    std::atomic<bool> under_blockchain_sync_;\n\n    const configuration &configuration_;\n    static boost::filesystem::path webpage_path_;\n\n    consensus::miner miner_;\n    boost::shared_ptr<mgbubble::RestServ> rest_server_;\n    boost::shared_ptr<mgbubble::WsPushServ> push_server_;\n    // These are thread safe.\n    authenticator authenticator_;\n    query_service secure_query_service_;\n    query_service public_query_service_;\n    heartbeat_service secure_heartbeat_service_;\n    heartbeat_service public_heartbeat_service_;\n    block_service secure_block_service_;\n    block_service public_block_service_;\n    tx_service secure_tx_service_;\n    tx_service public_tx_service_;\n    notification_worker secure_notification_worker_;\n    notification_worker public_notification_worker_;\n};\n\n} // namespace server\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainApp/ucd/services/block_service.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SERVER_BLOCK_SERVICE_HPP\n#define UC_SERVER_BLOCK_SERVICE_HPP\n\n#include <cstdint>\n#include <memory>\n#include <UChain/protocol.hpp>\n#include <UChainApp/ucd/define.hpp>\n#include <UChainApp/ucd/settings.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nclass server_node;\n\n// This class is thread safe.\n// Subscribe to block acceptances into the long chain.\nclass BCS_API block_service\n    : public bc::protocol::zmq::worker\n{\n  public:\n    typedef std::shared_ptr<block_service> ptr;\n\n    /// The fixed inprocess worker endpoints.\n    static const config::endpoint public_worker;\n    static const config::endpoint secure_worker;\n\n    /// Construct a block service.\n    block_service(bc::protocol::zmq::authenticator &authenticator,\n                  server_node &node, bool secure);\n\n    /// Start the service.\n    bool start() override;\n\n    /// Stop the service.\n    bool stop() override;\n\n  protected:\n    typedef bc::protocol::zmq::socket socket;\n\n    virtual bool bind(socket &xpub, socket &xsub);\n    virtual bool unbind(socket &xpub, socket &xsub);\n\n    // Implement the service.\n    virtual void work();\n\n  private:\n    typedef bc::message::block_msg::ptr block_ptr;\n    typedef bc::message::block_msg::ptr_list block_list;\n\n    bool handle_reorganization(const code &ec, uint64_t fork_point,\n                               const block_list &new_blocks, const block_list &);\n    void publish_blocks(uint32_t fork_point, const block_list &blocks);\n    void publish_block(socket &publisher, uint32_t height,\n                       const block_ptr block);\n\n    const bool secure_;\n    const server::settings &settings_;\n\n    // These are thread safe.\n    bc::protocol::zmq::authenticator &authenticator_;\n    server_node &node_;\n};\n\n} // namespace server\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainApp/ucd/services/heartbeat_service.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SERVER_HEARTBEAT_SERVICE_HPP\n#define UC_SERVER_HEARTBEAT_SERVICE_HPP\n\n#include <cstdint>\n#include <memory>\n#include <UChain/protocol.hpp>\n#include <UChainApp/ucd/define.hpp>\n#include <UChainApp/ucd/settings.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nclass server_node;\n\n// This class is thread safe.\n// Subscribe to a pulse from a dedicated service endpoint.\nclass BCS_API heartbeat_service\n    : public bc::protocol::zmq::worker\n{\n  public:\n    typedef std::shared_ptr<heartbeat_service> ptr;\n\n    /// Construct a heartbeat endpoint.\n    heartbeat_service(bc::protocol::zmq::authenticator &authenticator,\n                      server_node &node, bool secure);\n\n  protected:\n    typedef bc::protocol::zmq::socket socket;\n\n    virtual bool bind(socket &publisher);\n    virtual bool unbind(socket &publisher);\n\n    // Implement the service.\n    virtual void work();\n\n    // Publish the heartbeat (integrated worker).\n    void publish(uint32_t count, socket &socket);\n\n  private:\n    const server::settings &settings_;\n    const int32_t period_;\n    const bool secure_;\n\n    // This is thread safe.\n    bc::protocol::zmq::authenticator &authenticator_;\n};\n\n} // namespace server\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainApp/ucd/services/query_service.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SERVER_QUERY_SERVICE_HPP\n#define UC_SERVER_QUERY_SERVICE_HPP\n\n#include <memory>\n#include <UChain/protocol.hpp>\n#include <UChainApp/ucd/define.hpp>\n#include <UChainApp/ucd/settings.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nclass server_node;\n\n// This class is thread safe.\n// Submit queries and address subscriptions and receive address notifications.\nclass BCS_API query_service\n    : public bc::protocol::zmq::worker\n{\n  public:\n    typedef std::shared_ptr<query_service> ptr;\n\n    /// The fixed inprocess query and notify worker endpoints.\n    static const config::endpoint public_query;\n    static const config::endpoint secure_query;\n    static const config::endpoint public_notify;\n    static const config::endpoint secure_notify;\n\n    /// Construct a query service.\n    query_service(bc::protocol::zmq::authenticator &authenticator,\n                  server_node &node, bool secure);\n\n  protected:\n    typedef bc::protocol::zmq::socket socket;\n\n    virtual bool bind(socket &router, socket &query_dealer,\n                      socket &notify_dealer);\n    virtual bool unbind(socket &router, socket &query_dealer,\n                        socket &notify_dealer);\n\n    // Implement the service.\n    virtual void work();\n\n  private:\n    const bool secure_;\n    const server::settings &settings_;\n\n    // This is thread safe.\n    bc::protocol::zmq::authenticator &authenticator_;\n};\n\n} // namespace server\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainApp/ucd/services/tx_service.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SERVER_TRANSACTION_SERVICE_HPP\n#define UC_SERVER_TRANSACTION_SERVICE_HPP\n\n#include <memory>\n#include <UChain/protocol.hpp>\n#include <UChainApp/ucd/define.hpp>\n#include <UChainApp/ucd/settings.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nclass server_node;\n\n// This class is thread safe.\n// Subscribe to transaction acceptances into the transaction memory pool.\nclass BCS_API tx_service\n    : public bc::protocol::zmq::worker\n{\n  public:\n    typedef std::shared_ptr<tx_service> ptr;\n\n    /// The fixed inprocess worker endpoints.\n    static const config::endpoint public_worker;\n    static const config::endpoint secure_worker;\n\n    /// Construct a transaction service.\n    tx_service(bc::protocol::zmq::authenticator &authenticator,\n                        server_node &node, bool secure);\n\n    /// Start the service.\n    bool start() override;\n\n    /// Stop the service.\n    bool stop() override;\n\n  protected:\n    typedef bc::protocol::zmq::socket socket;\n\n    virtual bool bind(socket &xpub, socket &xsub);\n    virtual bool unbind(socket &xpub, socket &xsub);\n\n    // Implement the service.\n    virtual void work();\n\n  private:\n    typedef bc::chain::point::indexes index_list;\n\n    bool handle_transaction(const code &ec, const index_list &,\n                            bc::message::tx_message::ptr tx);\n    void publish_transaction(const chain::transaction &tx);\n\n    const bool secure_;\n    const server::settings &settings_;\n\n    // These are thread safe.\n    bc::protocol::zmq::authenticator &authenticator_;\n    server_node &node_;\n};\n\n} // namespace server\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainApp/ucd/settings.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SERVER_SETTINGS_HPP\n#define UC_SERVER_SETTINGS_HPP\n\n#include <cstdint>\n#include <string>\n#include <vector>\n#include <boost/filesystem.hpp>\n#include <UChain/node.hpp>\n#include <UChain/protocol.hpp>\n#include <UChainApp/ucd/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\n/// Common database configuration settings, properties not thread safe.\nclass BCS_API settings\n{\n  public:\n    settings();\n    settings(bc::settings context);\n\n    /// Properties.\n    uint16_t query_workers;\n    uint32_t heartbeat_interval_seconds;\n    uint32_t subscription_expiration_minutes;\n    uint32_t subscription_limit;\n    std::string mongoose_listen;\n    std::string websocket_listen;\n    std::string log_level;\n    bool administrator_required;\n    bool secure_only;\n    bool read_only;\n\n    bool query_service_enabled;\n    bool heartbeat_service_enabled;\n    bool block_service_enabled;\n    bool tx_service_enabled;\n    bool websocket_service_enabled;\n\n    config::endpoint public_query_endpoint;\n    config::endpoint public_heartbeat_endpoint;\n    config::endpoint public_block_endpoint;\n    config::endpoint public_transaction_endpoint;\n\n    config::endpoint secure_query_endpoint;\n    config::endpoint secure_heartbeat_endpoint;\n    config::endpoint secure_block_endpoint;\n    config::endpoint secure_transaction_endpoint;\n\n    config::sodium server_private_key;\n    config::sodium::list client_public_keys;\n    config::authority::list client_addresses;\n\n    /// Helpers.\n    asio::duration heartbeat_interval() const;\n    asio::duration subscription_expiration() const;\n};\n\n} // namespace server\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainApp/ucd/utility/address_key.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SERVER_ADDRESS_KEY_HPP\n#define UC_SERVER_ADDRESS_KEY_HPP\n\n#include <cstddef>\n#include <boost/functional/hash_fwd.hpp>\n#include <UChain/coin.hpp>\n#include <UChainApp/ucd/messages/route.hpp>\n#include <UChainApp/ucd/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nclass BCS_API address_key\n{\n  public:\n    address_key(const route &reply_to, const binary &prefix_filter);\n    bool operator==(const address_key &other) const;\n    const route &reply_to() const;\n    const binary &prefix_filter() const;\n\n  private:\n    const route &reply_to_;\n    const binary &prefix_filter_;\n};\n\n} // namespace server\n} // namespace libbitcoin\n\nnamespace std\n{\ntemplate <>\nstruct hash<bc::server::address_key>\n{\n    size_t operator()(const bc::server::address_key &value) const\n    {\n        // boost::hash_combine uses boost::hash declarations., but these\n        // are defined as std::hash (for use with std::map). So we must\n        // explicity perform the hash operation before combining.\n        const auto to = std::hash<bc::server::route>()(value.reply_to());\n        const auto filter = std::hash<bc::binary>()(value.prefix_filter());\n\n        size_t seed = 0;\n        boost::hash_combine(seed, to);\n        boost::hash_combine(seed, filter);\n        return seed;\n    }\n};\n} // namespace std\n\n#endif\n"
  },
  {
    "path": "include/UChainApp/ucd/utility/authenticator.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SERVER_SECURE_AUTHENTICATOR_HPP\n#define UC_SERVER_SECURE_AUTHENTICATOR_HPP\n\n#include <memory>\n#include <UChain/protocol.hpp>\n#include <UChainApp/ucd/define.hpp>\n#include <UChainApp/ucd/settings.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nclass server_node;\n\nclass BCS_API authenticator\n    : public bc::protocol::zmq::authenticator\n{\npublic:\n  typedef std::shared_ptr<authenticator> ptr;\n\n  /// Construct an instance of the authenticator.\n  authenticator(server_node &node);\n\n  /// This class is not copyable.\n  authenticator(const authenticator &) = delete;\n  void operator=(const authenticator &) = delete;\n\n  /// Apply authentication to the socket.\n  bool apply(bc::protocol::zmq::socket &socket, const std::string &domain,\n             bool secure);\n};\n\n} // namespace server\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainApp/ucd/utility/coredump.hpp",
    "content": "#ifndef CORE_DUMP_HPP\n#define CORE_DUMP_HPP\n#include <boost/format.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\n#ifdef _MSC_VER\n\n#include <Windows.h>\n#include <Dbghelp.h>\n#pragma comment(lib, \"Dbghelp.lib\")\n\nLONG WINAPI exp_filter(struct _EXCEPTION_POINTERS *pExp)\n{\n    SYSTEMTIME systime;\n    GetLocalTime(&systime);\n#ifdef UNICODE\n    boost::wformat fmt(L\".\\\\ucd%d%02d%02d%02d%02d%02d.dmp\");\n#else\n    boost::format fmt(\".\\\\ucd%d%02d%02d%02d%02d%02d.dmp\");\n#endif // UNICODE\n    fmt % systime.wYear % systime.wMonth % systime.wDay % systime.wHour %\n        systime.wMinute % systime.wSecond;\n    HANDLE hFile = ::CreateFile(\n        fmt.str().c_str(),\n        GENERIC_WRITE,\n        0,\n        NULL,\n        CREATE_ALWAYS,\n        FILE_ATTRIBUTE_NORMAL,\n        NULL);\n\n    if (INVALID_HANDLE_VALUE != hFile)\n    {\n        MINIDUMP_EXCEPTION_INFORMATION einfo;\n        einfo.ThreadId = ::GetCurrentThreadId();\n        einfo.ExceptionPointers = pExp;\n        einfo.ClientPointers = FALSE;\n\n        MiniDumpWriteDump(\n            ::GetCurrentProcess(),\n            ::GetCurrentProcessId(),\n            hFile,\n            MiniDumpWithFullMemory,\n            &einfo,\n            NULL,\n            NULL);\n        ::CloseHandle(hFile);\n    }\n\n    return EXCEPTION_EXECUTE_HANDLER;\n}\n#endif\n\n/// catch unhandle exception save to dump.\nvoid start_unhandled_exception_filter()\n{\n#ifdef _MSC_VER\n    ::SetUnhandledExceptionFilter(exp_filter);\n#endif\n}\n\n} //namespace server\n} //namespace libbitcoin\n#endif"
  },
  {
    "path": "include/UChainApp/ucd/utility/fetch_helpers.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SERVER_FETCH_HELPERS_HPP\n#define UC_SERVER_FETCH_HELPERS_HPP\n\n#include <cstddef>\n#include <cstdint>\n#include <UChain/coin.hpp>\n#include <UChainApp/ucd/define.hpp>\n#include <UChainApp/ucd/messages/msg.hpp>\n#include <UChainApp/ucd/server_node.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nstatic BC_CONSTEXPR size_t code_size = sizeof(uint32_t);\nstatic BC_CONSTEXPR size_t index_size = sizeof(uint32_t);\nstatic BC_CONSTEXPR size_t point_size = hash_size + sizeof(uint32_t);\n\n// fetch_history stuff\n\nbool BCS_API unwrap_fetch_history_args(bc::wallet::payment_address &address,\n                                       uint32_t &from_height, const message &request);\n\nvoid BCS_API send_history_result(const code &ec,\n                                 const chain::history_compact::list &history, const message &request,\n                                 send_handler handler);\n\n// fetch_transaction stuff\n\nbool BCS_API unwrap_fetch_transaction_args(hash_digest &hash,\n                                           const message &request);\n\nvoid BCS_API chain_transaction_fetched(const code &ec,\n                                       const chain::transaction &tx, const message &request,\n                                       send_handler handler);\n\nvoid BCS_API pool_transaction_fetched(const code &ec,\n                                      bc::message::tx_message::ptr tx, const message &request,\n                                      send_handler handler);\n\n} // namespace server\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainApp/ucd/version.hpp",
    "content": "///////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 2014-2018 libbitcoin-server developers (see COPYING).\n//\n//        GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY\n//\n///////////////////////////////////////////////////////////////////////////////\n#ifndef UC_SERVER_VERSION_HPP\n#define UC_SERVER_VERSION_HPP\n\n/**\n * The semantic version of this repository as: [major].[minor].[patch]\n * For interpretation of the versioning scheme see: http://semver.org\n */\n\n#define UC_SERVER_VERSION \"0.0.6\"\n#define UC_SERVER_MAJOR_VERSION 0\n#define UC_SERVER_MINOR_VERSION 0\n#define UC_SERVER_PATCH_VERSION 6\n\n#endif\n"
  },
  {
    "path": "include/UChainApp/ucd/workers/notification_worker.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SERVER_NOTIFICATION_WORKER_HPP\n#define UC_SERVER_NOTIFICATION_WORKER_HPP\n\n#include <cstdint>\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChainApp/ucd/define.hpp>\n#include <UChainApp/ucd/messages/msg.hpp>\n#include <UChainApp/ucd/messages/route.hpp>\n#include <UChainApp/ucd/settings.hpp>\n#include <UChainApp/ucd/utility/address_key.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nclass server_node;\n\n// This class is thread safe.\n// Provide address and stealth notifications to the query service.\nclass BCS_API notification_worker\n    : public bc::protocol::zmq::worker\n{\n  public:\n    typedef std::shared_ptr<notification_worker> ptr;\n\n    /// Construct an address worker.\n    notification_worker(bc::protocol::zmq::authenticator &authenticator,\n                        server_node &node, bool secure);\n\n    /// Start the worker.\n    bool start() override;\n\n    /// Stop the worker.\n    bool stop() override;\n\n    /// Subscribe to address and stealth prefix notifications.\n    virtual void subscribe_address(const route &reply_to, uint32_t id,\n                                   const binary &prefix_filter, chain::subscribe_type type);\n\n    /// Subscribe to transaction penetration notifications.\n    virtual void subscribe_penetration(const route &reply_to, uint32_t id,\n                                       const hash_digest &tx_hash);\n\n  protected:\n    typedef bc::protocol::zmq::socket socket;\n\n    virtual bool connect(socket &router);\n    virtual bool disconnect(socket &router);\n\n    // Implement the service.\n    virtual void work();\n\n  private:\n    typedef chain::point::indexes index_list;\n    typedef std::shared_ptr<uint8_t> sequence_ptr;\n    typedef bc::message::block_msg::ptr_list block_list;\n\n    typedef notifier<address_key, const code &,\n                     const bc::wallet::payment_address &, int32_t, const hash_digest &,\n                     const chain::transaction &>\n        payment_subscriber;\n    typedef notifier<address_key, const code &, uint32_t, uint32_t,\n                     const hash_digest &, const chain::transaction &>\n        stealth_subscriber;\n    typedef notifier<address_key, const code &, const binary &, uint32_t,\n                     const hash_digest &, const chain::transaction &>\n        address_subscriber;\n    typedef notifier<address_key, const code &, uint32_t,\n                     const hash_digest &, const hash_digest &>\n        penetration_subscriber;\n\n    // Remove expired subscriptions.\n    void purge();\n    int32_t purge_interval_milliseconds() const;\n\n    bool handle_blockchain_reorganization(const code &ec, uint64_t fork_point,\n                                          const block_list &new_blocks, const block_list &);\n    bool handle_tx_pool(const code &ec, const index_list &,\n                                 bc::message::tx_message::ptr tx);\n    bool handle_inventory(const code &ec,\n                          const bc::message::inventory::ptr packet);\n\n    void notify_blocks(uint32_t fork_point, const block_list &blocks);\n    void notify_block(socket &peer, uint32_t height,\n                      const chain::block::ptr block);\n    void notify_transaction(uint32_t height, const hash_digest &block_hash,\n                            const chain::transaction &tx);\n\n    // v2/v3 (deprecated)\n    void notify_payment(const bc::wallet::payment_address &address,\n                        uint32_t height, const hash_digest &block_hash,\n                        const chain::transaction &tx);\n    void notify_stealth(uint32_t prefix, uint32_t height,\n                        const hash_digest &block_hash, const chain::transaction &tx);\n\n    // v3\n    void notify_address(const binary &field, uint32_t height,\n                        const hash_digest &block_hash, const chain::transaction &tx);\n    void notify_penetration(uint32_t height, const hash_digest &block_hash,\n                            const hash_digest &tx_hash);\n\n    // Send a notification to the subscriber.\n    void send(const route &reply_to, const std::string &command,\n              uint32_t id, const data_chunk &payload);\n    void send_payment(const route &reply_to, uint32_t id,\n                      const bc::wallet::payment_address &address, uint32_t height,\n                      const hash_digest &block_hash, const chain::transaction &tx);\n    void send_stealth(const route &reply_to, uint32_t id, uint32_t prefix,\n                      uint32_t height, const hash_digest &block_hash,\n                      const chain::transaction &tx);\n    void send_address(const route &reply_to, uint32_t id, uint8_t sequence,\n                      uint32_t height, const hash_digest &block_hash,\n                      const chain::transaction &tx);\n\n    bool handle_payment(const code &ec, const bc::wallet::payment_address &address,\n                        uint32_t height, const hash_digest &block_hash,\n                        const chain::transaction &tx, const route &reply_to, uint32_t id,\n                        const binary &prefix_filter);\n    bool handle_stealth(const code &ec, uint32_t prefix, uint32_t height,\n                        const hash_digest &block_hash, const chain::transaction &tx,\n                        const route &reply_to, uint32_t id, const binary &prefix_filter);\n    bool handle_address(const code &ec, const binary &field, uint32_t height,\n                        const hash_digest &block_hash, const chain::transaction &tx,\n                        const route &reply_to, uint32_t id, const binary &prefix_filter,\n                        sequence_ptr sequence);\n\n    const bool secure_;\n    const server::settings &settings_;\n\n    // These are thread safe.\n    server_node &node_;\n    bc::protocol::zmq::authenticator &authenticator_;\n    address_subscriber::ptr address_subscriber_;\n    payment_subscriber::ptr payment_subscriber_;\n    stealth_subscriber::ptr stealth_subscriber_;\n    penetration_subscriber::ptr penetration_subscriber_;\n};\n\n} // namespace server\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainApp/ucd/workers/query_worker.hpp",
    "content": "/**\n * Copyright (c) 2016 libbitcoin developers \n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SERVER_QUERY_WORKER_HPP\n#define UC_SERVER_QUERY_WORKER_HPP\n\n#include <memory>\n#include <functional>\n#include <string>\n#include <unordered_map>\n#include <UChain/protocol.hpp>\n#include <UChainApp/ucd/define.hpp>\n#include <UChainApp/ucd/messages/msg.hpp>\n#include <UChainApp/ucd/settings.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nclass server_node;\n\n// This class is thread safe.\n// Provide asynchronous query responses to the query service.\nclass BCS_API query_worker\n    : public bc::protocol::zmq::worker\n{\n  public:\n    typedef std::shared_ptr<query_worker> ptr;\n\n    /// Construct a query worker.\n    query_worker(bc::protocol::zmq::authenticator &authenticator,\n                 server_node &node, bool secure);\n\n  protected:\n    typedef bc::protocol::zmq::socket socket;\n\n    typedef std::function<void(const message &, send_handler)> command_handler;\n    typedef std::unordered_map<std::string, command_handler> command_map;\n\n    virtual void attach_interface();\n    virtual void attach(const std::string &command, command_handler handler);\n\n    virtual bool connect(socket &router);\n    virtual bool disconnect(socket &router);\n    virtual void query(socket &router);\n\n    // Implement the worker.\n    virtual void work();\n\n  private:\n    const bool secure_;\n    const server::settings &settings_;\n\n    // These are thread safe.\n    server_node &node_;\n    bc::protocol::zmq::authenticator &authenticator_;\n\n    // This is protected by base class mutex.\n    command_map command_handlers_;\n};\n\n} // namespace server\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainApp/ucd.hpp",
    "content": "///////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 2014-2018 libbitcoin-server developers (see COPYING).\n//\n//        GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY\n//\n///////////////////////////////////////////////////////////////////////////////\n#ifndef UC_SERVER_HPP\n#define UC_SERVER_HPP\n\n/**\n * API Users: Include only this header. Direct use of other headers is fragile\n * and unsupported as header organization is subject to change.\n *\n * Maintainers: Do not include this header internal to this library.\n */\n\n#include <UChain/node.hpp>\n#include <UChain/protocol.hpp>\n#include <UChainApp/ucd/config.hpp>\n#include <UChainApp/ucd/define.hpp>\n#include <UChainApp/ucd/parser.hpp>\n#include <UChainApp/ucd/server_node.hpp>\n#include <UChainApp/ucd/settings.hpp>\n#include <UChainApp/ucd/version.hpp>\n#include <UChainApp/ucd/interface/address.hpp>\n#include <UChainApp/ucd/interface/blockchain.hpp>\n#include <UChainApp/ucd/interface/protocol.hpp>\n#include <UChainApp/ucd/interface/tx_pool.hpp>\n#include <UChainApp/ucd/messages/msg.hpp>\n#include <UChainApp/ucd/messages/route.hpp>\n#include <UChainApp/ucd/services/block_service.hpp>\n#include <UChainApp/ucd/services/heartbeat_service.hpp>\n#include <UChainApp/ucd/services/query_service.hpp>\n#include <UChainApp/ucd/services/tx_service.hpp>\n#include <UChainApp/ucd/utility/address_key.hpp>\n#include <UChainApp/ucd/utility/authenticator.hpp>\n#include <UChainApp/ucd/utility/fetch_helpers.hpp>\n#include <UChainApp/ucd/workers/notification_worker.hpp>\n#include <UChainApp/ucd/workers/query_worker.hpp>\n\n#endif\n"
  },
  {
    "path": "include/UChainService/api/command/base_helper.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#pragma once\n\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/command.hpp>\n#include <UChain/blockchain/block_chain_impl.hpp>\n#include <UChainService/consensus/miner.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/// NOTICE: this type is not equal to asset_type and business_kind\n/// asset_type : the collapsed type of tx output asset, **recorded on blockchain**\n/// business_kind   : the expanded type of asset, mainly used for database/history query\n/// for example :\n/// asset_type           |  business_kind\n/// -------------------------------------------------------------------\n/// asset_ucn           --> ucn\n/// asset_ucn_award     --> ucn_award\n/// asset_token         --> token_issue | token_transfer\n/// asset_message       --> message\n/// asset_uid           --> uid_register   |  uid_transfer\n/// asset_token_cert    --> token_cert\n/// asset_candidate     --> candidate\n/// -------------------------------------------------------------------\n/// utxo_attach_type is only used in explorer module\n/// utxo_attach_type will be used to generate asset with asset_type and content\n/// for example :\n/// utxo_attach_type::token_issue    --> asset_token of token_detail\n///     auto token_detail = token(TOKEN_DETAIL_TYPE, token_detail);\n///     asset(UC_TOKEN_TYPE, attach_version, token_detail);\n/// utxo_attach_type::token_transfer --> asset_token of token_transfer\n///     auto token_transfer = token(TOKEN_TRANSFERABLE_TYPE, token_transfer);\n///     asset(UC_TOKEN_TYPE, attach_version, token_transfer);\n/// NOTICE: createrawtx / createmultisigtx --type option is using these values.\n/// DO NOT CHANGE EXIST ITEMS!!!\nenum class utxo_attach_type : uint32_t\n{\n    ucn = 0,\n    deposit = 1,\n    token_issue = 2,\n    token_transfer = 3,\n    token_attenuation_transfer = 4,\n    token_locked_transfer = 5,\n    message = 6,\n    token_cert = 7,\n    token_secondaryissue = 8,\n    uid_register = 9,\n    uid_transfer = 10,\n    token_cert_issue = 11,\n    token_cert_transfer = 12,\n    token_cert_autoissue = 13,\n    candidate = 14,\n    candidate_transfer = 15,\n    invalid = 0xffffffff\n};\n\nextern utxo_attach_type get_utxo_attach_type(const chain::output &);\n\nstruct address_token_record\n{\n    std::string prikey;\n    std::string addr;\n    uint64_t amount{0}; // spendable ucn amount\n    std::string symbol;\n    uint64_t token_amount{0}; // spendable token amount\n    token_cert_type token_cert{token_cert_ns::none};\n    utxo_attach_type type{utxo_attach_type::invalid};\n    output_point output;\n    chain::script script;\n    uint32_t hd_index{0}; // only used for multisig tx\n};\n\nstruct receiver_record\n{\n    typedef std::vector<receiver_record> list;\n\n    std::string target;\n    std::string symbol;\n    uint64_t amount{0}; // ucn value\n    uint64_t token_amount{0};\n    token_cert_type token_cert{token_cert_ns::none};\n\n    utxo_attach_type type{utxo_attach_type::invalid};\n    asset attach_elem; // used for MESSAGE_TYPE, used for information transfer etc.\n    chain::input_point input_point{null_hash, max_uint32};\n\n    receiver_record()\n        : target(), symbol(), amount(0), token_amount(0), token_cert(token_cert_ns::none), type(utxo_attach_type::invalid), attach_elem(), input_point{null_hash, max_uint32}\n    {\n    }\n\n    receiver_record(const std::string &target_, const std::string &symbol_,\n                    uint64_t amount_, uint64_t token_amount_,\n                    utxo_attach_type type_, const asset &attach_elem_ = asset(),\n                    const chain::input_point &input_point_ = {null_hash, max_uint32})\n        : receiver_record(target_, symbol_, amount_, token_amount_,\n                          token_cert_ns::none, type_, attach_elem_, input_point_)\n    {\n    }\n\n    receiver_record(const std::string &target_, const std::string &symbol_,\n                    uint64_t amount_, uint64_t token_amount_, token_cert_type token_cert_,\n                    utxo_attach_type type_, const asset &attach_elem_ = asset(),\n                    const chain::input_point &input_point_ = {null_hash, max_uint32})\n        : target(target_), symbol(symbol_), amount(amount_), token_amount(token_amount_), token_cert(token_cert_), type(type_), attach_elem(attach_elem_), input_point(input_point_)\n    {\n    }\n\n    bool is_empty() const;\n};\n\nstruct balances\n{\n    uint64_t total_received;\n    uint64_t confirmed_balance;\n    uint64_t unspent_balance;\n    uint64_t frozen_balance;\n};\n\nstruct deposited_balance\n{\n    deposited_balance(const std::string &address_, const string &tx_hash_,\n                      uint64_t deposited_, uint64_t expiration_)\n        : address(address_), tx_hash(tx_hash_), balance(0), bonus(0), deposited_height(deposited_), expiration_height(expiration_)\n    {\n    }\n\n    std::string address;\n    std::string tx_hash;\n    std::string bonus_hash;\n    uint64_t balance;\n    uint64_t bonus;\n    uint64_t deposited_height;\n    uint64_t expiration_height;\n\n    // for sort\n    bool operator<(const deposited_balance &other) const\n    {\n        return expiration_height < other.expiration_height;\n    }\n\n    typedef std::vector<deposited_balance> list;\n};\n\n// helper function\nvoid sync_fetchbalance(bc::wallet::payment_address &address,\n                       bc::blockchain::block_chain_impl &blockchain, balances &addr_balance);\n\nvoid sync_fetchbalance(bc::wallet::payment_address &address,\n                       bc::blockchain::block_chain_impl &blockchain, balances &addr_balance);\n\nvoid sync_fetch_deposited_balance(bc::wallet::payment_address &address,\n                                  bc::blockchain::block_chain_impl &blockchain, std::shared_ptr<deposited_balance::list> sh_vec);\n\nvoid sync_fetch_token_balance(const std::string &address, bool sum_all,\n                              bc::blockchain::block_chain_impl &blockchain,\n                              std::shared_ptr<token_balances::list> sh_token_vec, uint64_t start_height = 0, uint64_t end_height = 0);\n\nvoid sync_fetch_token_deposited_balance(const std::string &address,\n                                        bc::blockchain::block_chain_impl &blockchain,\n                                        std::shared_ptr<token_deposited_balance::list> sh_token_vec);\n\nstd::shared_ptr<token_balances::list> sync_fetch_token_view(const std::string &symbol,\n                                                            bc::blockchain::block_chain_impl &blockchain);\n\nstd::shared_ptr<token_deposited_balance::list> sync_fetch_token_deposited_view(\n    const std::string &symbol,\n    bc::blockchain::block_chain_impl &blockchain);\n\nvoid sync_fetch_token_cert_balance(const std::string &address, const string &symbol,\n                                   bc::blockchain::block_chain_impl &blockchain,\n                                   std::shared_ptr<token_cert::list> sh_vec, token_cert_type cert_type = token_cert_ns::none);\n\nstd::string get_random_payment_address(std::shared_ptr<std::vector<wallet_address>>,\n                                       bc::blockchain::block_chain_impl &blockchain);\n\nstd::string get_address_from_strict_uid(const std::string &uid_or_address,\n                                        bc::blockchain::block_chain_impl &blockchain);\n\nstd::string get_address(const std::string &uid_or_address,\n                        bc::blockchain::block_chain_impl &blockchain);\n\nstd::string get_address(const std::string &uid_or_address,\n                        asset &attach, bool is_from,\n                        bc::blockchain::block_chain_impl &blockchain);\n\nstd::string get_address_from_uid(const std::string &uid,\n                                 bc::blockchain::block_chain_impl &blockchain);\n\nstd::string get_fee_dividend_address(bc::blockchain::block_chain_impl &blockchain);\n\nvoid check_token_symbol(const std::string &symbol, bool check_sensitive = false);\nvoid check_candidate_symbol(const std::string &symbol, bool check_sensitive = false);\nvoid check_candidate_authority(const std::string &authority);\nvoid check_uid_symbol(const std::string &symbol, bool check_sensitive = false);\nvoid check_token_symbol_with_miner(const std::string &symbol, const consensus::miner &miner, const std::string &address);\nvoid check_token_symbol_with_method(const std::string &symbol);\n\nclass BCX_API base_transfer_common\n{\n  public:\n    enum filter : uint8_t\n    {\n        FILTER_UCN = 1 << 0,\n        FILTER_TOKEN = 1 << 1,\n        FILTER_TOKENCERT = 1 << 2,\n        FILTER_UID = 1 << 3,\n        FILTER_IDENTIFIABLE_TOKEN = 1 << 4,\n        FILTER_ALL = 0xff,\n        // if specify 'from_' address,\n        // then get these types' unspent only from 'from_' address\n        FILTER_PAYFROM = FILTER_UCN | FILTER_TOKEN,\n        FILTER_ALL_BUT_PAYFROM = FILTER_ALL & ~FILTER_PAYFROM\n    };\n\n    base_transfer_common(\n        bc::blockchain::block_chain_impl &blockchain,\n        receiver_record::list &&receiver_list, uint64_t fee,\n        std::string &&symbol, std::string &&from, std::string &&change)\n        : blockchain_{blockchain}, symbol_{std::move(symbol)}, from_{std::move(from)}, mychange_{std::move(change)}, payment_ucn_{fee}, receiver_list_{std::move(receiver_list)} {};\n\n    virtual ~base_transfer_common()\n    {\n        receiver_list_.clear();\n        from_list_.clear();\n    };\n\n    static const uint64_t maximum_fee{1000000000000};\n    static const uint64_t minimum_fee{200000};\n    static const uint64_t tx_limit{677};\n    static const uint64_t attach_version{1};\n\n    virtual bool get_spendable_output(chain::output &, const chain::history &, uint64_t height) const;\n    virtual chain::operation::stack get_script_operations(const receiver_record &record) const;\n    virtual void sync_fetchutxo(\n        const std::string &prikey, const std::string &addr, filter filter = FILTER_ALL);\n    virtual asset populate_output_asset(const receiver_record &record);\n    virtual void sum_payments();\n    virtual void sum_payment_amount();\n    virtual void populate_change();\n    virtual void populate_tx_outputs();\n    virtual void populate_unspent_list() = 0;\n    virtual void sign_tx_inputs();\n    virtual void send_tx();\n    virtual void populate_tx_header();\n\n    // common functions, single responsibility.\n    static void check_fee_in_valid_range(uint64_t fee);\n    void check_receiver_list_not_empty() const;\n    bool is_payment_satisfied(filter filter = FILTER_ALL) const;\n    void check_payment_satisfied(filter filter = FILTER_ALL) const;\n    void check_model_param_initial(std::string &param, uint64_t amount);\n\n    static chain::operation::stack get_pay_key_hash_with_attenuation_model_operations(\n        const std::string &model_param, const receiver_record &record);\n\n    void populate_ucn_change(const std::string &address = std::string(\"\"));\n    void populate_token_change(const std::string &address = std::string(\"\"));\n    void populate_tx_inputs();\n    void check_tx();\n    void exec();\n\n    std::string get_mychange_address(filter filter) const;\n\n    tx_type &get_transaction() { return tx_; }\n    const tx_type &get_transaction() const { return tx_; }\n\n    // in secondary issue, locked token can also verify threshold condition\n    virtual bool is_locked_token_as_payment() const { return false; }\n\n    virtual bool filter_out_address(const std::string &address) const;\n\n    virtual std::string get_sign_tx_multisig_script(const address_token_record &from) const;\n\n    void set_uid_verify_asset(const receiver_record &record, asset &attach);\n\n  protected:\n    bc::blockchain::block_chain_impl &blockchain_;\n    tx_type tx_; // target transaction\n    std::string symbol_;\n    std::string from_;\n    std::string mychange_;\n    uint64_t tx_item_idx_{0};\n    uint64_t payment_ucn_{0};\n    uint64_t payment_token_{0};\n    uint64_t unspent_ucn_{0};\n    uint64_t unspent_token_{0};\n    std::vector<token_cert_type> payment_token_cert_;\n    std::vector<token_cert_type> unspent_token_cert_;\n    uint8_t payment_uid_{0};\n    uint8_t unspent_uid_{0};\n    uint8_t payment_candidate_{0};\n    uint8_t unspent_candidate_{0};\n    std::vector<receiver_record> receiver_list_;\n    std::vector<address_token_record> from_list_;\n};\n\nclass BCX_API base_transfer_helper : public base_transfer_common\n{\n  public:\n    base_transfer_helper(command &cmd, bc::blockchain::block_chain_impl &blockchain,\n                         std::string &&name, std::string &&passwd,\n                         std::string &&from, receiver_record::list &&receiver_list,\n                         uint64_t fee, std::string &&symbol = std::string(\"\"),\n                         std::string &&change = std::string(\"\"))\n        : base_transfer_common(blockchain, std::move(receiver_list), fee,\n                               std::move(symbol), std::move(from),\n                               std::move(change)),\n          cmd_{cmd}, name_{std::move(name)}, passwd_{std::move(passwd)}\n    {\n    }\n\n    ~base_transfer_helper()\n    {\n    }\n\n    void populate_unspent_list() override;\n\n  protected:\n    command &cmd_;\n    std::string name_;\n    std::string passwd_;\n};\n\nclass BCX_API base_multisig_transfer_helper : public base_transfer_helper\n{\n  public:\n    base_multisig_transfer_helper(command &cmd, bc::blockchain::block_chain_impl &blockchain,\n                                  std::string &&name, std::string &&passwd,\n                                  std::string &&from, receiver_record::list &&receiver_list,\n                                  uint64_t fee, std::string &&symbol,\n                                  wallet_multisig &&multisig_from)\n        : base_transfer_helper(cmd, blockchain, std::move(name), std::move(passwd),\n                               std::move(from), std::move(receiver_list), fee, std::move(symbol)),\n          multisig_(std::move(multisig_from))\n    {\n    }\n\n    ~base_multisig_transfer_helper()\n    {\n    }\n\n    bool filter_out_address(const std::string &address) const override;\n\n    std::string get_sign_tx_multisig_script(const address_token_record &from) const override;\n\n    void send_tx() override;\n\n  protected:\n    // for multisig address\n    wallet_multisig multisig_;\n};\n\nclass BCX_API base_transaction_constructor : public base_transfer_common\n{\n  public:\n    base_transaction_constructor(bc::blockchain::block_chain_impl &blockchain, utxo_attach_type type,\n                                 std::vector<std::string> &&from_vec, receiver_record::list &&receiver_list,\n                                 std::string &&symbol, std::string &&change,\n                                 std::string &&message, uint64_t fee)\n        : base_transfer_common(blockchain, std::move(receiver_list), fee,\n                               std::move(symbol), \"\", std::move(change)),\n          type_{type}, message_{std::move(message)}, from_vec_{std::move(from_vec)}\n    {\n    }\n\n    virtual ~base_transaction_constructor()\n    {\n        from_vec_.clear();\n    };\n\n    void sum_payment_amount() override;\n    void populate_unspent_list() override;\n    void populate_change() override;\n\n    // no operation in exec\n    void sign_tx_inputs() override {}\n    void send_tx() override {}\n\n  protected:\n    utxo_attach_type type_{utxo_attach_type::invalid};\n    std::string message_;\n    std::vector<std::string> from_vec_; // from address vector\n};\n\nclass BCX_API depositing_ucn : public base_transfer_helper\n{\n  public:\n    depositing_ucn(command &cmd, bc::blockchain::block_chain_impl &blockchain,\n                   std::string &&name, std::string &&passwd,\n                   std::string &&from, receiver_record::list &&receiver_list,\n                   uint16_t deposit_cycle = 7, uint64_t fee = 10000)\n        : base_transfer_helper(cmd, blockchain, std::move(name), std::move(passwd),\n                               std::move(from), std::move(receiver_list), fee),\n          deposit_cycle_{deposit_cycle}\n    {\n    }\n\n    ~depositing_ucn() {}\n\n    static const std::vector<uint16_t> vec_cycle;\n\n    uint32_t get_reward_lock_height() const;\n\n    chain::operation::stack get_script_operations(const receiver_record &record) const override;\n\n  private:\n    uint16_t deposit_cycle_{7}; // 7 days\n};\n\nclass BCX_API depositing_ucn_transaction : public base_transaction_constructor\n{\n  public:\n    depositing_ucn_transaction(bc::blockchain::block_chain_impl &blockchain, utxo_attach_type type,\n                               std::vector<std::string> &&from_vec, receiver_record::list &&receiver_list,\n                               uint16_t deposit, std::string &&change,\n                               std::string &&message, uint64_t fee)\n        : base_transaction_constructor(blockchain, type, std::forward<std::vector<std::string>>(from_vec),\n                                       std::move(receiver_list), std::string(\"\"),\n                                       std::move(change), std::move(message), fee),\n          deposit_{deposit}\n    {\n    }\n\n    ~depositing_ucn_transaction() {}\n\n    static const std::vector<uint16_t> vec_cycle;\n\n    uint32_t get_reward_lock_height() const;\n\n    chain::operation::stack get_script_operations(const receiver_record &record) const override;\n\n  private:\n    uint16_t deposit_{7}; // 7 days\n};\n\nclass BCX_API voting_token : public base_transfer_helper\n{\n  public:\n    voting_token(command &cmd, bc::blockchain::block_chain_impl &blockchain,\n                 std::string &&name, std::string &&passwd,\n                 std::string &&from, receiver_record::list &&receiver_list,\n                 uint16_t amount, uint64_t fee = 10000)\n        : base_transfer_helper(cmd, blockchain, std::move(name), std::move(passwd),\n                               std::move(from), std::move(receiver_list), fee, std::string(UC_VOTE_TOKEN_SYMBOL)),\n          amount_{amount}\n    {\n    }\n\n    ~voting_token() {}\n\n    uint32_t get_reward_lock_height() const;\n\n    chain::operation::stack get_script_operations(const receiver_record &record) const override;\n\n  private:\n    uint64_t amount_;\n};\n\nclass BCX_API sending_ucn : public base_transfer_helper\n{\n  public:\n    sending_ucn(command &cmd, bc::blockchain::block_chain_impl &blockchain,\n                std::string &&name, std::string &&passwd,\n                std::string &&from, receiver_record::list &&receiver_list,\n                std::string &&change, uint64_t fee)\n        : base_transfer_helper(cmd, blockchain, std::move(name), std::move(passwd),\n                               std::move(from), std::move(receiver_list), fee, \"\", std::move(change))\n    {\n    }\n\n    ~sending_ucn() {}\n};\n\nclass BCX_API sending_multisig_tx : public base_multisig_transfer_helper\n{\n  public:\n    sending_multisig_tx(command &cmd, bc::blockchain::block_chain_impl &blockchain,\n                        std::string &&name, std::string &&passwd,\n                        std::string &&from, receiver_record::list &&receiver_list, uint64_t fee,\n                        wallet_multisig &multisig, std::string &&symbol = std::string(\"\"))\n        : base_multisig_transfer_helper(cmd, blockchain, std::move(name), std::move(passwd),\n                                        std::move(from), std::move(receiver_list), fee, std::move(symbol),\n                                        std::move(multisig))\n    {\n    }\n\n    ~sending_multisig_tx() {}\n\n    void populate_change() override;\n};\n\nclass BCX_API issuing_token : public base_transfer_helper\n{\n  public:\n    issuing_token(command &cmd, bc::blockchain::block_chain_impl &blockchain,\n                  std::string &&name, std::string &&passwd,\n                  std::string &&from, std::string &&symbol,\n                  std::string &&model_param,\n                  receiver_record::list &&receiver_list, uint64_t fee, uint32_t fee_percentage_to_miner)\n        : base_transfer_helper(cmd, blockchain, std::move(name), std::move(passwd),\n                               std::move(from), std::move(receiver_list), fee, std::move(symbol)),\n          attenuation_model_param_{std::move(model_param)}, fee_percentage_to_miner_(fee_percentage_to_miner)\n    {\n    }\n\n    ~issuing_token() {}\n\n    void sum_payments() override;\n    void sum_payment_amount() override;\n    asset populate_output_asset(const receiver_record &record) override;\n    chain::operation::stack get_script_operations(const receiver_record &record) const override;\n\n  private:\n    std::shared_ptr<token_detail> unissued_token_;\n    std::string domain_cert_address_;\n    std::string attenuation_model_param_;\n    uint32_t fee_percentage_to_miner_;\n};\n\nclass BCX_API secondary_issuing_token : public base_transfer_helper\n{\n  public:\n    secondary_issuing_token(command &cmd, bc::blockchain::block_chain_impl &blockchain,\n                            std::string &&name, std::string &&passwd,\n                            std::string &&from, std::string &&symbol,\n                            std::string &&model_param,\n                            receiver_record::list &&receiver_list, uint64_t fee, uint64_t volume)\n        : base_transfer_helper(cmd, blockchain, std::move(name), std::move(passwd),\n                               std::move(from), std::move(receiver_list), fee, std::move(symbol)),\n          volume_(volume), attenuation_model_param_{std::move(model_param)}\n    {\n    }\n\n    ~secondary_issuing_token() {}\n\n    void sum_payment_amount() override;\n    void populate_change() override;\n    asset populate_output_asset(const receiver_record &record) override;\n    chain::operation::stack get_script_operations(const receiver_record &record) const override;\n\n    uint64_t get_volume() { return volume_; };\n\n    bool is_locked_token_as_payment() const override { return true; }\n\n    void populate_tx_header() override\n    {\n        tx_.version = transaction_version::check_uid_feature;\n        tx_.locktime = 0;\n    };\n\n  private:\n    uint64_t volume_{0};\n    std::shared_ptr<token_detail> issued_token_;\n    std::string target_address_;\n    std::string attenuation_model_param_;\n};\n\nclass BCX_API sending_token : public base_transfer_helper\n{\n  public:\n    sending_token(command &cmd, bc::blockchain::block_chain_impl &blockchain,\n                  std::string &&name, std::string &&passwd,\n                  std::string &&from, std::string &&symbol,\n                  std::string &&model_param,\n                  receiver_record::list &&receiver_list, uint64_t fee,\n                  std::string &&message, std::string &&change)\n        : base_transfer_helper(cmd, blockchain, std::move(name), std::move(passwd),\n                               std::move(from), std::move(receiver_list), fee,\n                               std::move(symbol), std::move(change)),\n          attenuation_model_param_{std::move(model_param)}, message_{std::move(message)}\n    {\n    }\n\n    ~sending_token()\n    {\n    }\n\n    void sum_payment_amount() override;\n    void populate_change() override;\n    chain::operation::stack get_script_operations(const receiver_record &record) const override;\n\n  private:\n    std::string attenuation_model_param_;\n    std::string message_;\n};\n\nclass BCX_API registering_uid : public base_multisig_transfer_helper\n{\n  public:\n    registering_uid(command &cmd, bc::blockchain::block_chain_impl &blockchain,\n                    std::string &&name, std::string &&passwd,\n                    std::string &&from, std::string &&symbol, receiver_record::list &&receiver_list,\n                    uint64_t fee, uint32_t fee_percentage_to_miner,\n                    wallet_multisig &&multisig)\n        : base_multisig_transfer_helper(cmd, blockchain, std::move(name), std::move(passwd),\n                                        std::move(from), std::move(receiver_list), fee, std::move(symbol),\n                                        std::move(multisig)),\n          fee_percentage_to_miner_(fee_percentage_to_miner)\n    {\n    }\n\n    ~registering_uid()\n    {\n    }\n\n    void sum_payment_amount() override;\n\n    void populate_tx_header() override\n    {\n        tx_.version = transaction_version::check_uid_feature;\n        tx_.locktime = 0;\n    };\n\n  private:\n    uint32_t fee_percentage_to_miner_;\n};\n\nclass BCX_API sending_multisig_uid : public base_transfer_helper\n{\n  public:\n    sending_multisig_uid(command &cmd, bc::blockchain::block_chain_impl &blockchain,\n                         std::string &&name, std::string &&passwd,\n                         std::string &&from, std::string &&feefrom, std::string &&symbol,\n                         receiver_record::list &&receiver_list, uint64_t fee, wallet_multisig &&multisig, wallet_multisig &&multisigto)\n        : base_transfer_helper(cmd, blockchain, std::move(name), std::move(passwd),\n                               std::move(from), std::move(receiver_list), fee, std::move(symbol)),\n          fromfee(feefrom), multisig_from_(std::move(multisig)), multisig_to_(std::move(multisigto))\n    {\n    }\n\n    ~sending_multisig_uid()\n    {\n    }\n\n    void sum_payment_amount() override;\n    void populate_unspent_list() override;\n    void populate_change() override;\n\n    std::string get_sign_tx_multisig_script(const address_token_record &from) const override;\n\n    // no operation in exec\n    void send_tx() override {}\n\n    void populate_tx_header() override\n    {\n        tx_.version = transaction_version::check_uid_feature;\n        tx_.locktime = 0;\n    };\n\n  private:\n    std::string fromfee;\n    wallet_multisig multisig_from_;\n    wallet_multisig multisig_to_;\n};\n\nclass BCX_API sending_uid : public base_transfer_helper\n{\n  public:\n    sending_uid(command &cmd, bc::blockchain::block_chain_impl &blockchain,\n                std::string &&name, std::string &&passwd,\n                std::string &&from, std::string &&feefrom, std::string &&symbol,\n                receiver_record::list &&receiver_list, uint64_t fee)\n        : base_transfer_helper(cmd, blockchain, std::move(name), std::move(passwd),\n                               std::move(from), std::move(receiver_list), fee, std::move(symbol)),\n          fromfee(feefrom)\n    {\n    }\n\n    ~sending_uid()\n    {\n    }\n\n    void sum_payment_amount() override;\n    void populate_unspent_list() override;\n    void populate_change() override;\n\n    void populate_tx_header() override\n    {\n        tx_.version = transaction_version::check_uid_feature;\n        tx_.locktime = 0;\n    };\n\n  private:\n    std::string fromfee;\n};\n\nclass BCX_API transferring_token_cert : public base_multisig_transfer_helper\n{\n  public:\n    transferring_token_cert(command &cmd, bc::blockchain::block_chain_impl &blockchain,\n                            std::string &&name, std::string &&passwd,\n                            std::string &&from, std::string &&symbol,\n                            receiver_record::list &&receiver_list, uint64_t fee,\n                            wallet_multisig &&multisig_from)\n        : base_multisig_transfer_helper(cmd, blockchain, std::move(name), std::move(passwd),\n                                        std::move(from), std::move(receiver_list), fee, std::move(symbol),\n                                        std::move(multisig_from))\n    {\n    }\n\n    ~transferring_token_cert()\n    {\n    }\n\n    void populate_tx_header() override\n    {\n        tx_.version = transaction_version::check_uid_feature;\n        tx_.locktime = 0;\n    };\n};\n\nclass BCX_API issuing_token_cert : public base_transfer_helper\n{\n  public:\n    issuing_token_cert(command &cmd, bc::blockchain::block_chain_impl &blockchain,\n                       std::string &&name, std::string &&passwd,\n                       std::string &&from, std::string &&symbol,\n                       receiver_record::list &&receiver_list, uint64_t fee)\n        : base_transfer_helper(cmd, blockchain, std::move(name), std::move(passwd),\n                               std::move(from), std::move(receiver_list), fee, std::move(symbol))\n    {\n    }\n\n    ~issuing_token_cert()\n    {\n    }\n\n    void sum_payment_amount() override;\n\n    void populate_tx_header() override\n    {\n        tx_.version = transaction_version::check_uid_feature;\n        tx_.locktime = 0;\n    };\n};\nclass BCX_API registering_candidate : public base_transfer_helper\n{\n  public:\n    registering_candidate(command &cmd, bc::blockchain::block_chain_impl &blockchain,\n                          std::string &&name, std::string &&passwd,\n                          std::string &&from, std::string &&symbol, std::map<std::string, std::string> &&candidate_map,\n                          receiver_record::list &&receiver_list, uint64_t fee)\n        : base_transfer_helper(cmd, blockchain, std::move(name), std::move(passwd),\n                               std::move(from), std::move(receiver_list), fee, std::move(symbol)),\n          candidate_map_(candidate_map)\n    {\n    }\n\n    ~registering_candidate()\n    {\n    }\n\n    void populate_tx_header() override\n    {\n        tx_.version = transaction_version::check_uid_feature;\n        tx_.locktime = 0;\n    };\n\n    asset populate_output_asset(const receiver_record &record) override;\n\n    uint32_t get_reward_lock_height() const;\n\n    chain::operation::stack get_script_operations(const receiver_record &record) const override;\n\n  private:\n    std::map<std::string, std::string> candidate_map_;\n};\n\nclass BCX_API transferring_candidate : public base_multisig_transfer_helper\n{\n  public:\n    transferring_candidate(command &cmd, bc::blockchain::block_chain_impl &blockchain,\n                           std::string &&name, std::string &&passwd,\n                           std::string &&from, std::string &&symbol,\n                           receiver_record::list &&receiver_list, uint64_t fee,\n                           wallet_multisig &&multisig_from)\n        : base_multisig_transfer_helper(cmd, blockchain, std::move(name), std::move(passwd),\n                                        std::move(from), std::move(receiver_list), fee, std::move(symbol),\n                                        std::move(multisig_from))\n    {\n    }\n\n    ~transferring_candidate()\n    {\n    }\n\n    void populate_tx_header() override\n    {\n        tx_.version = transaction_version::check_uid_feature;\n        tx_.locktime = 0;\n    };\n\n    asset populate_output_asset(const receiver_record &record) override;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/command_assistant.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n\n#include <UChain/coin.hpp>\n\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/command.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n// to genarate address/public key\nstd::string ec_to_xxx_impl(const std::string &cmd, const std::string &fromkey);\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/command_extension.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n\n#include <functional>\n#include <memory>\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/command.hpp>\n#include <UChainService/txs/token/token_detail.hpp> // used for createtoken\n#include <UChainApp/ucd/server_node.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nstruct prikey_amount\n{\n    std::string first;\n    uint64_t second;\n};\n\nstruct prikey_ucn_amount\n{\n    std::string key;\n    uint64_t value;\n    uint64_t token_amount;\n    output_point output;\n};\n\nstruct utxo_attach_info\n{\n    //target:1:token-transfer:symbol:amount\n    std::string target;\n    uint32_t version;\n    std::string type;\n    std::string symbol;\n    uint64_t amount;\n    uint64_t value;            // ucn\n    std::string output_option; // used by get_tx_encode\n};\n\ntemplate <class T1, class T2>\nclass BCX_API colon_delimited2_item\n{\n  public:\n    /**\n     * Default constructor.\n     */\n    colon_delimited2_item(){};\n\n    colon_delimited2_item(T1 first, T2 second)\n        : first_(first), second_(second){};\n\n    /**\n     * Initialization constructor.\n     * @param[in]  tuple  The value to initialize with.\n     */\n    colon_delimited2_item(const std::string &tuple)\n    {\n        std::stringstream(tuple) >> *this;\n    };\n\n    static bool decode_colon_delimited(colon_delimited2_item<T1, T2> &height, const std::string &tuple)\n    {\n        const auto tokens = split(tuple, BX_TX_POINT_DELIMITER);\n        if (tokens.size() != 2)\n            return false;\n\n        deserialize(height.first_, tokens[0], true);\n        deserialize(height.second_, tokens[1], true);\n\n        return true;\n    };\n\n    // colon_delimited2_item is currently a private encoding in bx.\n    static std::string encode_colon_delimited(const colon_delimited2_item<T1, T2> &height)\n    {\n        std::stringstream result;\n        result << height.first_ << BX_TX_POINT_DELIMITER << height.second_;\n        return result.str();\n    };\n\n    /**\n     * Overload stream in. Throws if colon_delimited2_item is invalid.\n     * @param[in]   colon_delimited2_item     The colon_delimited2_item stream to read the value from.\n     * @param[out]  argument  The object to receive the read value.\n     * @return                The colon_delimited2_item stream reference.\n     */\n    friend std::istream &operator>>(std::istream &stream, colon_delimited2_item &argument)\n    {\n        std::string tuple;\n        stream >> tuple;\n\n        if (!decode_colon_delimited(argument, tuple))\n        {\n            throw std::logic_error{\"invalid option \" + tuple};\n        }\n\n        return stream;\n    };\n\n    /**\n     * Overload stream out.\n     * @param[in]   output    The output stream to write the value to.\n     * @param[out]  argument  The object from which to obtain the value.\n     * @return                The output stream reference.\n     */\n    friend std::ostream &operator<<(std::ostream &output, const colon_delimited2_item &argument)\n    {\n        output << encode_colon_delimited(argument);\n        return output;\n    };\n\n    // get method\n    T1 first()\n    {\n        return first_;\n    };\n\n    void set_first(const T1 &first)\n    {\n        first_ = first;\n    };\n\n    T2 second()\n    {\n        return second_;\n    };\n\n    void set_second(const T2 &second)\n    {\n        second_ = second;\n    };\n\n  private:\n    /**\n     * The state of this object. only for uint64_t\n     */\n    T1 first_;\n    T2 second_;\n};\n\nclass command_extension : public command\n{\n  public:\n    virtual console_result invoke(Json::Value &jv_output,\n                                  libbitcoin::server::server_node &node)\n    {\n        return console_result::failure;\n    }\n\n  protected:\n    struct argument_base\n    {\n        std::string name;\n        std::string auth;\n    } auth_;\n};\n\nclass send_command : public command_extension\n{\n  public:\n    virtual bool is_block_height_fullfilled(uint64_t height) override\n    {\n        if (height >= minimum_block_height())\n        {\n            return true;\n        }\n        return false;\n    }\n\n    virtual uint64_t minimum_block_height() override\n    {\n        return 610000;\n    }\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/command_extension_func.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 uc developers\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n\n#include <functional>\n#include <memory>\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/command.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\n\nstd::string formerly_extension(const std::string &former);\n\nstd::shared_ptr<command> find_extension(const std::string &symbol);\n\nvoid broadcast_extension(const std::function<void(std::shared_ptr<command>)> func, std::ostream &os);\nbool check_read_only(const string &symbol);\n\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/addaddress.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ addaddress *************************/\n\nclass addaddress : public command_extension\n{\n  public:\n    static const char *symbol() { return \"addaddress\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"Generate new address for this wallet.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"number,n\",\n            value<std::uint32_t>(&option_.count),\n            \"The number of addresses to be generated/deleted, defaults to 1.\")(\n            \"operation,o\",\n            value<std::string>(&option_.operation),\n            \"The operation[ add|del ] to the target node address. default: add.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n    } argument_;\n\n    struct option\n    {\n        option() : count(1){};\n        std::string operation;\n        uint32_t count;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/addpeer.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ addpeer *************************/\n\nclass addpeer : public command_extension\n{\n  public:\n    static const char *symbol() { return \"addpeer\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"This command is used to add/remove p2p node.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"NODEADDRESS\", 1)\n            .add(\"ADMINNAME\", 1)\n            .add(\"ADMINAUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(argument_.address, \"NODEADDRESS\", variables, input, raw);\n        load_input(auth_.name, \"ADMINNAME\", variables, input, raw);\n        load_input(auth_.auth, \"ADMINAUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"NODEADDRESS\",\n            value<std::string>(&argument_.address)->required(),\n            \"The target node address[x.x.x.x:port].\")(\n            \"ADMINNAME\",\n            value<std::string>(&auth_.name),\n            \"admin name.\")(\n            \"ADMINAUTH\",\n            value<std::string>(&auth_.auth),\n            \"admin password/authorization.\")(\n            \"operation,o\",\n            value<std::string>(&option_.operation),\n            \"The operation[ add|ban ] to the target node address. default: add.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string address;\n    } argument_;\n\n    struct option\n    {\n        std::string operation;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/changepass.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ changepass *************************/\n\nclass changepass : public command_extension\n{\n  public:\n    static const char *symbol() { return \"changepass\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"changepass \"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"password,p\",\n            value<std::string>(&option_.passwd)->required(),\n            \"The new password.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n    } argument_;\n\n    struct option\n    {\n        option()\n            : passwd()\n        {\n        }\n\n        std::string passwd;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/checkpublickey.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nclass checkpublickey : public command_extension\n{\n  public:\n    static const char *symbol() { return \"checkpublickey\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"checkpublickey \"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"ADDRESS\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(argument_.address, \"ADDRESS\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"ADDRESS\",\n            value<std::string>(&argument_.address)->required(),\n            \"Address.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string address;\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/checkwalletinfo.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ checkwalletinfo *************************/\n\nclass checkwalletinfo : public command_extension\n{\n  public:\n    static const char *symbol() { return \"checkwalletinfo\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"Show wallet details\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"LASTWORD\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(auth_.auth, \"LASTWORD\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"LASTWORD\",\n            value<std::string>(&argument_.last_word)->required(),\n            \"The last word of your backup words.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string last_word;\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/createmultisigaddress.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ createmultisigaddress *************************/\n\nclass createmultisigaddress : public command_extension\n{\n  public:\n    static const char *symbol() { return \"createmultisigaddress\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"createmultisigaddress \"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"signaturenum,m\",\n            value<uint16_t>(&option_.m)->required(),\n            \"Wallet multisig signature number.\")(\n            \"publickeynum,n\",\n            value<uint16_t>(&option_.n)->required(),\n            \"Wallet multisig public key number.\")(\n            \"selfpublickey,s\",\n            value<std::string>(&option_.self_publickey)->required(),\n            \"the public key belongs to this wallet.\")(\n            \"publickey,k\",\n            value<std::vector<std::string>>(&option_.public_keys),\n            \"cosigner public key used for multisig\")(\n            \"description,d\",\n            value<std::string>(&option_.description),\n            \"multisig record description.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        argument()\n        {\n        }\n    } argument_;\n\n    struct option\n    {\n        option()\n            : m(0), n(0), self_publickey(\"\"), description(\"\")\n        {\n        }\n\n        uint16_t m;\n        uint16_t n;\n        std::vector<std::string> public_keys;\n        std::string self_publickey;\n        std::string description;\n\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/createmultisigtx.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nclass createmultisigtx : public command_extension\n{\n  public:\n    static const char *symbol() { return \"createmultisigtx\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"createmultisigtx \"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"FROMADDRESS\", 1)\n            .add(\"TOADDRESS\", 1)\n            .add(\"AMOUNT\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(argument_.from, \"FROMADDRESS\", variables, input, raw);\n        load_input(argument_.to, \"TOADDRESS\", variables, input, raw);\n        load_input(argument_.amount, \"AMOUNT\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"FROMADDRESS\",\n            value<std::string>(&argument_.from)->required(),\n            \"Send from this address, must be a multi-signature script address.\")(\n            \"TOADDRESS\",\n            value<std::string>(&argument_.to)->required(),\n            \"Send to this address\")(\n            \"AMOUNT\",\n            value<uint64_t>(&argument_.amount)->required(),\n            \"UCN integer bits.\")(\n            \"symbol,s\",\n            value<std::string>(&option_.symbol),\n            \"token name, not specify this option for UCN tx\")(\n            \"type,t\",\n            value<uint16_t>(&option_.type)->default_value(0),\n            \"Transaction type, defaults to 0. 0 -- transfer UCN, 3 -- transfer token\")(\n            \"fee,f\",\n            value<uint64_t>(&argument_.fee)->default_value(bc::min_tx_fee),\n            \"Transaction fee. defaults to 200000 UCN bits.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        argument()\n            : amount(0), fee(0)\n        {\n        }\n\n        std::string from;\n        std::string to;\n        uint64_t amount;\n        uint64_t fee;\n    } argument_;\n\n    struct option\n    {\n        std::string symbol;\n        uint16_t type;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/createrawtx.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ createrawtx *************************/\n\nclass createrawtx : public command_extension\n{\n  public:\n    static const char *symbol() { return \"createrawtx\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"createrawtx\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata();\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"type,t\",\n            value<uint16_t>(&option_.type)->required(),\n            \"Transaction type. 0 -- transfer UCN, 1 -- deposit UCN, 3 -- transfer token\")(\n            \"senders,s\",\n            value<std::vector<std::string>>(&option_.senders)->required(),\n            \"Send from addresses\")(\n            \"receivers,r\",\n            value<std::vector<std::string>>(&option_.receivers)->required(),\n            \"Send to [address:amount]. amount is token number if sybol option specified\")(\n            \"symbol,n\",\n            value<std::string>(&option_.symbol)->default_value(\"\"),\n            \"token name, not specify this option for UCN tx\")(\n            \"deposit,d\",\n            value<uint16_t>(&option_.deposit)->default_value(10),\n            \"Deposits support [10, 45, 120, 240, 540] days. defaluts to 10 days\")(\n            \"change,c\",\n            value<std::string>(&option_.mychange_address),\n            \"change to this address, includes UCN and token change\")(\n            \"message,i\",\n            value<std::string>(&option_.message),\n            \"Message/Information attached to this transaction\")(\n            \"fee,f\",\n            value<uint64_t>(&option_.fee)->default_value(bc::min_tx_fee),\n            \"Transaction fee. defaults to 200000 UCN bits.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        argument()\n        {\n        }\n    } argument_;\n\n    struct option\n    {\n        uint16_t type;\n        std::vector<std::string> senders;\n        std::vector<std::string> receivers;\n        std::string symbol;\n        std::string mychange_address;\n        std::string message;\n        uint16_t deposit;\n        uint64_t fee;\n\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/createtoken.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ createtoken *************************/\nstruct non_negative_uint64\n{\n  public:\n    uint64_t volume;\n};\n\nvoid validate(boost::any &v, const std::vector<std::string> &values,\n              non_negative_uint64 *, int);\n\nclass createtoken : public command_extension\n{\n  public:\n    static const char *symbol() { return \"createtoken\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"createtoken \"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"rate,r\",\n            value<int32_t>(&option_.registersecondarytoken_threshold),\n            \"The percent threshold value when you secondary issue. \\\n             0,  not allowed to secondary issue;  \\\n            -1,  the token can be secondary issue freely; \\\n            [1, 100], the token can be secondary issue when own percentage greater than or equal to this value. \\\n            Defaults to 0.\")(\n            \"symbol,s\",\n            value<std::string>(&option_.symbol)->required(),\n            \"The token symbol, global uniqueness, only supports UPPER-CASE alphabet and dot(.), eg: -.LAPTOP, dot separates prefix '-', It's impossible to create any token named with '-' prefix, but this issuer.\")(\n            \"issuer,i\",\n            value<std::string>(&option_.issuer)->required(),\n            \"Issue must be specified as a UID symbol.\")(\n            \"volume,v\",\n            value<non_negative_uint64>(&option_.maximum_supply)->required(),\n            \"The token maximum supply volume, with unit of integer bits.\")(\n            \"decimalnumber,n\",\n            value<uint32_t>(&option_.decimal_number),\n            \"The token amount decimal number, defaults to 0.\")(\n            \"description,d\",\n            value<std::string>(&option_.description),\n            \"The token data chuck, defaults to empty string.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n    } argument_;\n\n    struct option\n    {\n        option() : symbol(\"\"),\n                   maximum_supply{0},\n                   decimal_number(0),\n                   registersecondarytoken_threshold(0),\n                   issuer(\"\"),\n                   description(\"\"){};\n\n        std::string symbol;\n        non_negative_uint64 maximum_supply;\n        uint32_t decimal_number;\n        int32_t registersecondarytoken_threshold;\n        std::string issuer;\n        std::string description;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/createwallet.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ createwallet *************************/\n\nclass createwallet : public command_extension\n{\n  public:\n    static const char *symbol() { return \"createwallet\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"Generate a new wallet to manage the keys belong to one user in this wallet.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"language,l\",\n            value<std::string>(&option_.language)->default_value(\"en\"),\n            \"Options are 'en', 'es', 'ja', 'zh_Hans', 'zh_Hant' and 'any', defaults to 'en'.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH);\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n    } argument_;\n\n    struct option\n    {\n        std::string language;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/decoderawtx.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ decoderawtx *************************/\n\nclass decoderawtx : public command_extension\n{\n  public:\n    static const char *symbol() { return \"decoderawtx\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"decoderawtx \"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"TRANSACTION\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(argument_.transaction, \"TRANSACTION\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"TRANSACTION\",\n            value<explorer::config::transaction>(&argument_.transaction)->required(),\n            \"The input Base16 transaction to sign.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        explorer::config::transaction transaction;\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/deletemultisigaddress.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ deletemultisigaddress *************************/\n\nclass deletemultisigaddress : public command_extension\n{\n  public:\n    static const char *symbol() { return \"deletemultisigaddress\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"deletemultisigaddress \"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"ADDRESS\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(option_.address, \"ADDRESS\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"ADDRESS\",\n            value<std::string>(&option_.address)->required(),\n            \"The multisig script corresponding address.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        argument()\n        {\n        }\n    } argument_;\n\n    struct option\n    {\n        option()\n            : address(\"\"), m(0), n(0), index(0)\n        {\n        }\n        uint16_t index;\n        uint16_t m;\n        uint16_t n;\n        std::vector<std::string> public_keys;\n        std::string self_publickey;\n        std::string address;\n\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/deletetoken.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ deletetoken *************************/\n\nclass deletetoken : public command_extension\n{\n  public:\n    static const char *symbol() { return \"deletetoken\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"deletetoken\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"symbol,s\",\n            value<std::string>(&option_.symbol)->required(),\n            \"The token symbol/name. Global unique.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n    } argument_;\n\n    struct option\n    {\n        option()\n            : symbol(\"\"){};\n\n        std::string symbol;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/deletewallet.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ deletewallet *************************/\n\nclass deletewallet : public command_extension\n{\n  public:\n    static const char *symbol() { return \"deletewallet\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"deletewallet \"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"LASTWORD\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(auth_.auth, \"LASTWORD\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"LASTWORD\",\n            value<std::string>(&argument_.last_word)->required(),\n            \"The last word of your private-key phrase.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string last_word;\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/deposit.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nclass deposit : public command_extension\n{\n  public:\n    static const char *symbol() { return \"deposit\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"Deposit some UCN, then get reward for frozen some UCN.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"AMOUNT\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(argument_.amount, \"AMOUNT\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"AMOUNT\",\n            value<uint64_t>(&argument_.amount)->required(),\n            \"UCN integer bits.\")(\n            \"uid,u\",\n            value<std::string>(&argument_.uid),\n            \"The deposit target uid.\")(\n            \"deposit,d\",\n            value<uint16_t>(&argument_.deposit)->default_value(10),\n            \"Deposits support [10, 45, 120, 240, 540] days. defaluts to 10 days\")(\n            \"fee,f\",\n            value<uint64_t>(&argument_.fee)->default_value(bc::min_tx_fee),\n            \"Transaction fee. defaults to 200000 UCN bits.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        uint64_t amount;\n        uint64_t fee;\n        uint16_t deposit;\n        std::string uid;\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/destroy.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ destroy *************************/\n\nclass destroy : public command_extension\n{\n  public:\n    static const char *symbol() { return \"destroy\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"destroy token to blackhole address 1111111111111111111114oLvT2.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"SYMBOL\", 1)\n            .add(\"AMOUNT\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(argument_.symbol, \"SYMBOL\", variables, input, raw);\n        load_input(argument_.amount, \"AMOUNT\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"SYMBOL\",\n            value<std::string>(&argument_.symbol)->required(),\n            \"The token will be destroyed.\")(\n            \"AMOUNT\",\n            value<uint64_t>(&argument_.amount)->default_value(0),\n            \"Token integer bits. see token <decimal_number>.\")(\n            \"cert,c\",\n            value<std::string>(&option_.cert_type)->default_value(\"\"),\n            \"If specified, then only destroy related cert. Default is not specified.\")(\n            \"candidate,m\",\n            value<bool>(&option_.is_candidate)->default_value(false)->zero_tokens(),\n            \"If specified, then only destroy related candidate. Default is not specified.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        argument() : amount(0), symbol(\"\")\n        {\n        }\n\n        uint64_t amount;\n        std::string symbol;\n    } argument_;\n\n    struct option\n    {\n        option() : is_candidate(false), cert_type(\"\")\n        {\n        }\n\n        bool is_candidate;\n        std::string cert_type;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/exportkeyfile.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ exportwalletasfile *************************/\n\nclass exportkeyfile : public command_extension\n{\n  public:\n    static const char *symbol() { return \"exportkeyfile\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"exportkeyfile\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"LASTWORD\", 1)\n            .add(\"DESTINATION\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(argument_.last_word, \"LASTWORD\", variables, input, raw);\n        load_input(argument_.dst, \"DESTINATION\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"LASTWORD\",\n            value<std::string>(&argument_.last_word)->required(),\n            \"The last word of your master private-key phrase.\")(\n            \"DESTINATION\",\n            value<boost::filesystem::path>(&argument_.dst)->default_value(\"\"),\n            \"The keyfile storage path to.\")(\n            \"data,d\",\n            value<bool>(&option_.is_data)->default_value(false)->zero_tokens(),\n            \"If specified, the keyfile content will be append to the report, rather than to local file specified by DESTINATION.\");\n        ;\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string last_word;\n        boost::filesystem::path dst;\n    } argument_;\n\n    struct option\n    {\n        bool is_data;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/importkeyfile.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ importkeyfile *************************/\n\nclass importkeyfile : public command_extension\n{\n  public:\n    static const char *symbol() { return \"importkeyfile\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"importkeyfile \"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"FILE\", 1)\n            .add(\"FILECONTENT\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(option_.file, \"FILE\", variables, input, raw);\n        load_input(option_.content, \"FILECONTENT\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"FILE\",\n            value<boost::filesystem::path>(&option_.file)->required(),\n            \"key file path.\")(\n            \"FILECONTENT\",\n            value<std::string>(&option_.content),\n            \"key file content. this will omit the FILE argument if specified.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n    } argument_;\n\n    struct option\n    {\n        option()\n            : file(\"\"), content(\"\")\n        {\n        }\n\n        boost::filesystem::path file;\n        std::string content;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/importwallet.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nclass importwallet : public command_extension\n{\n  public:\n    static const char *symbol() { return \"importwallet\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"importwallet \"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WORD\", -1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(argument_.words, \"WORD\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WORD\",\n            value<std::vector<std::string>>(&argument_.words)->required(),\n            \"The set of words that that make up the mnemonic. If not specified the words are read from STDIN.\")(\n            \"language,l\",\n            value<explorer::config::language>(&option_.language),\n            \"The language identifier of the dictionary of the mnemonic. Options are 'en', 'es', 'ja', 'zh_Hans', 'zh_Hant' and 'any', defaults to 'any'.\")(\n            \"walletname,n\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"password,p\",\n            value<std::string>(&option_.passwd)->required(),\n            BX_WALLET_AUTH)(\n            \"hd_index,i\",\n            value<std::uint32_t>(&option_.hd_index),\n            \"The HD index for the wallet.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        argument()\n            : words()\n        {\n        }\n        std::vector<std::string> words;\n    } argument_;\n\n    struct option\n    {\n        option()\n            : language(), passwd(\"\"), hd_index(1)\n        {\n        }\n\n        explorer::config::language language;\n        std::string passwd;\n        uint32_t hd_index;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/registercandidate.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ registercandidate *************************/\n\nclass registercandidate : public command_extension\n{\n  public:\n    static const char *symbol() { return \"registercandidate\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"Register Candidate\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"SYMBOL\", 1)\n            .add(\"TOUID\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(argument_.symbol, \"SYMBOL\", variables, input, raw);\n        load_input(argument_.to, \"TOUID\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"SYMBOL\",\n            value<std::string>(&argument_.symbol)->required(),\n            \"The symbol of global candidate, supports alphabets/numbers/(“@”, “.”, “_”), case-sensitive, maximum length is 64.\")(\n            \"TOUID\",\n            value<std::string>(&argument_.to)->required(),\n            \"Target uid\")(\n            \"content,c\",\n            value<std::string>(&argument_.content)->default_value(\"\"),\n            \"Declaration of candidacy.\")(\n            \"fee,f\",\n            value<uint64_t>(&argument_.fee)->default_value(bc::min_fee_to_register_uid),\n            \"Transaction fee. defaults to 100 UCN.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string to;\n        std::string symbol;\n        std::string content;\n        uint64_t fee;\n    } argument_;\n\n  private:\n    void check_symbol_content(const std::string &symbol, const std::string &content);\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/registercert.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ registercert *************************/\n\nclass registercert : public command_extension\n{\n  public:\n    static const char *symbol() { return \"registercert\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"registercert supports define an token certification.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"TOUID\", 1)\n            .add(\"SYMBOL\", 1)\n            .add(\"CERT\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(argument_.to, \"TOUID\", variables, input, raw);\n        load_input(argument_.symbol, \"SYMBOL\", variables, input, raw);\n        load_input(argument_.cert, \"CERT\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"TOUID\",\n            value<std::string>(&argument_.to)->required(),\n            \"The UID will own this cert.\")(\n            \"SYMBOL\",\n            value<std::string>(&argument_.symbol)->required(),\n            \"Cert Symbol/Name.\")(\n            \"CERT\",\n            value<std::string>(&argument_.cert)->required(),\n            \"Cert type name can be: NAMING: cert of naming right of domain. The owner of domain cert can issue this type of cert by registercert with symbol like “domain.XYZ”(domain is the symbol of domain cert).\")(\n            \"fee,f\",\n            value<uint64_t>(&argument_.fee)->default_value(bc::min_tx_fee),\n            \"Transaction fee. defaults to 200000 UCN bits.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string to;\n        std::string symbol;\n        std::string cert;\n        uint64_t fee;\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/registersecondarytoken.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ registersecondarytoken *************************/\nclass registersecondarytoken : public command_extension\n{\n  public:\n    static const char *symbol() { return \"registersecondarytoken\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"registersecondarytoken, alias as additionalissue.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"TOUID\", 1)\n            .add(\"SYMBOL\", 1)\n            .add(\"VOLUME\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(argument_.to, \"TOUID\", variables, input, raw);\n        load_input(argument_.symbol, \"SYMBOL\", variables, input, raw);\n        load_input(argument_.volume, \"VOLUME\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"TOUID\",\n            value<std::string>(&argument_.to)->required(),\n            \"target uid to check and issue token, fee from and change to the address of this uid too.\")(\n            \"SYMBOL\",\n            value<std::string>(&argument_.symbol)->required(),\n            \"issued token symbol\")(\n            \"VOLUME\",\n            value<uint64_t>(&argument_.volume)->required(),\n            \"The volume of token, with unit of integer bits.\")(\n            \"model,m\",\n            value<std::string>(&option_.attenuation_model_param),\n            BX_TOKEN_OFFERING_CURVE)(\n            \"fee,f\",\n            value<uint64_t>(&argument_.fee)->default_value(bc::min_tx_fee),\n            \"The fee of tx. default_value 200000 UCN bits.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string to;\n        std::string symbol;\n        uint64_t fee;\n        uint64_t volume;\n    } argument_;\n\n    struct option\n    {\n        std::string attenuation_model_param;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/registertoken.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ registertoken *************************/\nclass registertoken : public command_extension\n{\n  public:\n    static const char *symbol() { return \"registertoken\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"Broadcast the token whole network.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"SYMBOL\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(argument_.symbol, \"SYMBOL\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"SYMBOL\",\n            value<std::string>(&argument_.symbol)->required(),\n            \"The token symbol, global uniqueness, only supports UPPER-CASE alphabet and dot(.)\")(\n            \"model,m\",\n            value<std::string>(&option_.attenuation_model_param),\n            BX_TOKEN_OFFERING_CURVE)(\n            \"fee,f\",\n            value<uint64_t>(&argument_.fee)->default_value(bc::min_fee_to_issue_token),\n            \"The fee of tx. minimum is 10000 UCN.\")(\n            \"percentage,p\",\n            value<uint32_t>(&argument_.percentage)->default_value(20),\n            \"Percentage of fee send to miner. minimum is 20.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string symbol;\n        uint64_t fee;\n        uint32_t percentage;\n    } argument_;\n\n    struct option\n    {\n        std::string attenuation_model_param;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/registeruid.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ registeruid *************************/\n\nclass registeruid : public command_extension\n{\n  public:\n    static const char *symbol() { return \"registeruid\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"registeruid \"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"ADDRESS\", 1)\n            .add(\"SYMBOL\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(argument_.address, \"ADDRESS\", variables, input, raw);\n        load_input(argument_.symbol, \"SYMBOL\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"ADDRESS\",\n            value<std::string>(&argument_.address)->required(),\n            \"The address will be bound to, can change to other addresses later.\")(\n            \"SYMBOL\",\n            value<std::string>(&argument_.symbol)->required(),\n            \"The symbol of global unique UC Digital Identity Destination/Index, supports alphabets/numbers/(“@”, “.”, “_”, “-“), case-sensitive, maximum length is 64.\")(\n            \"fee,f\",\n            value<uint64_t>(&argument_.fee)->default_value(bc::min_fee_to_register_uid),\n            \"The fee of tx. defaults to 100 UCN.\")(\n            \"percentage,p\",\n            value<uint32_t>(&argument_.percentage)->default_value(20),\n            \"Percentage of fee send to miner. minimum is 20 which is the default value.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string address;\n        std::string symbol;\n        uint64_t fee;\n        uint32_t percentage;\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/sendfrom.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ sendfrom *************************/\n\nclass sendfrom : public send_command\n{\n  public:\n    static const char *symbol() { return \"sendfrom\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"send UCN from a specified uid/address of this wallet to target uid/address, mychange goes to from_uid/address.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"FROM_\", 1)\n            .add(\"TO_\", 1)\n            .add(\"AMOUNT\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(argument_.from, \"FROM_\", variables, input, raw);\n        load_input(argument_.to, \"TO_\", variables, input, raw);\n        load_input(argument_.amount, \"AMOUNT\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"FROM_\",\n            value<std::string>(&argument_.from)->required(),\n            \"Send from this uid/address\")(\n            \"TO_\",\n            value<std::string>(&argument_.to)->required(),\n            \"Send to this uid/address\")(\n            \"AMOUNT\",\n            value<uint64_t>(&argument_.amount)->required(),\n            \"UCN integer bits.\")(\n            \"change,c\",\n            value<std::string>(&option_.change)->default_value(\"\"),\n            \"Change to this uid/address,should be yours.\")(\n            \"memo,m\",\n            value<std::string>(&option_.memo)->default_value(\"\"),\n            \"The memo to descript transaction\")(\n            \"fee,f\",\n            value<uint64_t>(&option_.fee)->default_value(bc::min_tx_fee),\n            \"Transaction fee. defaults to 200000 UCN bits.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        argument() : from(\"\"), to(\"\"), amount(0){};\n        std::string from;\n        std::string to;\n        uint64_t amount;\n    } argument_;\n\n    struct option\n    {\n        option() : fee(10000), memo(\"\"), change(\"\"){};\n\n        uint64_t fee;\n        std::string memo;\n        std::string change;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/sendrawtx.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ sendrawtx *************************/\n\nclass sendrawtx : public command_extension\n{\n  public:\n    static const char *symbol() { return \"sendrawtx\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"sendrawtx \"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"TRANSACTION\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(argument_.transaction, \"TRANSACTION\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"TRANSACTION\",\n            value<explorer::config::transaction>(&argument_.transaction)->required(),\n            \"The input Base16 transaction to broadcast.\")(\n            \"fee,f\",\n            value<uint64_t>(&argument_.fee)->default_value(bc::min_tx_fee),\n            \"The tx fee. default_value 200000 UCN bits.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        explorer::config::transaction transaction;\n        uint64_t fee;\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/sendto.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nclass sendto : public send_command\n{\n  public:\n    static const char *symbol() { return \"sendto\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"send UCN to a targert uid/address.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"TO_\", 1)\n            .add(\"AMOUNT\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(argument_.to, \"TO_\", variables, input, raw);\n        load_input(argument_.amount, \"AMOUNT\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"TO_\",\n            value<std::string>(&argument_.to)->required(),\n            \"Send to this uid/address\")(\n            \"AMOUNT\",\n            value<uint64_t>(&argument_.amount)->required(),\n            \"UCN integer bits.\")(\n            \"change,c\",\n            value<std::string>(&option_.change)->default_value(\"\"),\n            \"Change to this uid/address,should be yours.\")(\n            \"memo,m\",\n            value<std::string>(&option_.memo)->default_value(\"\"),\n            \"Attached memo for this transaction.\")(\n            \"fee,f\",\n            value<uint64_t>(&option_.fee)->default_value(bc::min_tx_fee),\n            \"Transaction fee. defaults to 200000 UCN bits.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        argument() : to(\"\"){};\n        std::string to;\n        uint64_t amount;\n    } argument_;\n\n    struct option\n    {\n        option() : fee(10000), memo(\"\"), change(\"\"){};\n\n        uint64_t fee;\n        std::string memo;\n        std::string change;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/sendtokenfrom.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ sendtokenfrom *************************/\n\nclass sendtokenfrom : public command_extension\n{\n  public:\n    static const char *symbol() { return \"sendtokenfrom\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"sendtokenfrom\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"FROM_\", 1)\n            .add(\"TO_\", 1)\n            .add(\"SYMBOL\", 1)\n            .add(\"AMOUNT\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(argument_.from, \"FROM_\", variables, input, raw);\n        load_input(argument_.to, \"TO_\", variables, input, raw);\n        load_input(argument_.symbol, \"SYMBOL\", variables, input, raw);\n        load_input(argument_.amount, \"AMOUNT\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"FROM_\",\n            value<std::string>(&argument_.from)->required(),\n            \"From uid/address\")(\n            \"TO_\",\n            value<std::string>(&argument_.to)->required(),\n            \"Target uid/address\")(\n            \"SYMBOL\",\n            value<std::string>(&argument_.symbol)->required(),\n            \"Token symbol\")(\n            \"AMOUNT\",\n            value<uint64_t>(&argument_.amount)->required(),\n            \"Token integer bits. see token <decimal_number>.\")(\n            \"change,c\",\n            value<std::string>(&option_.change),\n            \"Change to this uid/address\")(\n            \"model,m\",\n            value<std::string>(&option_.attenuation_model_param),\n            BX_TOKEN_OFFERING_CURVE)(\n            \"fee,f\",\n            value<uint64_t>(&option_.fee)->default_value(bc::min_tx_fee),\n            \"Transaction fee. defaults to 200000 UCN bits.\")(\n            \"memo,i\",\n            value<std::string>(&option_.memo),\n            \"Attached memo for this transaction.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string from;\n        std::string to;\n        std::string symbol;\n        uint64_t amount;\n    } argument_;\n\n    struct option\n    {\n        std::string attenuation_model_param;\n        std::string memo;\n        std::string change;\n        uint64_t fee;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/sendtokento.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ sendtokento *************************/\n\nclass sendtokento : public command_extension\n{\n  public:\n    static const char *symbol() { return \"sendtokento\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"sendtokento\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"TO_\", 1)\n            .add(\"TOKEN\", 1)\n            .add(\"AMOUNT\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(argument_.to, \"TO_\", variables, input, raw);\n        load_input(argument_.symbol, \"TOKEN\", variables, input, raw);\n        load_input(argument_.amount, \"AMOUNT\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"TO_\",\n            value<std::string>(&argument_.to)->required(),\n            \"Token receiver uid/address.\")(\n            \"TOKEN\",\n            value<std::string>(&argument_.symbol)->required(),\n            \"Token token symbol.\")(\n            \"AMOUNT\",\n            value<uint64_t>(&argument_.amount)->required(),\n            \"Token integer bits. see token <decimal_number>.\")(\n            \"change,c\",\n            value<std::string>(&option_.change)->default_value(\"\"),\n            \"Change to this uid/address\")(\n            \"model,m\",\n            value<std::string>(&option_.attenuation_model_param)->default_value(\"\"),\n            BX_TOKEN_OFFERING_CURVE)(\n            \"fee,f\",\n            value<uint64_t>(&option_.fee)->default_value(bc::min_tx_fee),\n            \"Transaction fee. defaults to 200000 UCN bits.\")(\n            \"memo,i\",\n            value<std::string>(&option_.memo)->default_value(\"\"),\n            \"Attached memo for this transaction.\");\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string to;\n        std::string symbol;\n        uint64_t amount;\n    } argument_;\n\n    struct option\n    {\n        std::string attenuation_model_param;\n        std::string memo;\n        std::string change;\n        uint64_t fee;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/sendtomulti.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ sendtomulti *************************/\n\nclass sendtomulti : public send_command\n{\n  public:\n    static const char *symbol() { return \"sendtomulti\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"send UCN to multi target.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Send to more target. \")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"receivers,r\",\n            value<std::vector<std::string>>(&argument_.receivers)->required(),\n            \"Send to [uid/address:ucn_bits].\")(\n            \"change,c\",\n            value<std::string>(&option_.change),\n            \"Change to this uid/address,should be yours.\")(\n            \"fee,f\",\n            value<uint64_t>(&option_.fee)->default_value(bc::min_tx_fee),\n            \"Transaction fee. defaults to 200000 UCN bits.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::vector<std::string> receivers;\n    } argument_;\n\n    struct option\n    {\n        option() : fee(10000), change(\"\"){};\n\n        uint64_t fee;\n        std::string change;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/setminingwallet.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ setminingwallet *************************/\n\nclass setminingwallet : public command_extension\n{\n  public:\n    static const char *symbol() { return \"setminingwallet\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"setminingwallet when pool mining.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"PAYMENT_ADDRESS\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(auth_.auth, \"PAYMENT_ADDRESS\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"PAYMENT_ADDRESS\",\n            value<bc::wallet::payment_address>(&argument_.payment_address)->required(),\n            \"the payment address of this wallet.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        bc::wallet::payment_address payment_address;\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showaddresses.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showaddresses *************************/\n\nclass showaddresses : public command_extension\n{\n  public:\n    static const char *symbol() { return \"showaddresses\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"List available addresses of this wallet.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH);\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showaddresstoken.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showaddresstoken *************************/\n\nclass showaddresstoken : public command_extension\n{\n  public:\n    static const char *symbol() { return \"showaddresstoken\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"showaddresstoken \"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"ADDRESS\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(argument_.address, \"ADDRESS\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"ADDRESS\",\n            value<std::string>(&argument_.address)->required(),\n            \"address\")(\n            \"cert,c\",\n            value<bool>(&option_.is_cert)->default_value(false)->zero_tokens(),\n            \"If specified, then only get related cert. Default is not specified.\")(\n            \"deposited,d\",\n            value<bool>(&option_.deposited)->zero_tokens()->default_value(false),\n            \"If specified, then only get deposited tokens. Default is not specified.\")(\n            \"symbol,s\",\n            value<std::string>(&option_.symbol)->default_value(\"\"),\n            \"Token symbol.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string address;\n    } argument_;\n\n    struct option\n    {\n        option() : is_cert(false),\n                   deposited(false)\n        {\n        }\n\n        bool is_cert;\n        bool deposited;\n        std::string symbol;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showaddressucn.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showaddressucn *************************/\n\nclass showaddressucn : public command_extension\n{\n  public:\n    static const char *symbol() { return \"showaddressucn\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"Get any valid target address UCN balance.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"PAYMENT_ADDRESS\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.auth, \"PAYMENT_ADDRESS\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"PAYMENT_ADDRESS\",\n            value<bc::wallet::payment_address>(&argument_.address)->required(),\n            \"The payment address. If not specified the address is read from STDIN.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        bc::wallet::payment_address address;\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showbalance.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showbalance *************************/\n\nclass showbalance : public command_extension\n{\n  public:\n    static const char *symbol() { return \"showbalance\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"Show total balance details of this wallet.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH);\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showbalances.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showbalances *************************/\n\nclass showbalances : public command_extension\n{\n  public:\n    static const char *symbol() { return \"showbalances\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"List balance details of each address of this wallet. defaults show non-zero unspent address.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"deposited,d\",\n            value<bool>(&option_.deposited)->zero_tokens()->default_value(false),\n            \"list deposited UCNs, default is false.\")(\n            \"nozero,n\",\n            value<bool>(&option_.non_zero)->zero_tokens()->default_value(false),\n            \"Default is false.\")(\n            \"greater_equal,g\",\n            value<uint64_t>(&option_.greater)->default_value(0),\n            \"Greater than UCN bits.\")(\n            \"lesser_equal,l\",\n            value<uint64_t>(&option_.lesser)->default_value(0),\n            \"Lesser than UCN bits.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH);\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n    } argument_;\n\n    struct option\n    {\n        bool non_zero;\n        bool deposited;\n        uint64_t greater;\n        uint64_t lesser;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showblock.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showblock *************************/\n\nclass showblock : public command_extension\n{\n  public:\n    static const char *symbol() { return \"showblock\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"Get sepcified block header from wallet.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"HASH_OR_HEIGH\", 1)\n            .add(\"json\", 1)\n            .add(\"tx_json\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(argument_.hash_or_height, \"HASH_OR_HEIGH\", variables, input, raw);\n        load_input(argument_.hash_or_height, \"json\", variables, input, raw);\n        load_input(argument_.hash_or_height, \"tx_json\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"HASH_OR_HEIGH\",\n            value<std::string>(&argument_.hash_or_height)->required(),\n            \"block hash or block height\")(\n            \"json\",\n            value<bool>(&option_.json)->default_value(true),\n            \"Json/Raw format, default is '--json=true'.\")(\n            \"tx_json\",\n            value<bool>(&option_.tx_json)->default_value(true),\n            \"Json/Raw format for txs, default is '--tx_json=true'.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string hash_or_height;\n    } argument_;\n\n    struct option\n    {\n        bool json;\n        bool tx_json;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showblockheader.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChain/explorer/config/hashtype.hpp>\n#include <UChain/explorer/config/header.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showblockheader *************************/\n\nclass showblockheader : public command_extension\n{\n  public:\n    showblockheader() noexcept {};\n    showblockheader(const std::string &other)\n    {\n        if (other == \"getbestblockhash\")\n            option_.is_getbestblockhash = true;\n    }\n    static const char *symbol() { return \"showblockheader\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"showblockheader, alias as fetch-header/getbestblockhash/getbestblockheader.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata();\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"hash,s\",\n            value<bc::config::hash256>(&option_.hash),\n            \"The Base16 block hash.\")(\n            \"height,t\",\n            value<uint32_t>(&option_.height),\n            \"The block height.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n    } argument_;\n\n    struct option\n    {\n        option() : hash(),\n                   height(std::numeric_limits<uint32_t>::max())\n        {\n        }\n\n        bool is_getbestblockhash{false};\n        bc::config::hash256 hash;\n        uint32_t height;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showblockheaders.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChain/explorer/config/hashtype.hpp>\n#include <UChain/explorer/config/header.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showblockheaders *************************/\n\nclass showblockheaders : public command_extension\n{\n  public:\n    static const char *symbol() { return \"showblockheaders\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"List block headers of this wallet.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth),\n            BX_WALLET_AUTH)(\n            \"height,e\",\n            value<libbitcoin::explorer::commands::colon_delimited2_item<uint64_t, uint64_t>>(&option_.height)->required(),\n            \"Get block headers according height eg: -e start-height:end-height will return tx between [start-height, end-height], \\\n            support 100 headers at most.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        argument(){};\n        uint64_t limit;\n        uint64_t index;\n    } argument_;\n\n    struct option\n    {\n        option() : height(0, 0){};\n        libbitcoin::explorer::commands::colon_delimited2_item<uint64_t, uint64_t> height;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showblockheight.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/node_method_wrapper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showblockheight *************************/\n\nclass showblockheight : public command_extension\n{\n  public:\n    showblockheight() noexcept {};\n    showblockheight(const std::string &other)\n    {\n        if (other == \"fetch-height\")\n            option_.is_fetch_height = true;\n    }\n\n    static const char *symbol() { return \"showblockheight\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"Get last height. Alias as fetch-height.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"ADMINNAME\", 1)\n            .add(\"ADMINAUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"ADMINNAME\", variables, input, raw);\n        load_input(auth_.auth, \"ADMINAUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"ADMINNAME\",\n            value<std::string>(&auth_.name),\n            BX_ADMIN_NAME)(\n            \"ADMINAUTH\",\n            value<std::string>(&auth_.auth),\n            BX_ADMIN_AUTH);\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n    } argument_;\n\n    struct option\n    {\n        bool is_fetch_height{false};\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showcandidate.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showcandidate *************************/\n\nclass showcandidate : public command_extension\n{\n  public:\n    static const char *symbol() { return \"showcandidate\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"Get information of candidate.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"SYMBOL\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(argument_.symbol, \"SYMBOL\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"SYMBOL\",\n            value<std::string>(&argument_.symbol),\n            \"Candidate symbol. If not specified then show whole network candidate symbols.\")(\n            \"limit,l\",\n            value<uint32_t>(&option_.limit)->default_value(100),\n            \"candidate count per page.\")(\n            \"index,i\",\n            value<uint32_t>(&option_.index)->default_value(1),\n            \"Page index.\")(\n            \"current,c\",\n            value<bool>(&option_.show_current)->default_value(false)->zero_tokens(),\n            \"If specified then show the lastest information of specified candidate. Default is not specified.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        argument() : symbol()\n        {\n        }\n\n        std::string symbol;\n    } argument_;\n\n    struct option\n    {\n        bool show_current;\n        uint32_t index;\n        uint32_t limit;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showcandidates.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showcandidates *************************/\n\nclass showcandidates : public command_extension\n{\n  public:\n    static const char *symbol() { return \"showcandidates\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"List candidates.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth),\n            BX_WALLET_AUTH);\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n    } argument_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showheaderext.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showheaderext *************************/\n\nclass showheaderext : public command_extension\n{\n  public:\n    static const char *symbol() { return \"showheaderext\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"showheaderext \"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"NUMBER\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(argument_.number, \"NUMBER\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"NUMBER\",\n            value<std::string>(&argument_.number)->required(),\n            \"Block number, or earliest, latest or pending\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string number;\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showinfo.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showinfo *************************/\n\nclass showinfo : public command_extension\n{\n  public:\n    static const char *symbol() { return \"showinfo\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"showinfo \"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"ADMINNAME\", 1)\n            .add(\"ADMINAUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"ADMINNAME\", variables, input, raw);\n        load_input(auth_.auth, \"ADMINAUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"ADMINNAME\",\n            value<std::string>(&auth_.name),\n            BX_ADMIN_NAME)(\n            \"ADMINAUTH\",\n            value<std::string>(&auth_.auth),\n            BX_ADMIN_AUTH);\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showminers.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/node_method_wrapper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showminers *************************/\n\nclass showminers : public command_extension\n{\n  public:\n    showminers() noexcept {};\n\n    static const char *symbol() { return \"showminers\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"Get blockchain miners for now.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"ADMINNAME\", 1)\n            .add(\"ADMINAUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"ADMINNAME\", variables, input, raw);\n        load_input(auth_.auth, \"ADMINAUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"ADMINNAME\",\n            value<std::string>(&auth_.name),\n            BX_ADMIN_NAME)(\n            \"ADMINAUTH\",\n            value<std::string>(&auth_.auth),\n            BX_ADMIN_AUTH);\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n    } argument_;\n\n    struct option\n    {\n        bool is_fetch_height{false};\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showmininginfo.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showmininginfo *************************/\n\nclass showmininginfo : public command_extension\n{\n  public:\n    static const char *symbol() { return \"showmininginfo\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"showmininginfo \"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"ADMINNAME\", 1)\n            .add(\"ADMINAUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"ADMINNAME\", variables, input, raw);\n        load_input(auth_.auth, \"ADMINAUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"ADMINNAME\",\n            value<std::string>(&auth_.name),\n            BX_ADMIN_NAME)(\n            \"ADMINAUTH\",\n            value<std::string>(&auth_.auth),\n            BX_ADMIN_AUTH);\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showmultisigaddresses.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showmultisigaddresses *************************/\n\nclass showmultisigaddresses : public command_extension\n{\n  public:\n    static const char *symbol() { return \"showmultisigaddresses\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"showmultisigaddresses \"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH);\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        argument()\n        {\n        }\n    } argument_;\n\n    struct option\n    {\n        option()\n            : index(0)\n        {\n        }\n\n        uint16_t index;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showpeers.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showpeers *************************/\n\nclass showpeers : public command_extension\n{\n  public:\n    static const char *symbol() { return \"showpeers\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"showpeers \"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"ADMINNAME\", 1)\n            .add(\"ADMINAUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"ADMINNAME\", variables, input, raw);\n        load_input(auth_.auth, \"ADMINAUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"ADMINNAME\",\n            value<std::string>(&auth_.name),\n            BX_ADMIN_NAME)(\n            \"ADMINAUTH\",\n            value<std::string>(&auth_.auth),\n            BX_ADMIN_AUTH);\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showtoken.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showtoken *************************/\n\nclass showtoken : public command_extension\n{\n  public:\n    static const char *symbol() { return \"showtoken\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"Show existed tokens details from UC blockchain.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"SYMBOL\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(argument_.symbol, \"SYMBOL\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"SYMBOL\",\n            value<std::string>(&argument_.symbol),\n            \"Token symbol. If not specified, will show whole network token symbols.\")(\n            \"cert,c\",\n            value<bool>(&option_.is_cert)->default_value(false)->zero_tokens(),\n            \"If specified, then only get related cert. Default is not specified.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        argument() : symbol()\n        {\n        }\n\n        std::string symbol;\n    } argument_;\n\n    struct option\n    {\n        bool is_cert;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showtokens.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showtokens *************************/\n\nclass showtokens : public command_extension\n{\n  public:\n    static const char *symbol() { return \"showtokens\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"list tokens details.(list all the tokens when WALLET_NAME is null)\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth),\n            BX_WALLET_AUTH)(\n            \"cert,c\",\n            value<bool>(&option_.is_cert)->default_value(false)->zero_tokens(),\n            \"If specified, then only get related cert. Default is not specified.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n    } argument_;\n\n    struct option\n    {\n        bool is_cert;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showtokenview.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showtokenview *************************/\n\nclass showtokenview : public command_extension\n{\n  public:\n    static const char *symbol() { return \"showtokenview\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"Show token owners from UC blockchain. \"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"SYMBOL\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(argument_.symbol, \"SYMBOL\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"SYMBOL\",\n            value<std::string>(&argument_.symbol),\n            \"Token symbol.\")(\n            \"limit,l\",\n            value<uint64_t>(&argument_.limit)->default_value(100),\n            \"Token count per page.\")(\n            \"index,i\",\n            value<uint64_t>(&argument_.index)->default_value(1),\n            \"Page index.\")(\n            \"deposit,d\",\n            value<bool>(&option_.is_deposit)->default_value(false)->zero_tokens(),\n            \"If specified, then only get related cert. Default is not specified.\");\n\n        return options;\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string symbol;\n        uint64_t limit;\n        uint64_t index;\n    } argument_;\n\n    struct option\n    {\n        bool is_deposit;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showtx.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showtx *************************/\n\nclass showtx : public command_extension\n{\n  public:\n    showtx() noexcept {};\n    showtx(const std::string &other)\n    {\n        if (other == \"fetch-tx\")\n            option_.is_fetch_tx = true;\n    }\n\n    static const char *symbol() { return \"showtx\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"showtx alias as fetch-tx/gettransaction\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"HASH\", 1)\n            .add(\"json\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(argument_.hash, \"HASH\", variables, input, raw);\n        load_input(argument_.hash, \"json\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"json\",\n            value<bool>(&option_.json)->default_value(true),\n            \"Json/Raw format, default is '--json=true'.\")(\n            \"HASH\",\n            value<bc::config::hash256>(&argument_.hash)->required(),\n            \"The Base16 transaction hash of the transaction to get. If not specified the transaction hash is read from STDIN.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        bc::config::hash256 hash;\n    } argument_;\n\n    struct option\n    {\n        bool json;\n        bool is_fetch_tx{false};\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showtxpool.hpp",
    "content": "/*\n * showtxpool.hpp\n *\n *  Created on: Jul 3, 2017\n *      Author: jiang\n */\n\n#ifndef INCLUDE_UChain_EXPLORER_EXTENSIONS_WALLET_showtxpool_HPP_\n#define INCLUDE_UChain_EXPLORER_EXTENSIONS_WALLET_showtxpool_HPP_\n\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showtxpool *************************/\n\nclass showtxpool : public command_extension\n{\n  public:\n    static const char *symbol() { return \"showtxpool\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"Returns all transactions in memory pool.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"ADMINNAME\", 1)\n            .add(\"ADMINAUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"ADMINNAME\", variables, input, raw);\n        load_input(auth_.auth, \"ADMINAUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"json,j\",\n            value<bool>(&option_.json)->default_value(true),\n            \"Json format or Raw format, default is Json(true).\")(\n            \"ADMINNAME\",\n            value<std::string>(&auth_.name),\n            BX_ADMIN_NAME)(\n            \"ADMINAUTH\",\n            value<std::string>(&auth_.auth),\n            BX_ADMIN_AUTH);\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n    } argument_;\n\n    struct option\n    {\n        bool json;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n\n#endif /* INCLUDE_UChain_EXPLORER_EXTENSIONS_WALLET_showtxpool_HPP_ */\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showtxs.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showtxs *************************/\n\nclass showtxs : public command_extension\n{\n  public:\n    static const char *symbol() { return \"showtxs\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"List transactions details of this wallet.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name),\n            BX_ADMIN_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth),\n            BX_ADMIN_AUTH)(\n            \"address,a\",\n            value<std::string>(&argument_.address),\n            \"Address.\")(\n            \"height,e\",\n            value<libbitcoin::explorer::commands::colon_delimited2_item<uint64_t, uint64_t>>(&option_.height),\n            \"Get tx according height eg: -e start-height:end-height will return tx between [start-height, end-height)\")(\n            \"symbol,s\",\n            value<std::string>(&argument_.symbol),\n            \"Token symbol.\")(\n            \"limit,l\",\n            value<uint64_t>(&argument_.limit)->default_value(100),\n            \"Transaction count per page.\")(\n            \"index,i\",\n            value<uint64_t>(&argument_.index)->default_value(1),\n            \"Page index.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        argument() : address(\"\"), symbol(\"\"), limit(100), index(0){};\n        std::string address;\n        std::string symbol;\n        uint64_t limit;\n        uint64_t index;\n    } argument_;\n\n    struct option\n    {\n        option() : height(0, 0){};\n        libbitcoin::explorer::commands::colon_delimited2_item<uint64_t, uint64_t> height;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showuid.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showuid *************************/\n\nclass showuid : public command_extension\n{\n  public:\n    static const char *symbol() { return \"showuid\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"showuid \"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"UidOrAddress\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(option_.symbol, \"UidOrAddress\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"UidOrAddress\",\n            value<std::string>(&option_.symbol),\n            \"Uid symbol or standard address; If no input parameters, then display whole network UIDs.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n    } argument_;\n\n    struct option\n    {\n        std::string symbol;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showuids.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showuids *************************/\n\nclass showuids : public command_extension\n{\n  public:\n    static const char *symbol() { return \"showuids\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"list UIDs in detail.(list all the UIDs when WALLET_NAME is null)\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth),\n            BX_WALLET_AUTH)(\n            \"limit,l\",\n            value<uint64_t>(&argument_.limit)->default_value(100),\n            \"UID count per page.Default is 100.\")(\n            \"index,i\",\n            value<uint64_t>(&argument_.index)->default_value(1),\n            \"Page index. Default is 1.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        argument() : limit(100), index(1){};\n        uint64_t limit;\n        uint64_t index;\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showvote.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showvote *************************/\n\nclass showvote : public command_extension\n{\n  public:\n    static const char *symbol() { return \"showvote\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"show vote amount of uid from a START_HEIGHT to a END_HEIGHT\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"UID\", 1)\n            .add(\"START_HEIGHT\", 1)\n            .add(\"END_HEIGHT\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(argument_.uid, \"UID\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"UID\",\n            value<std::string>(&argument_.uid)->required(),\n            \"uid\")(\n            \"START_HEIGHT\",\n            value<uint64_t>(&argument_.startheight)->required(),\n            \"The start height of blockchain.\")(\n            \"END_HEIGHT\",\n            value<uint64_t>(&argument_.endheight)->required(),\n            \"The end height of blockchain.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string uid;\n        uint64_t startheight;\n        uint64_t endheight;\n    } argument_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showwallettoken.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showwallettoken *************************/\n\nclass showwallettoken : public command_extension\n{\n  public:\n    static const char *symbol() { return \"showwallettoken\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"showwallettoken \"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"SYMBOL\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(argument_.symbol, \"SYMBOL\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"SYMBOL\",\n            value<std::string>(&argument_.symbol),\n            \"Token symbol.\")(\n            \"cert,c\",\n            value<bool>(&option_.is_cert)->default_value(false)->zero_tokens(),\n            \"If specified, then only get related cert. Default is not specified.\")(\n            \"deposited,d\",\n            value<bool>(&option_.deposited)->zero_tokens()->default_value(false),\n            \"If specified, then only get deposited tokens. Default is not specified.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string symbol;\n    } argument_;\n\n    struct option\n    {\n        option() : is_cert(false),\n                   deposited(false)\n        {\n        }\n\n        bool is_cert;\n        bool deposited;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/showwork.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showwork *************************/\n\nclass showwork : public command_extension\n{\n  public:\n    static const char *symbol() { return \"showwork\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"showwork to get mining info\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"ADMINNAME\", 1)\n            .add(\"ADMINAUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"ADMINNAME\", variables, input, raw);\n        load_input(auth_.auth, \"ADMINAUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"ADMINNAME\",\n            value<std::string>(&auth_.name),\n            BX_ADMIN_NAME)(\n            \"ADMINAUTH\",\n            value<std::string>(&auth_.auth),\n            BX_ADMIN_AUTH);\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/shutdown.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ shutdown *************************/\n\nclass shutdown : public command_extension\n{\n  public:\n    static const char *symbol() { return \"shutdown\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"stop ucd.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"ADMINNAME\", 1)\n            .add(\"ADMINAUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"ADMINNAME\", variables, input, raw);\n        load_input(auth_.auth, \"ADMINAUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"ADMINNAME\",\n            value<std::string>(&auth_.name),\n            \"admin name.\")(\n            \"ADMINAUTH\",\n            value<std::string>(&auth_.auth),\n            \"admin password/authorization.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/signmultisigtx.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nclass signmultisigtx : public command_extension\n{\n  public:\n    static const char *symbol() { return \"signmultisigtx\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"signmultisigtx \"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"TRANSACTION\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(argument_.transaction, \"TRANSACTION\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"TRANSACTION\",\n            value<explorer::config::transaction>(&argument_.transaction)->required(),\n            \"The input Base16 transaction to sign.\")(\n            \"selfpublickey,s\",\n            value<std::string>(&option_.self_publickey)->default_value(\"\"),\n            \"The private key of this public key will be used to sign.\")(\n            \"broadcast,b\",\n            value<bool>(&option_.broadcast_flag)->default_value(false)->zero_tokens(),\n            \"Broadcast the tx if it is fullly signed, disabled by default.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        explorer::config::transaction transaction;\n    } argument_;\n\n    struct option\n    {\n        option()\n            : broadcast_flag(false), self_publickey(\"\")\n        {\n        }\n\n        bool broadcast_flag;\n        std::string self_publickey;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/signrawtx.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ signrawtx *************************/\n\nclass signrawtx : public command_extension\n{\n  public:\n    static const char *symbol() { return \"signrawtx\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"signrawtx \"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"TRANSACTION\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(argument_.transaction, \"TRANSACTION\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"TRANSACTION\",\n            value<explorer::config::transaction>(&argument_.transaction)->required(),\n            \"The input Base16 transaction to sign.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        explorer::config::transaction transaction;\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/startmining.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ startmining *************************/\n\nclass startmining : public command_extension\n{\n  public:\n    static const char *symbol() { return \"startmining\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"start CPU solo mining. You have to setminingwallet firstly.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"ADDRESS\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(argument_.address, \"ADDRESS\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"ADDRESS\",\n            value<std::string>(&argument_.address)->required(),\n            \"The mining target address. Defaults to empty, means a new address will be generated.\")(\n            \"number,n\",\n            value<uint16_t>(&option_.number)->default_value(0),\n            \"The number of mining blocks, useful for testing. Defaults to 0, means no limit.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string address;\n    } argument_;\n\n    struct option\n    {\n        uint16_t number;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/stopmining.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ stopmining *************************/\n\nclass stopmining : public command_extension\n{\n  public:\n    static const char *symbol() { return \"stopmining\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"stop CPU solo mining.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_ADMIN_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_ADMIN_AUTH);\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/submitwork.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ submitwork *************************/\n\nclass submitwork : public command_extension\n{\n  public:\n    static const char *symbol() { return \"submitwork\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"submitwork to submit mining result.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"NONCE\", 1)\n            .add(\"HEADERHASH\", 1)\n            .add(\"MIXHASH\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(argument_.nonce, \"NONCE\", variables, input, raw);\n        load_input(argument_.header_hash, \"HEADERHASH\", variables, input, raw);\n        load_input(argument_.mix_hash, \"MIXHASH\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"NONCE\",\n            value<std::string>(&argument_.nonce)->required(),\n            \"nonce. without leading 0x\")(\n            \"HEADERHASH\",\n            value<std::string>(&argument_.header_hash)->required(),\n            \"header hash. with leading 0x\")(\n            \"MIXHASH\",\n            value<std::string>(&argument_.mix_hash)->required(),\n            \"mix hash. with leading 0x\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string nonce;\n        std::string mix_hash;\n        std::string header_hash;\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/swaptoken.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n#define DEFAULT_SWAP_FEE 100000000\n\n/************************ destroy *************************/\n\nclass swaptoken : public command_extension\n{\n  public:\n    static const char *symbol() { return \"swaptoken\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"Swap tokens for crosschain transaction.\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"TO_\", 1)\n            .add(\"SYMBOL\", 1)\n            .add(\"AMOUNT\", 1)\n            .add(\"FOREIGN_ADDR\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(argument_.to, \"TO_\", variables, input, raw);\n        load_input(argument_.symbol, \"SYMBOL\", variables, input, raw);\n        load_input(argument_.amount, \"AMOUNT\", variables, input, raw);\n        load_input(argument_.foreign_addr, \"FOREIGN_ADDR\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"TO_\",\n            value<std::string>(&argument_.to)->required(),\n            \"To this uid/address the specific token will be sent. expect to be \\\"crosschain\\\".\")(\n            \"SYMBOL\",\n            value<std::string>(&argument_.symbol)->required(),\n            \"Token symbol\")(\n            \"AMOUNT\",\n            value<uint64_t>(&argument_.amount)->required(),\n            \"Token integer bits. see token <decimal_number>.\")(\n            \"FOREIGN_ADDR\",\n            value<std::string>(&argument_.foreign_addr)->required(),\n            \"To this address of the destination chain to swap the token.\")(\n            \"change,c\",\n            value<std::string>(&option_.change),\n            \"Change to this uid/address\")(\n            \"from,d\",\n            value<std::string>(&option_.from),\n            \"From this uid/address\")(\n            \"swapfee,s\",\n            value<uint64_t>(&option_.swapfee)->default_value(DEFAULT_SWAP_FEE),\n            \"Transaction fee for crosschain token swap. defaults to 1 UCN\")(\n            \"fee,f\",\n            value<uint64_t>(&option_.fee)->default_value(bc::min_tx_fee),\n            \"Transaction fee for miners. defaults to 200000 UCN bits.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string to;\n        std::string symbol;\n        uint64_t amount;\n        std::string foreign_addr;\n    } argument_;\n\n    struct option\n    {\n        std::string from;\n        uint64_t swapfee;\n        uint64_t fee;\n        std::string change;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/transfercandidate.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ transfercandidate *************************/\n\nclass transfercandidate : public command_extension\n{\n  public:\n    static const char *symbol() { return \"transfercandidate\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"Transfer candidate to other UID\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"TOUID\", 1)\n            .add(\"SYMBOL\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(argument_.to, \"TOUID\", variables, input, raw);\n        load_input(argument_.symbol, \"SYMBOL\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"TOUID\",\n            value<std::string>(&argument_.to)->required(),\n            \"Target uid\")(\n            \"SYMBOL\",\n            value<std::string>(&argument_.symbol)->required(),\n            \"Token candidate symbol\")(\n            \"fee,f\",\n            value<uint64_t>(&argument_.fee)->default_value(bc::min_tx_fee),\n            \"Transaction fee. defaults to 200000 UCN bits.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string to;\n        std::string symbol;\n        uint64_t fee;\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/transfercert.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ transfercert *************************/\n\nclass transfercert : public command_extension\n{\n  public:\n    static const char *symbol() { return \"transfercert\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"transfercert\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"TOUID\", 1)\n            .add(\"SYMBOL\", 1)\n            .add(\"CERT\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(argument_.to, \"TOUID\", variables, input, raw);\n        load_input(argument_.symbol, \"SYMBOL\", variables, input, raw);\n        load_input(argument_.cert, \"CERT\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"TOUID\",\n            value<std::string>(&argument_.to)->required(),\n            \"Target uid\")(\n            \"SYMBOL\",\n            value<std::string>(&argument_.symbol)->required(),\n            \"Cert symbol\")(\n            \"CERT\",\n            value<std::string>(&argument_.cert)->required(),\n            \"Cert type name. eg. ISSUE, DOMAIN or NAMING\")(\n            \"fee,f\",\n            value<uint64_t>(&argument_.fee)->default_value(bc::min_tx_fee),\n            \"Transaction fee. defaults to 200000 UCN bits.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string to;\n        std::string symbol;\n        std::string cert;\n        uint64_t fee;\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/transferuid.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ transferuid *************************/\n\nclass transferuid : public command_extension\n{\n  public:\n    static const char *symbol() { return \"transferuid\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"transferuid \"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"TOADDRESS\", 1)\n            .add(\"UIDSYMBOL\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(argument_.to, \"TOADDRESS\", variables, input, raw);\n        load_input(argument_.symbol, \"UIDSYMBOL\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"TOADDRESS\",\n            value<std::string>(&argument_.to)->required(),\n            \"Target address\")(\n            \"UIDSYMBOL\",\n            value<std::string>(&argument_.symbol)->required(),\n            \"Uid symbol\")(\n            \"fee,f\",\n            value<uint64_t>(&argument_.fee)->default_value(bc::min_tx_fee),\n            \"Transaction fee. defaults to 200000 UCN bits.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string to;\n        std::string symbol;\n        uint64_t fee;\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/validateaddress.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ validateaddress *************************/\n\nclass validateaddress : public command_extension\n{\n  public:\n    static const char *symbol() { return \"validateaddress\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ctgy_extension & bs) == bs; }\n    const char *description() override { return \"validateaddress \"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"PAYMENT_ADDRESS\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(argument_.address, \"PAYMENT_ADDRESS\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"PAYMENT_ADDRESS\",\n            value<std::string>(&argument_.address),\n            \"Valid payment address. If not specified the address is read from STDIN.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string address;\n    } argument_;\n\n    struct option\n    {\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/commands/vote.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n#include <UChain/explorer/define.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nclass vote : public command_extension\n{\n  public:\n    static const char *symbol() { return \"vote\"; }\n    const char *name() override { return symbol(); }\n    bool category(int bs) override { return (ex_online & bs) == bs; }\n    const char *description() override { return \"vote to a miner's addresss/uid, then lock some UCN for about 48h.1 UCN can get 20 votes\"; }\n\n    arguments_metadata &load_arguments() override\n    {\n        return get_argument_metadata()\n            .add(\"WALLET_NAME\", 1)\n            .add(\"WALLET_AUTH\", 1)\n            .add(\"FROM_\", 1)\n            .add(\"TO_\", 1);\n    }\n\n    void load_fallbacks(std::istream &input,\n                        po::variables_map &variables) override\n    {\n        const auto raw = requires_raw_input();\n        load_input(auth_.name, \"WALLET_NAME\", variables, input, raw);\n        load_input(auth_.auth, \"WALLET_AUTH\", variables, input, raw);\n        load_input(argument_.from, \"FROM_\", variables, input, raw);\n        load_input(argument_.to, \"TO_\", variables, input, raw);\n    }\n\n    options_metadata &load_options() override\n    {\n        using namespace po;\n        options_description &options = get_option_metadata();\n        options.add_options()(\n            BX_HELP_VARIABLE \",h\",\n            value<bool>()->zero_tokens(),\n            \"Get a description and instructions for this command.\")(\n            \"WALLET_NAME\",\n            value<std::string>(&auth_.name)->required(),\n            BX_WALLET_NAME)(\n            \"WALLET_AUTH\",\n            value<std::string>(&auth_.auth)->required(),\n            BX_WALLET_AUTH)(\n            \"FROM_\",\n            value<std::string>(&argument_.from)->required(),\n            \"The uid to deposit some UCN for 48h.\")(\n            \"receivers,r\",\n            value<std::vector<std::string>>(&argument_.to)->required(),\n            \"vote to [uid:ucn_bits].\")(\n            \"fee,f\",\n            value<uint64_t>(&option_.fee)->default_value(bc::min_tx_fee),\n            \"Transaction fee. defaults to 200000 UCN bits.\");\n\n        return options;\n    }\n\n    void set_defaults_from_config(po::variables_map &variables) override\n    {\n    }\n\n    console_result invoke(Json::Value &jv_output,\n                          libbitcoin::server::server_node &node) override;\n\n    struct argument\n    {\n        std::string from;\n        std::vector<std::string> to;\n    } argument_;\n\n    struct option\n    {\n        uint64_t fee;\n    } option_;\n};\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/exception.hpp",
    "content": "/*\n * exception.hpp\n *\n *  Created on: Jun 5, 2017\n *      Author: jiang\n */\n\n#ifndef INCLUDE_UChain_EXPLORER_UTILITIES_EXCEPTION_HPP_\n#define INCLUDE_UChain_EXPLORER_UTILITIES_EXCEPTION_HPP_\n\n#include <boost/format.hpp>\n\n#define DEFINE_EXPLORER_EXCEPTION(class_name, exception_code)                                \\\n    class class_name : public explorer_exception                                             \\\n    {                                                                                        \\\n      public:                                                                                \\\n        class_name(const std::string &message) : explorer_exception(exception_code, message) \\\n        {                                                                                    \\\n        }                                                                                    \\\n    }\n\n#define DEFINE_EXPLORER_EXCEPTION2(class_name)                                                    \\\n    class class_name : public explorer_exception                                                  \\\n    {                                                                                             \\\n      public:                                                                                     \\\n        class_name(uint32_t code, const std::string &message) : explorer_exception(code, message) \\\n        {                                                                                         \\\n        }                                                                                         \\\n    }\n\n#define DEFINE_STD_JSONRPC_EXCEPTION(class_name, code, message) \\\n    class class_name : public explorer_exception                \\\n    {                                                           \\\n      public:                                                   \\\n        class_name() : explorer_exception(code, message)        \\\n        {                                                       \\\n        }                                                       \\\n    }\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\n\nclass explorer_exception : public std::exception\n{\n  public:\n    explorer_exception(uint32_t code, const std::string &message);\n\n    virtual ~explorer_exception() = default;\n    uint32_t code() const { return code_; }\n    const std::string &message() const { return message_; }\n    virtual const char *what() const noexcept override { return message_.data(); }\n\n  private:\n    uint32_t code_;\n    std::string message_;\n};\n\nstd::ostream &operator<<(std::ostream &out, const explorer_exception &ex);\n\nvoid relay_exception(std::stringstream &);\n\nDEFINE_EXPLORER_EXCEPTION(unknown_error_exception, 500);\nDEFINE_EXPLORER_EXCEPTION(fatal_exception, 1001);\nDEFINE_EXPLORER_EXCEPTION(connection_exception, 1011);\nDEFINE_EXPLORER_EXCEPTION(session_expired_exception, 1012);\n\nDEFINE_EXPLORER_EXCEPTION(invalid_command_exception, 1020);\nDEFINE_EXPLORER_EXCEPTION(command_params_exception, 1021);\nDEFINE_EXPLORER_EXCEPTION(command_platform_compat_exception, 1022);\nDEFINE_EXPLORER_EXCEPTION(ui_invoke_explorer_exception, 1023);\nDEFINE_EXPLORER_EXCEPTION(setting_required_exception, 1024);\nDEFINE_EXPLORER_EXCEPTION(block_sync_required_exception, 1025);\n\nDEFINE_EXPLORER_EXCEPTION(argument_exceed_limit_exception, 2001);\nDEFINE_EXPLORER_EXCEPTION(argument_size_invalid_exception, 2002);\nDEFINE_EXPLORER_EXCEPTION(argument_legality_exception, 2003);\nDEFINE_EXPLORER_EXCEPTION(argument_dismatch_exception, 2004);\n\nDEFINE_EXPLORER_EXCEPTION(wallet_existed_exception, 3001);\nDEFINE_EXPLORER_EXCEPTION(wallet_authority_exception, 3002);\nDEFINE_EXPLORER_EXCEPTION(wallet_notfound_exception, 3003);\n\nDEFINE_EXPLORER_EXCEPTION(wallet_name_exception, 3201);\nDEFINE_EXPLORER_EXCEPTION(wallet_length_exception, 3202);\nDEFINE_EXPLORER_EXCEPTION(wallet_address_get_exception, 3203);\n\nDEFINE_EXPLORER_EXCEPTION(wallet_deposit_period_exception, 3301);\nDEFINE_EXPLORER_EXCEPTION(wallet_balance_lack_exception, 3302);\n\nDEFINE_EXPLORER_EXCEPTION(address_list_empty_exception, 4001);\nDEFINE_EXPLORER_EXCEPTION(address_list_nullptr_exception, 4002);\nDEFINE_EXPLORER_EXCEPTION(address_dismatch_wallet_exception, 4003);\nDEFINE_EXPLORER_EXCEPTION(address_amount_exception, 4004);\nDEFINE_EXPLORER_EXCEPTION(address_notfound_exception, 4005);\nDEFINE_EXPLORER_EXCEPTION(address_generate_exception, 4005);\n\nDEFINE_EXPLORER_EXCEPTION(address_invalid_exception, 4010);\nDEFINE_EXPLORER_EXCEPTION(toaddress_empty_exception, 4011);\nDEFINE_EXPLORER_EXCEPTION(toaddress_invalid_exception, 4012);\nDEFINE_EXPLORER_EXCEPTION(toaddress_unrecognized_exception, 4013);\nDEFINE_EXPLORER_EXCEPTION(fromaddress_empty_exception, 4014);\nDEFINE_EXPLORER_EXCEPTION(fromaddress_invalid_exception, 4015);\nDEFINE_EXPLORER_EXCEPTION(fromaddress_unrecognized_exception, 4016);\nDEFINE_EXPLORER_EXCEPTION(address_not_bound_uid_exception, 4017);\n\nDEFINE_EXPLORER_EXCEPTION(token_lack_exception, 5001);\nDEFINE_EXPLORER_EXCEPTION(token_amount_exception, 5002);\nDEFINE_EXPLORER_EXCEPTION(token_notfound_exception, 5003);\nDEFINE_EXPLORER_EXCEPTION(token_type_exception, 5004);\nDEFINE_EXPLORER_EXCEPTION(token_exchange_poundage_exception, 5005);\nDEFINE_EXPLORER_EXCEPTION(token_issue_poundage_exception, 5006);\nDEFINE_EXPLORER_EXCEPTION(token_description_length_exception, 5007);\nDEFINE_EXPLORER_EXCEPTION(token_symbol_duplicate_exception, 5008);\nDEFINE_EXPLORER_EXCEPTION(token_symbol_existed_exception, 5009);\nDEFINE_EXPLORER_EXCEPTION(token_symbol_notfound_exception, 5010);\nDEFINE_EXPLORER_EXCEPTION(token_symbol_length_exception, 5011);\nDEFINE_EXPLORER_EXCEPTION(token_symbol_name_exception, 5012);\nDEFINE_EXPLORER_EXCEPTION(token_issued_not_delete, 5013);\nDEFINE_EXPLORER_EXCEPTION(token_delete_fail, 5014);\nDEFINE_EXPLORER_EXCEPTION(token_secondaryissue_threshold_exception, 5015);\nDEFINE_EXPLORER_EXCEPTION(token_attenuation_model_exception, 5016);\nDEFINE_EXPLORER_EXCEPTION(token_cert_exception, 5017);\nDEFINE_EXPLORER_EXCEPTION(token_cert_existed_exception, 5018);\nDEFINE_EXPLORER_EXCEPTION(token_cert_notfound_exception, 5019);\nDEFINE_EXPLORER_EXCEPTION(token_cert_notowned_exception, 5020);\nDEFINE_EXPLORER_EXCEPTION(token_cert_domain_exception, 5021);\n\nDEFINE_EXPLORER_EXCEPTION(ucn_lack_exception, 5051);\n\nDEFINE_EXPLORER_EXCEPTION(block_height_get_exception, 5101);\nDEFINE_EXPLORER_EXCEPTION(block_last_height_get_exception, 5102);\nDEFINE_EXPLORER_EXCEPTION(block_height_exception, 5103);\nDEFINE_EXPLORER_EXCEPTION(block_hash_get_exception, 5104);\nDEFINE_EXPLORER_EXCEPTION(block_header_get_exception, 5105);\n\nDEFINE_EXPLORER_EXCEPTION(multisig_cosigne_exception, 5201);\nDEFINE_EXPLORER_EXCEPTION(multisig_exist_exception, 5202);\nDEFINE_EXPLORER_EXCEPTION(multisig_notfound_exception, 5203);\nDEFINE_EXPLORER_EXCEPTION(multisig_script_exception, 5204);\nDEFINE_EXPLORER_EXCEPTION(multisig_index_exception, 5205);\nDEFINE_EXPLORER_EXCEPTION(signature_amount_exception, 5220);\nDEFINE_EXPLORER_EXCEPTION(pubkey_amount_exception, 5230);\nDEFINE_EXPLORER_EXCEPTION(pubkey_dismatch_exception, 5231);\nDEFINE_EXPLORER_EXCEPTION(prikey_notfound_exception, 5232);\nDEFINE_EXPLORER_EXCEPTION(pubkey_notfound_exception, 5233);\n\nDEFINE_EXPLORER_EXCEPTION(tx_io_exception, 5301);\nDEFINE_EXPLORER_EXCEPTION(tx_source_exception, 5302);\nDEFINE_EXPLORER_EXCEPTION(tx_sign_exception, 5303);\nDEFINE_EXPLORER_EXCEPTION(tx_validate_exception, 5304);\nDEFINE_EXPLORER_EXCEPTION(tx_broadcast_exception, 5305);\nDEFINE_EXPLORER_EXCEPTION(tx_notfound_exception, 5306);\nDEFINE_EXPLORER_EXCEPTION(tx_asset_value_exception, 5307);\nDEFINE_EXPLORER_EXCEPTION(tx_fetch_exception, 5308);\nDEFINE_EXPLORER_EXCEPTION(tx_send_exception, 5309);\nDEFINE_EXPLORER_EXCEPTION(tx_encode_get_exception, 5310);\nDEFINE_EXPLORER_EXCEPTION(tx_decode_get_exception, 5311);\nDEFINE_EXPLORER_EXCEPTION(tx_timestamp_exception, 5312);\nDEFINE_EXPLORER_EXCEPTION(tx_locktime_exception, 5313);\n\nDEFINE_EXPLORER_EXCEPTION(utxo_fetch_exception, 5401);\n\nDEFINE_EXPLORER_EXCEPTION(redeem_script_empty_exception, 5501);\nDEFINE_EXPLORER_EXCEPTION(redeem_script_data_exception, 5502);\nDEFINE_EXPLORER_EXCEPTION(redeem_script_pattern_exception, 5503);\n\nDEFINE_EXPLORER_EXCEPTION(encode_exception, 6001);\nDEFINE_EXPLORER_EXCEPTION(ec_to_address_exception, 6002);\nDEFINE_EXPLORER_EXCEPTION(ec_to_public_exception, 6003);\n\nDEFINE_EXPLORER_EXCEPTION(uid_symbol_name_exception, 7001);\nDEFINE_EXPLORER_EXCEPTION(uid_symbol_existed_exception, 7002);\nDEFINE_EXPLORER_EXCEPTION(uid_symbol_length_exception, 7003);\nDEFINE_EXPLORER_EXCEPTION(uid_description_length_exception, 7004);\nDEFINE_EXPLORER_EXCEPTION(uid_register_poundage_exception, 7005);\nDEFINE_EXPLORER_EXCEPTION(uid_symbol_notfound_exception, 7006);\nDEFINE_EXPLORER_EXCEPTION(uid_symbol_duplicate_exception, 7007);\nDEFINE_EXPLORER_EXCEPTION(uid_address_needed_exception, 7008);\nDEFINE_EXPLORER_EXCEPTION(uid_symbol_notowned_exception, 7009);\nDEFINE_EXPLORER_EXCEPTION(uid_multisig_address_exception, 7010);\n\nDEFINE_EXPLORER_EXCEPTION(seed_exception, 9001);\nDEFINE_EXPLORER_EXCEPTION(seed_size_exception, 9001);\nDEFINE_EXPLORER_EXCEPTION(seed_length_exception, 9002);\n\nDEFINE_EXPLORER_EXCEPTION(hd_length_exception, 9101);\nDEFINE_EXPLORER_EXCEPTION(hd_key_exception, 9102);\nDEFINE_EXPLORER_EXCEPTION(hd_new_exception, 9103);\nDEFINE_EXPLORER_EXCEPTION(hd_private_new_exception, 9104);\nDEFINE_EXPLORER_EXCEPTION(hd_to_ec_exception, 9105);\n\nDEFINE_EXPLORER_EXCEPTION(mnemonicwords_amount_exception, 9201);\nDEFINE_EXPLORER_EXCEPTION(mnemonicwords_content_exception, 9202);\nDEFINE_EXPLORER_EXCEPTION(mnemonicwords_new_exception, 9203);\nDEFINE_EXPLORER_EXCEPTION(mnemonicwords_to_seed_exception, 9204);\nDEFINE_EXPLORER_EXCEPTION(mnemonicwords_dismatch_exception, 9205);\nDEFINE_EXPLORER_EXCEPTION(mnemonicwords_empty_exception, 9206);\nDEFINE_EXPLORER_EXCEPTION(mnemonicwords_existed_exception, 9207);\n\nDEFINE_STD_JSONRPC_EXCEPTION(jsonrpc_parse_error, -32700, \"jsonrpc parse error\");\nDEFINE_STD_JSONRPC_EXCEPTION(jsonrpc_invalid_request, -32600, \"jsonrpc invalid request\");\nDEFINE_STD_JSONRPC_EXCEPTION(jsonrpc_method_not_found, -32601, \"jsonrpc method not found\");\nDEFINE_STD_JSONRPC_EXCEPTION(jsonrpc_invalid_params, -32602, \"jsonrpc invalid params\");\nDEFINE_STD_JSONRPC_EXCEPTION(jsonrpc_internal_error, -32603, \"jsonrpc internal error\");\n\n} //namespace explorer\n} //namespace libbitcoin\n#endif /* INCLUDE_UChain_EXPLORER_UTILITIES_EXCEPTION_HPP_ */\n"
  },
  {
    "path": "include/UChainService/api/command/node_method_wrapper.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-api.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#pragma once\n\n#include <functional>\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChainApp/ucd/server_node.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nbool administrator_required_checker(bc::server::server_node &node,\n                                    const std::string &name, const std::string &auth);\n\nuint64_t get_last_height(bc::server::server_node &node);\n\nuint32_t get_connections_count(bc::server::server_node &node);\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/api/command/wallet_info.hpp",
    "content": "/**\r\n * Copyright (c) 2018-2020 UChain developers \r\n *\r\n * This file is part of UChainService.\r\n *\r\n * UChain is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License with\r\n * additional permissions to the one published by the Free Software\r\n * Foundation, either version 3 of the License, or (at your option)\r\n * any later version. For more information see LICENSE.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\r\n */\r\n#pragma once\r\n\r\n#include <cstdint>\r\n#include <istream>\r\n#include <vector>\r\n#include <UChain/coin/chain/point.hpp>\r\n#include <UChain/coin/chain/script/script.hpp>\r\n#include <UChain/coin/define.hpp>\r\n#include <UChain/coin/utility/reader.hpp>\r\n#include <UChain/coin/utility/writer.hpp>\r\n#include <UChain/coin/formats/base_16.hpp>\r\n#include <UChain/blockchain/block_chain_impl.hpp>\r\n#include <UChainService/txs/wallet/wallet_address.hpp>\r\n#include <UChainService/txs/token/token_detail.hpp>\r\n\r\nnamespace libbitcoin\r\n{\r\nnamespace chain\r\n{\r\n\r\n// used for store all wallet related information\r\nclass BC_API wallet_info\r\n{\r\n  public:\r\n    wallet_info(libbitcoin::blockchain::block_chain_impl &blockchain, std::string &passphrase);\r\n    wallet_info(libbitcoin::blockchain::block_chain_impl &blockchain, std::string &passphrase,\r\n                libbitcoin::chain::wallet &meta, std::vector<wallet_address> &addr_vec, std::vector<token_detail> &token_vec);\r\n\r\n    bool from_data(const data_chunk &data);\r\n    bool from_data(std::istream &stream);\r\n    bool from_data(reader &source);\r\n    data_chunk to_data() const;\r\n    void to_data(std::ostream &stream) const;\r\n    void to_data(writer &sink) const;\r\n    void store(std::string &name, std::string &passwd);\r\n    wallet get_wallet() const;\r\n    std::vector<wallet_address> &get_wallet_address();\r\n    std::vector<token_detail> &get_wallet_token();\r\n    void encrypt();\r\n    void decrypt(std::string &hexcode);\r\n    friend std::istream &operator>>(std::istream &input, wallet_info &self_ref);\r\n    friend std::ostream &operator<<(std::ostream &output, const wallet_info &self_ref);\r\n\r\n  private:\r\n    libbitcoin::blockchain::block_chain_impl &blockchain_;\r\n    wallet meta_;\r\n    std::vector<wallet_address> addr_vec_;\r\n    std::vector<token_detail> token_vec_;\r\n    // encrypt/decrypt\r\n    data_chunk data_;\r\n    std::string passphrase_;\r\n};\r\n\r\n} // namespace chain\r\n} // namespace libbitcoin\r\n"
  },
  {
    "path": "include/UChainService/api/rest.hpp",
    "content": "//\"mgbubble\" is mongoose wrapper in c++14 for UC http service\n\n#include <UChainService/api/restful/Mongoose.hpp>\n#include <UChainService/api/restful/RestServ.hpp>\n#include <UChainService/api/restful/WsPushServ.hpp>\n"
  },
  {
    "path": "include/UChainService/api/restful/MgServer.hpp",
    "content": "/*\n* Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS).\n* Copyright (C) 2013-2018 Swirly Cloud Limited.\n*\n* This program is free software; you can redistribute it and/or modify it under the terms of the\n* GNU General Public License as published by the Free Software Foundation; either version 2 of the\n* License, or (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n* General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License along with this program; if\n* not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n* 02110-1301, USA.\n*/\n#ifndef UCD_WS_SERVER_HPP\n#define UCD_WS_SERVER_HPP\n\n#include <UChain/coin/define.hpp>\n#include <atomic>\n#include <string>\n#include <memory>\n#include <mongoose/mongoose.h>\n\nnamespace mgbubble\n{\n\nstruct mg_event\n{\n    //uint64_t id;\n    void *data;\n};\n\nclass MgServer\n{\n  public:\n    static constexpr auto NAME = \"mgserver\";\n\n  public:\n    explicit MgServer(const std::string &svr_addr) : svr_addr_(svr_addr), running_(false)\n    {\n        memset(&s_http_server_opts_, 0x00, sizeof(s_http_server_opts_));\n\n        mg_mgr_init(&mgr_, this);\n        nc_ = mg_bind(&mgr_, svr_addr_.c_str(), ev_handler);\n        if (nc_ != nullptr)\n        {\n            nc_->flags |= MG_F_USER_1; // mark as listen socket\n            mg_set_protocol_http_websocket(nc_);\n        }\n\n        notify_sock_[0] = notify_sock_[1] = INVALID_SOCKET;\n        nc_notify_ = nullptr;\n    }\n\n    virtual ~MgServer()\n    {\n        mg_mgr_free(&mgr_);\n    }\n\n    virtual bool start();\n    virtual void stop();\n    bool stopped() { return running_ == false; }\n    bool is_websocket(const struct mg_connection &nc) const { return !!(nc.flags & MG_F_IS_WEBSOCKET); }\n    bool is_listen_socket(const struct mg_connection &nc) const { return !!(nc.flags & MG_F_USER_1); }\n    bool is_on_sending(struct mg_connection &nc) { return (nc.send_mbuf.len != 0); }\n\n    // DO NOT CALL IN WsServer Worker Thread\n    // on_broadcast called after broadcasted\n    // max buffer is 8k (mongoose default)\n    bool broadcast(const std::string &msg);\n    bool broadcast(const char *msg, size_t len);\n\n    void set_document_root(const char *root) { s_http_server_opts_.document_root = root; }\n\n    bool attach_notify(mg_event_handler_t callback = nullptr)\n    {\n        if ((notify_sock_[0] == INVALID_SOCKET) && (mg_sockucnair(notify_sock_, SOCK_STREAM) == 1))\n        {\n            nc_notify_ = mg_add_sock(&mgr_, notify_sock_[1], (callback != nullptr) ? callback : ev_handler);\n            if (nc_notify_ != nullptr)\n            {\n                nc_notify_->flags |= MG_F_USER_2; // mark as notify socket\n                nc_notify_->handler = ev_notify_handler;\n            }\n        }\n        return nc_notify_ != nullptr;\n    }\n    bool is_notify_socket(struct mg_connection &nc) const { return !!(nc.flags & MG_F_USER_2); }\n\n    bool notify(uint64_t id, void *data)\n    {\n        (void)(id);\n        struct mg_event ev\n        {\n            data\n        };\n        return notify(ev);\n    }\n    bool notify(struct mg_event ev)\n    {\n        if (notify_sock_[0] == INVALID_SOCKET)\n            return false;\n        int n = ::MG_SEND_FUNC(notify_sock_[0], (const char *)&ev, sizeof(ev), 0);\n        return n > 0;\n    }\n\n  protected:\n    // ONLY CALLED IN WsServer Worker Thread\n    bool send(struct mg_connection &nc, const std::string &msg, bool close_required = false);\n    bool send(struct mg_connection &nc, const char *msg, size_t len, bool close_required = false);\n    bool send_frame(struct mg_connection &nc, const std::string &msg, bool binary = false);\n    bool send_frame(struct mg_connection &nc, const char *msg, size_t len, bool binary = false);\n\n    void serve_http_static(struct mg_connection &nc, struct http_message &hm)\n    {\n        mg_serve_http(&nc, &hm, s_http_server_opts_);\n        nc.flags |= MG_F_SEND_AND_CLOSE;\n    }\n\n  protected:\n    struct mg_mgr &mg_mgr() { return mgr_; }\n    struct mg_connection &mg_listen() { return *nc_; }\n\n  protected:\n    virtual void run();\n\n    virtual void on_http_req_handler(struct mg_connection &nc, http_message &msg);\n    virtual void on_ws_handshake_req_handler(struct mg_connection &nc, http_message &msg);\n    virtual void on_ws_handshake_done_handler(struct mg_connection &nc);\n    virtual void on_ws_frame_handler(struct mg_connection &nc, websocket_message &msg);\n    virtual void on_ws_ctrlf_handler(struct mg_connection &nc, websocket_message &msg);\n    virtual void on_timer_handler(struct mg_connection &nc);\n    virtual void on_close_handler(struct mg_connection &nc);\n    virtual void on_send_handler(struct mg_connection &nc, int bytes_transfered);\n    virtual void on_notify_handler(struct mg_connection &nc, struct mg_event &ev);\n\n    // called for each connection after broadcast\n    virtual void on_broadcast(struct mg_connection &nc, const char *ev_data);\n\n    virtual void ev_handler_default(struct mg_connection *nc, int ev, void *ev_data);\n\n  protected:\n    static void ev_broadcast(struct mg_connection *nc, int ev, void *ev_data);\n    static void ev_handler(struct mg_connection *nc, int ev, void *ev_data);\n    static void ev_notify_handler(struct mg_connection *nc, int ev, void *ev_data);\n\n  private:\n    struct mg_mgr mgr_;\n    struct mg_connection *nc_;\n    struct mg_serve_http_opts s_http_server_opts_;\n\n    sock_t notify_sock_[2]; // 0 is used out of thread, 1 is used in mongoose event loop\n    struct mg_connection *nc_notify_;\n\n    std::string svr_addr_;\n    std::atomic<bool> running_;\n    std::shared_ptr<std::thread> worker_;\n};\n} // namespace mgbubble\n\n#endif\n"
  },
  {
    "path": "include/UChainService/api/restful/Mongoose.hpp",
    "content": "/*\r\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS).\r\n * Copyright (C) 2013-2018 Swirly Cloud Limited.\r\n *\r\n * This program is free software; you can redistribute it and/or modify it under the terms of the\r\n * GNU General Public License as published by the Free Software Foundation; either version 2 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\r\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r\n * General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU General Public License along with this program; if\r\n * not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\r\n * 02110-1301, USA.\r\n */\r\n#ifndef UCD_MONGOOSE_HPP\r\n#define UCD_MONGOOSE_HPP\r\n\r\n#include <vector>\r\n#include <UChainService/api/restful/utility/Queue.hpp>\r\n#include <UChainService/api/restful/utility/String.hpp>\r\n#include <UChainService/api/restful/exception/Error.hpp>\r\n#include <UChain/explorer/dispatch.hpp>\r\n#include \"mongoose/mongoose.h\"\r\n/**\r\n * @addtogroup Web\r\n * @{\r\n */\r\n\r\nnamespace mgbubble\r\n{\r\n\r\ninline string_view operator+(const mg_str &str) noexcept\r\n{\r\n    return {str.p, str.len};\r\n}\r\n\r\ninline string_view operator+(const websocket_message &msg) noexcept\r\n{\r\n    return {reinterpret_cast<char *>(msg.data), msg.size};\r\n}\r\n\r\nclass ToCommandArg\r\n{\r\n  public:\r\n    auto argv() const noexcept { return argv_; }\r\n    auto argc() const noexcept { return argc_; }\r\n    const auto &get_command() const\r\n    {\r\n        if (!vargv_.empty())\r\n            return vargv_[0];\r\n        throw std::logic_error{\"no command found\"};\r\n    }\r\n\r\n    void add_arg(std::string &&outside);\r\n\r\n    static const int max_paramters{208};\r\n\r\n  protected:\r\n    virtual void data_to_arg(uint8_t api_version) = 0;\r\n    const char *argv_[max_paramters]{nullptr};\r\n    int argc_{0};\r\n\r\n    std::vector<std::string> vargv_;\r\n};\r\n\r\nclass HttpMessage : public ToCommandArg\r\n{\r\n  public:\r\n    HttpMessage(http_message *impl) noexcept : impl_{impl}, jsonrpc_id_(-1) {}\r\n    ~HttpMessage() noexcept = default;\r\n\r\n    // Copy.\r\n    // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1778\r\n    HttpMessage(const HttpMessage &) = default;\r\n    HttpMessage &operator=(const HttpMessage &) = default;\r\n\r\n    // Move.\r\n    HttpMessage(HttpMessage &&) = default;\r\n    HttpMessage &operator=(HttpMessage &&) = default;\r\n\r\n    auto get() const noexcept { return impl_; }\r\n    auto method() const noexcept { return +impl_->method; }\r\n    auto uri() const noexcept { return +impl_->uri; }\r\n    auto proto() const noexcept { return +impl_->proto; }\r\n    auto queryString() const noexcept { return +impl_->query_string; }\r\n    auto header(const char *name) const noexcept\r\n    {\r\n        auto *val = mg_get_http_header(impl_, name);\r\n        return val ? +*val : string_view{};\r\n    }\r\n    auto body() const noexcept { return +impl_->body; }\r\n\r\n    const int64_t jsonrpc_id() const noexcept { return jsonrpc_id_; }\r\n\r\n    void data_to_arg(uint8_t rpc_version) override;\r\n\r\n  private:\r\n    int64_t jsonrpc_id_;\r\n    http_message *impl_;\r\n};\r\n\r\nclass WebsocketMessage : public ToCommandArg\r\n{ // connect to bx command-tool\r\n  public:\r\n    WebsocketMessage(websocket_message *impl) noexcept : impl_{impl} {}\r\n    ~WebsocketMessage() noexcept = default;\r\n\r\n    // Copy.\r\n    WebsocketMessage(const WebsocketMessage &) = default;\r\n    WebsocketMessage &operator=(const WebsocketMessage &) = default;\r\n\r\n    // Move.\r\n    WebsocketMessage(WebsocketMessage &&) = default;\r\n    WebsocketMessage &operator=(WebsocketMessage &&) = default;\r\n\r\n    auto get() const noexcept { return impl_; }\r\n    auto data() const noexcept { return reinterpret_cast<char *>(impl_->data); }\r\n    auto size() const noexcept { return impl_->size; }\r\n\r\n    void data_to_arg(uint8_t api_version = 1) override;\r\n\r\n  private:\r\n    websocket_message *impl_;\r\n};\r\n\r\nclass MgEvent : public std::enable_shared_from_this<MgEvent>\r\n{\r\n  public:\r\n    explicit MgEvent(const std::function<void(uint64_t)> &&handler)\r\n        : callback_(std::move(handler))\r\n    {\r\n    }\r\n\r\n    MgEvent *hook()\r\n    {\r\n        self_ = this->shared_from_this();\r\n        return this;\r\n    }\r\n\r\n    void unhook()\r\n    {\r\n        self_.reset();\r\n    }\r\n\r\n    virtual void operator()(uint64_t id)\r\n    {\r\n        callback_(id);\r\n        self_.reset();\r\n    }\r\n\r\n  private:\r\n    std::shared_ptr<MgEvent> self_;\r\n\r\n    // called on mongoose thread\r\n    std::function<void(uint64_t id)> callback_;\r\n};\r\n\r\n} // namespace mgbubble\r\n\r\n/** @} */\r\n\r\n#endif // UCD_MONGOOSE_HPP\r\n"
  },
  {
    "path": "include/UChainService/api/restful/MongooseCli.hpp",
    "content": "/*\r\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS).\r\n * Copyright (C) 2013-2018 Swirly Cloud Limited.\r\n *\r\n * This program is free software; you can redistribute it and/or modify it under the terms of the\r\n * GNU General Public License as published by the Free Software Foundation; either version 2 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\r\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r\n * General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU General Public License along with this program; if\r\n * not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\r\n * 02110-1301, USA.\r\n */\r\n#ifndef UCD_MONGOOSECLI_HPP\r\n#define UCD_MONGOOSECLI_HPP\r\n\r\n#include <iostream>\r\n#include <functional>\r\n#include \"mongoose/mongoose.h\"\r\n\r\nnamespace mgbubble\r\n{\r\nnamespace cli\r\n{\r\n\r\ntypedef std::function<void(const http_message *)> reply_handler;\r\n\r\ntemplate <typename DerivedT>\r\nclass MgrCli\r\n{\r\n  public:\r\n    // Copy.\r\n    MgrCli(const MgrCli &) = delete;\r\n    MgrCli &operator=(const MgrCli &) = delete;\r\n\r\n    // Move.\r\n    MgrCli(MgrCli &&) = delete;\r\n    MgrCli &operator=(MgrCli &&) = delete;\r\n\r\n    inline time_t poll(int milli) { return mg_mgr_poll(&mgr_, milli); }\r\n\r\n  protected:\r\n    MgrCli() noexcept { mg_mgr_init(&mgr_, this); }\r\n    ~MgrCli() noexcept { mg_mgr_free(&mgr_); }\r\n\r\n    static void ev_handler(mg_connection *nc, int ev, void *ev_data)\r\n    {\r\n        auto *hm = static_cast<http_message *>(ev_data);\r\n        auto *self = static_cast<DerivedT *>(nc->user_data); //this\r\n\r\n        switch (ev)\r\n        {\r\n        case MG_EV_CONNECT:\r\n            if (*(int *)ev_data != 0)\r\n            {\r\n                fprintf(stderr, \"connect[%s] failed: %s\\n\",\r\n                        self->get_url().c_str(), strerror(*(int *)ev_data));\r\n                self->exit();\r\n            }\r\n            break;\r\n        case MG_EV_HTTP_REPLY:\r\n            nc->flags |= MG_F_CLOSE_IMMEDIATELY;\r\n            self->reply(hm);\r\n            self->exit();\r\n            break;\r\n        default:\r\n            break;\r\n        }\r\n    }\r\n\r\n    mg_mgr mgr_;\r\n};\r\n\r\nclass HttpReq : public MgrCli<HttpReq>\r\n{\r\n  public:\r\n    explicit HttpReq(const std::string &url, int milli, reply_handler &&oreply)\r\n        : url_(url), reply(oreply)\r\n    {\r\n        memset(&opts_, 0x00, sizeof(opts_));\r\n        opts_.user_data = reinterpret_cast<void *>(this);\r\n\r\n        if (milli > 0)\r\n            milli_ = milli;\r\n    }\r\n    ~HttpReq() noexcept {}\r\n\r\n    //void got_reply(http_message* msg) { reply(msg); }\r\n\r\n    const std::string &get_url() { return url_; }\r\n    void set_url(const std::string &other) { url_ = other; }\r\n    void set_url(std::string &&other) { url_ = other; }\r\n    void exit() { exit_ = true; }\r\n    void reset() { exit_ = false; }\r\n\r\n    void get()\r\n    {\r\n        conn_ = mg_connect_http_opt(&mgr_, ev_handler, opts_, url_.c_str(), NULL, NULL);\r\n        while (!exit_)\r\n        {\r\n            poll(milli_);\r\n        }\r\n    }\r\n    void post(std::string &&data) { post(data); }\r\n    void post(const std::string &data)\r\n    {\r\n        conn_ = mg_connect_http_opt(&mgr_, ev_handler, opts_, url_.c_str(), NULL, data.c_str());\r\n        while (!exit_)\r\n        {\r\n            poll(milli_);\r\n        }\r\n    }\r\n    void post(std::string &&header, std::string &&data) { post(header, data); }\r\n    void post(const std::string &header, const std::string &data)\r\n    {\r\n        conn_ = mg_connect_http_opt(&mgr_, ev_handler, opts_, url_.c_str(), header.c_str(), data.c_str());\r\n        while (!exit_)\r\n        {\r\n            poll(milli_);\r\n        }\r\n    }\r\n\r\n    reply_handler reply;\r\n\r\n  private:\r\n    int milli_{3000};\r\n    bool exit_{false};\r\n    mg_connect_opts opts_;\r\n    mg_connection *conn_{nullptr};\r\n    std::string url_;\r\n};\r\n\r\n} // namespace cli\r\n} // namespace mgbubble\r\n\r\n/** @} */\r\n\r\n#endif // UCD_MONGOOSECLI_HPP\r\n"
  },
  {
    "path": "include/UChainService/api/restful/ReadME.md",
    "content": "\"mgbubble\" is mongoose wrapper in c++14 for UC http service\n"
  },
  {
    "path": "include/UChainService/api/restful/RestServ.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS) \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChainService/api/restful/Mongoose.hpp>\n#include <UChainService/api/restful/MgServer.hpp>\n#include <UChainService/api/restful/utility/Stream_buf.hpp>\n#include <UChainService/api/restful/utility/Tokeniser.hpp>\n#include <UChainService/api/restful/exception/Instances.hpp>\n\n#include <UChain/client.hpp>\n#include <UChain/blockchain.hpp>\n#include <UChainApp/ucd/services/query_service.hpp> //public_query\n\nnamespace libbitcoin\n{\nnamespace server\n{\nclass server_node;\n}\n} // namespace libbitcoin\n\nnamespace mgbubble\n{\n\nusing namespace bc;\n\nclass RestServ : public MgServer\n{\n    typedef MgServer base;\n\n  public:\n    explicit RestServ(const char *webroot, libbitcoin::server::server_node &node, const std::string &srv_addr)\n        : node_(node), MgServer(srv_addr)\n    {\n        document_root_ = webroot;\n        set_document_root(document_root_.c_str());\n    }\n    ~RestServ() noexcept { stop(); };\n\n    // Copy.\n    RestServ(const RestServ &rhs) = delete;\n    RestServ &operator=(const RestServ &rhs) = delete;\n\n    // Move.\n    RestServ(RestServ &&) = delete;\n    RestServ &operator=(RestServ &&) = delete;\n\n    void rpc_request(mg_connection &nc, HttpMessage data, uint8_t rpc_version = 1);\n    void ws_request(mg_connection &nc, WebsocketMessage ws);\n\n  public:\n    void reset(HttpMessage &data) noexcept;\n\n    bool start() override;\n\n    void spawn_to_mongoose(const std::function<void(uint64_t)> &&handler);\n\n  protected:\n    void run() override;\n\n    void on_http_req_handler(struct mg_connection &nc, struct http_message &msg) override;\n    void on_notify_handler(struct mg_connection &nc, struct mg_event &ev) override;\n    void on_ws_handshake_done_handler(struct mg_connection &nc) override;\n    void on_ws_frame_handler(struct mg_connection &nc, struct websocket_message &msg) override;\n\n  private:\n    enum : int\n    {\n        // Method values are represented as powers of two for simplicity.\n        MethodGet = 1 << 0,\n        MethodPost = 1 << 1,\n        MethodPut = 1 << 2,\n        MethodDelete = 1 << 3,\n        // Method value mask.\n        MethodMask = MethodGet | MethodPost | MethodPut | MethodDelete,\n\n        // Subsequent bits represent matching components.\n        MatchMethod = 1 << 4,\n        MatchUri = 1 << 5,\n        // Match result mask.\n        MatchMask = MatchMethod | MatchUri\n    };\n\n    bool isSet(int bs) const noexcept { return (state_ & bs) == bs; }\n\n    // config\n    static thread_local OStream out_;\n    static thread_local Tokeniser<'/'> uri_;\n    static thread_local int state_;\n    const char *const servername_{\"UChain \" UC_VERSION};\n    libbitcoin::server::server_node &node_;\n    string document_root_;\n};\n\n} // namespace mgbubble\n"
  },
  {
    "path": "include/UChainService/api/restful/WsPushServ.hpp",
    "content": "/*\n* Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS).\n* Copyright (C) 2013-2018 Swirly Cloud Limited.\n*\n* This program is free software; you can redistribute it and/or modify it under the terms of the\n* GNU General Public License as published by the Free Software Foundation; either version 2 of the\n* License, or (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n* General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License along with this program; if\n* not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n* 02110-1301, USA.\n*/\n#ifndef UCD_WS_PUSH_SERV_HPP\n#define UCD_WS_PUSH_SERV_HPP\n\n#include <string>\n#include <vector>\n#include <atomic>\n#include <mutex>\n#include <memory>\n#include <unordered_map>\n#include <UChain/coin.hpp>\n#include <UChainService/api/restful/MgServer.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\nclass server_node;\n}\n} // namespace libbitcoin\n\nnamespace mgbubble\n{\n\nclass WsEvent : public std::enable_shared_from_this<WsEvent>\n{\n  public:\n    explicit WsEvent(const std::function<void(uint64_t)> &&handler)\n        : callback_(std::move(handler))\n    {\n    }\n\n    WsEvent *hook()\n    {\n        self_ = this->shared_from_this();\n        return this;\n    }\n\n    void unhook()\n    {\n        self_.reset();\n    }\n\n    virtual void operator()(uint64_t id)\n    {\n        callback_(id);\n        self_.reset();\n    }\n\n  private:\n    std::shared_ptr<WsEvent> self_;\n\n    // called on mongoose thread\n    std::function<void(uint64_t id)> callback_;\n};\n\nclass WsPushServ : public MgServer\n{\n    typedef bc::chain::point::indexes index_list;\n    typedef bc::message::block_msg::ptr_list block_list;\n    typedef MgServer base;\n\n  public:\n    explicit WsPushServ(libbitcoin::server::server_node &node, const std::string &srv_addr)\n        : node_(node), MgServer(srv_addr)\n    {\n    }\n\n    ~WsPushServ() noexcept { stop(); };\n\n    bool start() override;\n\n    void spawn_to_mongoose(const std::function<void(uint64_t)> &&handler);\n\n  protected:\n    bool handle_blockchain_reorganization(\n        const bc::code &ec, uint64_t fork_point,\n        const block_list &new_blocks, const block_list &);\n    bool handle_tx_pool(\n        const bc::code &ec, const index_list &,\n        bc::message::tx_message::ptr tx);\n\n    void notify_blocks(uint32_t fork_point, const block_list &blocks);\n    void notify_block(uint32_t height, const bc::chain::block::ptr block);\n\n    void notify_block_impl(uint32_t height, const bc::chain::block::ptr block);\n    void notify_transaction(\n        uint32_t height, const bc::hash_digest &block_hash,\n        const bc::chain::transaction &tx);\n\n  protected:\n    void send_bad_response(\n        struct mg_connection &nc, const char *message = nullptr,\n        int code = 1000001, Json::Value data = Json::nullValue);\n    void send_response(\n        struct mg_connection &nc, const std::string &event,\n        const std::string &channel, Json::Value data = Json::nullValue);\n\n    void refresh_connections();\n\n  protected:\n    void run() override;\n\n    void on_ws_handshake_done_handler(struct mg_connection &nc) override;\n    void on_ws_frame_handler(struct mg_connection &nc, websocket_message &msg) override;\n    void on_close_handler(struct mg_connection &nc) override;\n    void on_broadcast(struct mg_connection &nc, const char *ev_data) override;\n    void on_send_handler(struct mg_connection &nc, int bytes_transfered) override;\n    void on_notify_handler(struct mg_connection &nc, struct mg_event &ev) override;\n\n  private:\n    typedef std::vector<std::string> string_vector;\n    typedef std::map<std::weak_ptr<mg_connection>, string_vector,\n                     std::owner_less<std::weak_ptr<mg_connection>>>\n        connection_string_map;\n\n    void do_notify(\n        const std::vector<std::weak_ptr<mg_connection>> &notify_cons,\n        Json::Value &value,\n        std::shared_ptr<connection_string_map> topic_map = nullptr);\n\n  private:\n    libbitcoin::server::server_node &node_;\n    std::unordered_map<void *, std::shared_ptr<mg_connection>> map_connections_;\n    connection_string_map subscribers_;\n    std::mutex subscribers_lock_;\n\n    connection_string_map block_subscribers_;\n    std::mutex block_subscribers_lock_;\n};\n} // namespace mgbubble\n\n#endif"
  },
  {
    "path": "include/UChainService/api/restful/WsServer.hpp",
    "content": "/*\n* Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS).\n* Copyright (C) 2013-2018 Swirly Cloud Limited.\n*\n* This program is free software; you can redistribute it and/or modify it under the terms of the\n* GNU General Public License as published by the Free Software Foundation; either version 2 of the\n* License, or (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n* General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License along with this program; if\n* not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n* 02110-1301, USA.\n*/\n#ifndef UCD_WS_SERVER_HPP\n#define UCD_WS_SERVER_HPP\n\n#include <atomic>\n#include <string>\n#include <memory>\n#include <mongoose/mongoose.h>\n\nnamespace mgbubble\n{\nclass MgServer\n{\n  public:\n    static constexpr auto NAME = \"wsserver\";\n\n  public:\n    explicit MgServer(const std::string &svr_addr) : svr_addr_(svr_addr), running_(false)\n    {\n        mg_mgr_init(&mgr_, this);\n        nc_ = mg_bind(&mgr_, svr_addr_.c_str(), ev_handler);\n        if (nc_ != nullptr)\n        {\n            nc_->flags |= MG_F_USER_1; // mark as listen socket\n            mg_set_protocol_http_websocket(nc_);\n        }\n    }\n\n    virtual ~MgServer()\n    {\n        mg_mgr_free(&mgr_);\n    }\n\n    virtual bool start();\n    virtual void stop();\n    bool stopped() { return running_ == false; }\n    bool is_websocket(const struct mg_connection &nc) const { return !!(nc.flags & MG_F_IS_WEBSOCKET); }\n    bool is_listen_socket(const struct mg_connection &nc) const { return !!(nc.flags & MG_F_USER_1); }\n\n    // DO NOT CALL IN WsServer Worker Thread\n    // on_broadcast called after broadcasted\n    // max buffer is 8k (mongoose default)\n    bool broadcast(const std::string &msg);\n    bool broadcast(const char *msg, size_t len);\n\n  protected:\n    // ONLY CALLED IN WsServer Worker Thread\n    bool send_frame(struct mg_connection &nc, const std::string &msg, bool binary = false);\n    bool send_frame(struct mg_connection &nc, const char *msg, size_t len, bool binary = false);\n\n  protected:\n    struct mg_mgr &mg_mgr() { return mgr_; }\n    struct mg_connection &mg_listen() { return *nc_; }\n\n  protected:\n    virtual void run();\n\n    virtual void on_ws_handshake_req_handler(struct mg_connection &nc, http_message &msg);\n    virtual void on_ws_handshake_done_handler(struct mg_connection &nc);\n    virtual void on_ws_frame_handler(struct mg_connection &nc, websocket_message &msg);\n    virtual void on_ws_ctrlf_handler(struct mg_connection &nc, websocket_message &msg);\n    virtual void on_timer_handler(struct mg_connection &nc);\n    virtual void on_close_handler(struct mg_connection &nc);\n\n    // called for each connection after broadcast\n    virtual void on_broadcast(struct mg_connection &nc, const char *ev_data);\n\n    virtual void ev_handler_default(struct mg_connection *nc, int ev, void *ev_data);\n\n  protected:\n    static void ev_broadcast(struct mg_connection *nc, int ev, void *ev_data);\n    static void ev_handler(struct mg_connection *nc, int ev, void *ev_data);\n\n  private:\n    struct mg_mgr mgr_;\n    struct mg_connection *nc_;\n    struct mg_serve_http_opts s_http_server_opts_;\n\n    std::string svr_addr_;\n    std::atomic<bool> running_;\n    std::shared_ptr<std::thread> worker_;\n};\n} // namespace mgbubble\n\n#endif"
  },
  {
    "path": "include/UChainService/api/restful/compat/define.hpp",
    "content": "/*\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS) - UChain.\n *\n * This program is free software; you can redistribute it and/or modify it under the terms of the\n * GNU General Public License as published by the Free Software Foundation; either version 2 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along with this program; if\n * not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n * 02110-1301, USA.\n */\n#ifndef UC_ASH_DEFS_HPP\n#define UC_ASH_DEFS_HPP\n\n/**\n * @addtogroup Util\n * @{\n */\n\n/**\n * Macro for exporting classes and functions that compose the public API.\n */\n#ifdef _WIN32\n#define UC_API\n#else\n#define UC_API __attribute__((visibility(\"default\")))\n#endif\n\n#define LOG_HTTP \"http\"\n\n/** @} */\n\n#endif // UC_ASH_DEFS_HPP\n"
  },
  {
    "path": "include/UChainService/api/restful/compat/string_view.h",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC___STRING_VIEW__\n#define UC___STRING_VIEW__\n\n#ifdef _MSC_VER\n#include <boost/utility/string_view_fwd.hpp>\n#include <boost/utility/string_view.hpp>\n#define string_view boost::string_view\n\n#else\n\n#include <string_view>\nnamespace mgbubble\n{\n\nusing std::basic_string_view;\nusing std::string_view;\n\n} // namespace mgbubble\n\n#endif\n\n#endif\n"
  },
  {
    "path": "include/UChainService/api/restful/exception/Error.hpp",
    "content": "/*\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS) - UChain.\n *\n * This program is free software; you can redistribute it and/or modify it under the terms of the\n * GNU General Public License as published by the Free Software Foundation; either version 2 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along with this program; if\n * not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n * 02110-1301, USA.\n */\n#ifndef UCD_EXCEPTION_HPP\n#define UCD_EXCEPTION_HPP\n\n#include <UChainService/api/restful/exception/Exception.hpp>\n\n/**\n * @addtogroup App\n * @{\n */\n\nnamespace mgbubble\n{\n\nclass Error : public Exception\n{\npublic:\n  explicit Error(string_view what) noexcept : Exception{what} {}\n  ~Error() noexcept = default;\n\n  // Copy.\n  Error(const Error &) noexcept = default;\n  Error &operator=(const Error &) noexcept = default;\n\n  // Move.\n  Error(Error &&) noexcept = default;\n  Error &operator=(Error &&) noexcept = default;\n};\n\n} // namespace mgbubble\n\n/** @} */\n\n#endif // UCD_EXCEPTION_HPP\n"
  },
  {
    "path": "include/UChainService/api/restful/exception/Exception.hpp",
    "content": "/*\r\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS).\r\n * Copyright (C) 2013-2018 Swirly Cloud Limited.\r\n *\r\n * This program is free software; you can redistribute it and/or modify it under the terms of the\r\n * GNU General Public License as published by the Free Software Foundation; either version 2 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\r\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r\n * General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU General Public License along with this program; if\r\n * not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\r\n * 02110-1301, USA.\r\n */\r\n\r\n#pragma once\r\n\r\n#include <cstring> // strcpy()\r\n#include <exception>\r\n#include <UChainService/api/restful/utility/Stream.hpp>\r\n\r\nnamespace mgbubble\r\n{\r\n\r\n/**\r\n * Maximum error message length.\r\n */\r\nconstexpr std::size_t ErrMsgMax{127};\r\n\r\nusing ErrMsg = StringBuilder<ErrMsgMax>;\r\n\r\nclass UC_API Exception : public std::exception\r\n{\r\npublic:\r\n  explicit Exception(string_view what) noexcept;\r\n\r\n  ~Exception() noexcept override;\r\n\r\n  // Copy.\r\n  Exception(const Exception &rhs) noexcept { *this = rhs; }\r\n  Exception &operator=(const Exception &rhs) noexcept\r\n  {\r\n    std::strcpy(what_, rhs.what_);\r\n    return *this;\r\n  }\r\n\r\n  // Move.\r\n  Exception(Exception &&) noexcept = default;\r\n  Exception &operator=(Exception &&) noexcept = default;\r\n\r\n  const char *what() const noexcept override;\r\n\r\nprivate:\r\n  char what_[ErrMsgMax + 1];\r\n};\r\n\r\n/**\r\n * Thread-local error message. This thread-local instance of StringBuilder can be used to format\r\n * error messages before throwing. Note that the StringBuilder is reset each time this function is\r\n * called.\r\n */\r\nUC_API ErrMsg &errMsg() noexcept;\r\n\r\n} // namespace mgbubble\r\n"
  },
  {
    "path": "include/UChainService/api/restful/exception/Instances.hpp",
    "content": "/*\r\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS).\r\n * Copyright (C) 2013-2018 Swirly Cloud Limited.\r\n *\r\n * This program is free software; you can redistribute it and/or modify it under the terms of the\r\n * GNU General Public License as published by the Free Software Foundation; either version 2 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\r\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r\n * General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU General Public License along with this program; if\r\n * not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\r\n * 02110-1301, USA.\r\n */\r\n#pragma once\r\n\r\n#include <iosfwd>\r\n#include <UChainService/api/restful/exception/Exception.hpp>\r\n\r\n/**\r\n * @addtogroup Exception\r\n * @{\r\n */\r\n\r\nnamespace mgbubble\r\n{\r\n\r\nclass UC_API ServException : public Exception\r\n{\r\n  public:\r\n    explicit ServException(string_view what) noexcept : Exception{what} {}\r\n    ~ServException() noexcept override;\r\n\r\n    // Copy.\r\n    ServException(const ServException &) noexcept = default;\r\n    ServException &operator=(const ServException &) noexcept = default;\r\n\r\n    // Move.\r\n    ServException(ServException &&) noexcept = default;\r\n    ServException &operator=(ServException &&) noexcept = default;\r\n\r\n    static void toJson(int status, const char *reason, const char *detail, std::ostream &os);\r\n\r\n    void toJson(std::ostream &os) const { toJson(httpStatus(), httpReason(), what(), os); }\r\n\r\n    virtual int httpStatus() const noexcept = 0;\r\n\r\n    virtual const char *httpReason() const noexcept = 0;\r\n};\r\n\r\ninline std::ostream &operator<<(std::ostream &os, const ServException &e)\r\n{\r\n    e.toJson(os);\r\n    return os;\r\n}\r\n\r\n/**\r\n * The request could not be understood by the server due to malformed syntax. The client SHOULD NOT\r\n * repeat the request without modifications.\r\n */\r\nclass UC_API BadRequestException : public ServException\r\n{\r\n  public:\r\n    explicit BadRequestException(string_view what) noexcept : ServException{what} {}\r\n    ~BadRequestException() noexcept override;\r\n\r\n    // Copy.\r\n    BadRequestException(const BadRequestException &) noexcept = default;\r\n    BadRequestException &operator=(const BadRequestException &) noexcept = default;\r\n\r\n    // Move.\r\n    BadRequestException(BadRequestException &&) noexcept = default;\r\n    BadRequestException &operator=(BadRequestException &&) noexcept = default;\r\n\r\n    int httpStatus() const noexcept override;\r\n\r\n    const char *httpReason() const noexcept override;\r\n};\r\n\r\nclass UC_API AlreadyExistsException : public BadRequestException\r\n{\r\n  public:\r\n    explicit AlreadyExistsException(string_view what) noexcept : BadRequestException{what} {}\r\n    ~AlreadyExistsException() noexcept override;\r\n\r\n    // Copy.\r\n    AlreadyExistsException(const AlreadyExistsException &) noexcept = default;\r\n    AlreadyExistsException &operator=(const AlreadyExistsException &) noexcept = default;\r\n\r\n    // Move.\r\n    AlreadyExistsException(AlreadyExistsException &&) noexcept = default;\r\n    AlreadyExistsException &operator=(AlreadyExistsException &&) noexcept = default;\r\n};\r\n\r\nclass UC_API RefAlreadyExistsException : public AlreadyExistsException\r\n{\r\n  public:\r\n    explicit RefAlreadyExistsException(string_view what) noexcept : AlreadyExistsException{what}\r\n    {\r\n    }\r\n    RefAlreadyExistsException() noexcept = default;\r\n\r\n    ~RefAlreadyExistsException() noexcept override;\r\n\r\n    // Copy.\r\n    RefAlreadyExistsException(const RefAlreadyExistsException &) noexcept = default;\r\n    RefAlreadyExistsException &operator=(const RefAlreadyExistsException &) noexcept = default;\r\n\r\n    // Move.\r\n    RefAlreadyExistsException(RefAlreadyExistsException &&) noexcept = default;\r\n    RefAlreadyExistsException &operator=(RefAlreadyExistsException &&) noexcept = default;\r\n};\r\n\r\nclass UC_API InvalidException : public BadRequestException\r\n{\r\n  public:\r\n    explicit InvalidException(string_view what) noexcept : BadRequestException{what} {}\r\n    ~InvalidException() noexcept override;\r\n\r\n    // Copy.\r\n    InvalidException(const InvalidException &) noexcept = default;\r\n    InvalidException &operator=(const InvalidException &) noexcept = default;\r\n\r\n    // Move.\r\n    InvalidException(InvalidException &&) noexcept = default;\r\n    InvalidException &operator=(InvalidException &&) noexcept = default;\r\n};\r\n\r\n/**\r\n * The server understood the request, but is refusing to fulfill it. Authorization will not help and\r\n * the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to\r\n * make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal\r\n * in the entity. If the server does not wish to make this information available to the client, the\r\n * status code 404 (Not Found) can be used instead.\r\n */\r\nclass UC_API ForbiddenException : public ServException\r\n{\r\n  public:\r\n    explicit ForbiddenException(string_view what) noexcept : ServException{what} {}\r\n    ~ForbiddenException() noexcept override;\r\n\r\n    // Copy.\r\n    ForbiddenException(const ForbiddenException &) noexcept = default;\r\n    ForbiddenException &operator=(const ForbiddenException &) noexcept = default;\r\n\r\n    // Move.\r\n    ForbiddenException(ForbiddenException &&) noexcept = default;\r\n    ForbiddenException &operator=(ForbiddenException &&) noexcept = default;\r\n\r\n    int httpStatus() const noexcept override;\r\n\r\n    const char *httpReason() const noexcept override;\r\n};\r\n\r\n/**\r\n * The server encountered an unexpected condition which prevented it from fulfilling the request.\r\n */\r\nclass UC_API InternalException : public ServException\r\n{\r\n  public:\r\n    explicit InternalException(string_view what) noexcept : ServException{what} {}\r\n    ~InternalException() noexcept override;\r\n\r\n    // Copy.\r\n    InternalException(const InternalException &) noexcept = default;\r\n    InternalException &operator=(const InternalException &) noexcept = default;\r\n\r\n    // Move.\r\n    InternalException(InternalException &&) noexcept = default;\r\n    InternalException &operator=(InternalException &&) noexcept = default;\r\n\r\n    int httpStatus() const noexcept override;\r\n\r\n    const char *httpReason() const noexcept override;\r\n};\r\n\r\n/**\r\n * The method specified in the Request-Line is not allowed for the resource identified by the\r\n * Request-URI. The response MUST include an Allow header containing a list of valid methods for the\r\n * requested resource.\r\n */\r\nclass UC_API MethodNotAllowedException : public ServException\r\n{\r\n  public:\r\n    explicit MethodNotAllowedException(string_view what) noexcept : ServException{what} {}\r\n    ~MethodNotAllowedException() noexcept override;\r\n\r\n    // Copy.\r\n    MethodNotAllowedException(const MethodNotAllowedException &) noexcept = default;\r\n    MethodNotAllowedException &operator=(const MethodNotAllowedException &) noexcept = default;\r\n\r\n    // Move.\r\n    MethodNotAllowedException(MethodNotAllowedException &&) noexcept = default;\r\n    MethodNotAllowedException &operator=(MethodNotAllowedException &&) noexcept = default;\r\n\r\n    int httpStatus() const noexcept override;\r\n\r\n    const char *httpReason() const noexcept override;\r\n};\r\n\r\n/**\r\n * The server has not found anything matching the Request-URI. No indication is given of whether the\r\n * condition is temporary or permanent. The 410 (Gone) status code SHOULD be used if the server\r\n * knows, through some internally configurable mechanism, that an old resource is permanently\r\n * unavailable and has no forwarding address. This status code is commonly used when the server does\r\n * not wish to reveal exactly why the request has been refused, or when no other response is\r\n * applicable.\r\n */\r\nclass UC_API NotFoundException : public ServException\r\n{\r\n  public:\r\n    explicit NotFoundException(string_view what) noexcept : ServException{what} {}\r\n    ~NotFoundException() noexcept override;\r\n\r\n    // Copy.\r\n    NotFoundException(const NotFoundException &) noexcept = default;\r\n    NotFoundException &operator=(const NotFoundException &) noexcept = default;\r\n\r\n    // Move.\r\n    NotFoundException(NotFoundException &&) noexcept = default;\r\n    NotFoundException &operator=(NotFoundException &&) noexcept = default;\r\n\r\n    int httpStatus() const noexcept override;\r\n\r\n    const char *httpReason() const noexcept override;\r\n};\r\n\r\n/**\r\n * The server is currently unable to handle the request due to a temporary overloading or\r\n * maintenance of the server. The implication is that this is a temporary condition which will be\r\n * alleviated after some delay. If known, the length of the delay MAY be indicated in a Retry-After\r\n * header. If no Retry-After is given, the client SHOULD handle the response as it would for a 500\r\n * response.\r\n */\r\nclass UC_API ServiceUnavailableException : public ServException\r\n{\r\n  public:\r\n    explicit ServiceUnavailableException(string_view what) noexcept : ServException{what} {}\r\n    ~ServiceUnavailableException() noexcept override;\r\n\r\n    // Copy.\r\n    ServiceUnavailableException(const ServiceUnavailableException &) noexcept = default;\r\n    ServiceUnavailableException &operator=(const ServiceUnavailableException &) noexcept = default;\r\n\r\n    // Move.\r\n    ServiceUnavailableException(ServiceUnavailableException &&) noexcept = default;\r\n    ServiceUnavailableException &operator=(ServiceUnavailableException &&) noexcept = default;\r\n\r\n    int httpStatus() const noexcept override;\r\n\r\n    const char *httpReason() const noexcept override;\r\n};\r\n\r\n/**\r\n * The request requires user authentication. The response MUST include a WWW-Authenticate header\r\n * field (section 14.47) containing a challenge applicable to the requested resource. The client MAY\r\n * repeat the request with a suitable Authorization header field (section 14.8). If the request\r\n * already included Authorization credentials, then the 401 response indicates that authorization\r\n * has been refused for those credentials. If the 401 response contains the same challenge as the\r\n * prior response, and the user agent has already attempted authentication at least once, then the\r\n * user SHOULD be presented the entity that was given in the response, since that entity might\r\n * include relevant diagnostic information. HTTP access authentication is explained in \"HTTP\r\n * Authentication: Basic and Digest Access Authentication\".\r\n */\r\nclass UC_API UnauthorizedException : public ServException\r\n{\r\n  public:\r\n    explicit UnauthorizedException(string_view what) noexcept : ServException{what} {}\r\n    ~UnauthorizedException() noexcept override;\r\n\r\n    // Copy.\r\n    UnauthorizedException(const UnauthorizedException &) noexcept = default;\r\n    UnauthorizedException &operator=(const UnauthorizedException &) noexcept = default;\r\n\r\n    // Move.\r\n    UnauthorizedException(UnauthorizedException &&) noexcept = default;\r\n    UnauthorizedException &operator=(UnauthorizedException &&) noexcept = default;\r\n\r\n    int httpStatus() const noexcept override;\r\n\r\n    const char *httpReason() const noexcept override;\r\n};\r\n\r\n} // namespace mgbubble\r\n\r\n/** @} */\r\n"
  },
  {
    "path": "include/UChainService/api/restful/utility/Compare.hpp",
    "content": "/*\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS) - UChain.\n *\n * This program is free software; you can redistribute it and/or modify it under the terms of the\n * GNU General Public License as published by the Free Software Foundation; either version 2 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along with this program; if\n * not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n * 02110-1301, USA.\n */\n#ifndef UC_ASH_COMPARE_HPP\n#define UC_ASH_COMPARE_HPP\n\n#include <type_traits>\n\n/**\n * @addtogroup Util\n * @{\n */\n\nnamespace mgbubble\n{\n\ntemplate <typename ValueT>\nclass Comparable\n{\npublic:\n  friend constexpr bool operator==(const ValueT &lhs, const ValueT &rhs) noexcept\n  {\n    return lhs.compare(rhs) == 0;\n  }\n\n  friend constexpr bool operator!=(const ValueT &lhs, const ValueT &rhs) noexcept\n  {\n    return lhs.compare(rhs) != 0;\n  }\n\n  friend constexpr bool operator<(const ValueT &lhs, const ValueT &rhs) noexcept\n  {\n    return lhs.compare(rhs) < 0;\n  }\n\n  friend constexpr bool operator<=(const ValueT &lhs, const ValueT &rhs) noexcept\n  {\n    return lhs.compare(rhs) <= 0;\n  }\n\n  friend constexpr bool operator>(const ValueT &lhs, const ValueT &rhs) noexcept\n  {\n    return lhs.compare(rhs) > 0;\n  }\n\n  friend constexpr bool operator>=(const ValueT &lhs, const ValueT &rhs) noexcept\n  {\n    return lhs.compare(rhs) >= 0;\n  }\n\nprotected:\n  ~Comparable() noexcept = default;\n};\n\ntemplate <typename EnumT, typename std::enable_if_t<std::is_enum<EnumT>::value> * = nullptr>\nint compare(EnumT lhs, EnumT rhs) noexcept\n{\n  int i = 0;\n  if (lhs < rhs)\n  {\n    i = -1;\n  }\n  else if (lhs > rhs)\n  {\n    i = 1;\n  }\n  else\n  {\n    i = 0;\n  }\n  return i;\n}\n\ntemplate <typename IntegralT,\n          typename std::enable_if_t<std::is_integral<IntegralT>::value> * = nullptr>\nint compare(IntegralT lhs, IntegralT rhs) noexcept\n{\n  int i = 0;\n  if (lhs < rhs)\n  {\n    i = -1;\n  }\n  else if (lhs > rhs)\n  {\n    i = 1;\n  }\n  else\n  {\n    i = 0;\n  }\n  return i;\n}\n\n} // namespace mgbubble\n\n/** @} */\n\n#endif // UC_ASH_COMPARE_HPP\n"
  },
  {
    "path": "include/UChainService/api/restful/utility/Queue.hpp",
    "content": "#pragma once\n#include <deque>\n#include <mutex>\n#include <condition_variable>\n\ntemplate <typename T>\nclass Queue\n{\n  public:\n    Queue() = default;\n    Queue(Queue &&) = default;\n\n    void push(T &&item)\n    {\n        std::unique_lock<std::mutex> lock(lock_);\n        queue_.push_back(item);\n        cond_.notify_one();\n    }\n\n    void push(T &item)\n    {\n        std::unique_lock<std::mutex> lock(lock_);\n        queue_.push_back(item);\n        cond_.notify_one();\n    }\n\n    bool empty()\n    {\n        std::unique_lock<std::mutex> lock(lock_);\n        return queue_.empty();\n    }\n\n    int count()\n    {\n        std::unique_lock<std::mutex> lock(lock_);\n        return queue_.size();\n    }\n\n    void clear()\n    {\n        std::unique_lock<std::mutex> lock(lock_);\n        std::deque<T> tmp;\n        queue_.swap(tmp);\n    }\n\n    bool pop(T &front)\n    {\n        std::unique_lock<std::mutex> lock(lock_);\n        if (!queue_.empty())\n        {\n            front = queue_.front();\n            queue_.pop_front();\n            return true;\n        }\n        return false;\n    }\n\n    bool pop_wait(T &front)\n    {\n        std::unique_lock<std::mutex> lock(lock_);\n        if (queue_.empty())\n        {\n            cond_.wait(lock);\n        }\n        if (!queue_.empty())\n        {\n            front = queue_.front();\n            queue_.pop_front();\n            return true;\n        }\n        return false;\n    }\n\n  private:\n    mutable std::mutex lock_;\n    std::condition_variable cond_;\n    std::deque<T> queue_;\n};\n"
  },
  {
    "path": "include/UChainService/api/restful/utility/Stream.hpp",
    "content": "/*\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS) - UChain.\n *\n * This program is free software; you can redistribute it and/or modify it under the terms of the\n * GNU General Public License as published by the Free Software Foundation; either version 2 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along with this program; if\n * not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n * 02110-1301, USA.\n */\n#pragma once\n\n#include <ostream>\n#include <UChainService/api/restful/compat/define.hpp>\n#include <UChainService/api/restful/compat/string_view.h>\n\n/**\n * @addtogroup Util\n * @{\n */\n\nnamespace mgbubble\n{\n\nUC_API void reset(std::ostream &os) noexcept;\n\ntemplate <std::size_t MaxN>\nclass StringBuf : public std::streambuf\n{\npublic:\n  StringBuf() noexcept { reset(); }\n  ~StringBuf() noexcept override = default;\n\n  // Copy.\n  StringBuf(const StringBuf &rhs) = delete;\n  StringBuf &operator=(const StringBuf &rhs) = delete;\n\n  // Move.\n  StringBuf(StringBuf &&) = delete;\n  StringBuf &operator=(StringBuf &&) = delete;\n\n  const char *data() const noexcept { return pbase(); }\n  bool empty() const noexcept { return pbase() == pptr(); }\n  std::size_t size() const noexcept { return pptr() - pbase(); }\n  string_view str() const noexcept { return {data(), size()}; }\n  void reset() noexcept { setp(buf_, buf_ + MaxN); };\n\nprivate:\n  char buf_[MaxN];\n};\n\ntemplate <std::size_t MaxN>\nclass StringBuilder : public std::ostream\n{\npublic:\n  StringBuilder() : std::ostream{nullptr} { rdbuf(&buf_); }\n  ~StringBuilder() noexcept override = default;\n\n  // Copy.\n  StringBuilder(const StringBuilder &rhs) = delete;\n  StringBuilder &operator=(const StringBuilder &rhs) = delete;\n\n  // Move.\n  StringBuilder(StringBuilder &&) = delete;\n  StringBuilder &operator=(StringBuilder &&) = delete;\n\n  const char *data() const noexcept { return buf_.data(); }\n  bool empty() const noexcept { return buf_.empty(); }\n  std::size_t size() const noexcept { return buf_.size(); }\n  string_view str() const noexcept { return buf_.str(); }\n  operator string_view() const noexcept { return buf_.str(); }\n  void reset() noexcept\n  {\n    buf_.reset();\n    mgbubble::reset(*this);\n  };\n\nprivate:\n  StringBuf<MaxN> buf_;\n};\n\ntemplate <std::size_t MaxN, typename ValueT>\nauto &operator<<(StringBuilder<MaxN> &sb, ValueT &&val)\n{\n  static_cast<std::ostream &>(sb) << std::forward<ValueT>(val);\n  return sb;\n}\n\n/**\n * Stream joiner. This is a simplified version of std::experimental::ostream_joiner, intended as a\n * placeholder until TS v2 is more widely available.\n */\nclass UC_API OStreamJoiner\n{\npublic:\n  using char_type = char;\n  using traits_type = std::char_traits<char_type>;\n  using ostream_type = std::ostream;\n  using value_type = void;\n  using difference_type = void;\n  using pointer = void;\n  using reference = void;\n  using iterator_category = std::output_iterator_tag;\n\n  OStreamJoiner(std::ostream &os, const char delim) noexcept : os_{&os}, delim_{delim} {}\n  ~OStreamJoiner() noexcept;\n\n  // Copy.\n  OStreamJoiner(const OStreamJoiner &) = default;\n  OStreamJoiner &operator=(const OStreamJoiner &) = default;\n\n  // Move.\n  OStreamJoiner(OStreamJoiner &&) = default;\n  OStreamJoiner &operator=(OStreamJoiner &&) = default;\n\n  template <typename ValueT>\n  OStreamJoiner &operator=(const ValueT &value)\n  {\n    if (!first_)\n    {\n      *os_ << delim_;\n    }\n    first_ = false;\n    *os_ << value;\n    return *this;\n  }\n  OStreamJoiner &operator*() noexcept { return *this; }\n  OStreamJoiner &operator++() noexcept { return *this; }\n  OStreamJoiner &operator++(int) noexcept { return *this; }\n\nprivate:\n  std::ostream *os_;\n  char delim_;\n  bool first_{true};\n};\n\n} // namespace mgbubble\n\n/** @} */\n"
  },
  {
    "path": "include/UChainService/api/restful/utility/Stream_buf.hpp",
    "content": "/*\r\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS).\r\n * Copyright (C) 2013-2018 Swirly Cloud Limited.\r\n *\r\n * This program is free software; you can redistribute it and/or modify it under the terms of the\r\n * GNU General Public License as published by the Free Software Foundation; either version 2 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\r\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r\n * General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU General Public License along with this program; if\r\n * not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\r\n * 02110-1301, USA.\r\n */\r\n#ifndef UCD_STREAM_HPP\r\n#define UCD_STREAM_HPP\r\n\r\n#include \"mongoose/mongoose.h\"\r\n\r\n#include <ostream>\r\n\r\n/**\r\n * @addtogroup App\r\n * @{\r\n */\r\n\r\nnamespace mgbubble\r\n{\r\n\r\nclass StreamBuf : public std::streambuf\r\n{\r\npublic:\r\n  explicit StreamBuf(mbuf &buf);\r\n  ~StreamBuf() noexcept override;\r\n\r\n  // Copy.\r\n  StreamBuf(const StreamBuf &rhs) = delete;\r\n  StreamBuf &operator=(const StreamBuf &rhs) = delete;\r\n\r\n  // Move.\r\n  StreamBuf(StreamBuf &&) = delete;\r\n  StreamBuf &operator=(StreamBuf &&) = delete;\r\n\r\n  const char_type *data() const noexcept { return buf_.buf; }\r\n  std::streamsize size() const noexcept { return buf_.len; }\r\n  void reset() noexcept;\r\n  void setContentLength(size_t pos, size_t len) noexcept;\r\n\r\nprotected:\r\n  int_type overflow(int_type c) noexcept override;\r\n\r\n  std::streamsize xsputn(const char_type *s, std::streamsize count) noexcept override;\r\n\r\nprivate:\r\n  mbuf &buf_;\r\n};\r\n\r\nclass OStream : public std::ostream\r\n{\r\npublic:\r\n  OStream();\r\n  ~OStream() noexcept override;\r\n\r\n  // Copy.\r\n  OStream(const OStream &rhs) = delete;\r\n  OStream &operator=(const OStream &rhs) = delete;\r\n\r\n  // Move.\r\n  OStream(OStream &&) = delete;\r\n  OStream &operator=(OStream &&) = delete;\r\n\r\n  StreamBuf *rdbuf() const noexcept { return static_cast<StreamBuf *>(std::ostream::rdbuf()); }\r\n  const char_type *data() const noexcept { return rdbuf()->data(); }\r\n  std::streamsize size() const noexcept { return rdbuf()->size(); }\r\n  StreamBuf *rdbuf(StreamBuf *sb) noexcept\r\n  {\r\n    return static_cast<StreamBuf *>(std::ostream::rdbuf(sb));\r\n  }\r\n  void reset(int status, const char *reason, const char *content_type = \"text/plain\", const char *charset = \"utf-8\") noexcept;\r\n  void setContentLength() noexcept;\r\n\r\nprivate:\r\n  size_t headSize_{0};\r\n  size_t lengthAt_{0};\r\n};\r\n\r\n} // namespace mgbubble\r\n\r\n/** @} */\r\n\r\n#endif // UCD_STREAM_HPP\r\n"
  },
  {
    "path": "include/UChainService/api/restful/utility/String.hpp",
    "content": "/*\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS) - UChain.\n *\n * This program is free software; you can redistribute it and/or modify it under the terms of the\n * GNU General Public License as published by the Free Software Foundation; either version 2 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along with this program; if\n * not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n * 02110-1301, USA.\n */\n#pragma once\n\n#include <cstring>\n#include <sstream>\n\n#include <UChainService/api/restful/compat/define.hpp>\n#include <UChainService/api/restful/compat/string_view.h>\n#include <UChainService/api/restful/utility/Compare.hpp>\n\n/**\n * @addtogroup Util\n * @{\n */\n\nnamespace mgbubble\n{\n\nconstexpr string_view operator\"\"_sv(const char *str, std::size_t len) noexcept\n{\n  return {str, len};\n}\n\ntemplate <std::size_t MaxN>\nstruct StringData\n{\n\n  // Length in the first cache-line.\n  std::size_t len;\n  char buf[MaxN];\n};\n\ntemplate <std::size_t MaxN>\nconstexpr string_view operator+(const StringData<MaxN> &s) noexcept\n{\n  return {s.buf, s.len};\n}\n\n/**\n * String buffer with fixed upper-bound.\n */\ntemplate <std::size_t MaxN>\nclass String\n{\npublic:\n  template <std::size_t MaxR>\n  String(const String<MaxR> &rhs) noexcept\n  {\n    assign(rhs.data(), rhs.size());\n  }\n  String(string_view rhs) noexcept { assign(rhs.data(), rhs.size()); }\n  String() noexcept { clear(); }\n\n  ~String() noexcept = default;\n\n  // Copy.\n  String(const String &rhs) noexcept { assign(rhs.data(), rhs.size()); }\n  constexpr String &operator=(const String &rhs) const noexcept\n  {\n    assign(rhs.data(), rhs.size());\n    return *this;\n  }\n\n  // Move.\n  constexpr String(String &&) noexcept = default;\n  String &operator=(String &&) noexcept = default;\n\n  template <std::size_t MaxR>\n  constexpr String &operator=(const String<MaxR> &rhs) const noexcept\n  {\n    assign(rhs.data(), rhs.size());\n    return *this;\n  }\n  constexpr String &operator=(string_view rhs) const noexcept\n  {\n    assign(rhs.data(), rhs.size());\n    return *this;\n  }\n  template <std::size_t MaxR>\n  constexpr int compare(const String<MaxR> &rhs) const noexcept\n  {\n    return compare(rhs.data(), rhs.size());\n  }\n  constexpr int compare(string_view rhs) const noexcept\n  {\n    return compare(rhs.data(), rhs.size());\n  }\n  constexpr const char *data() const noexcept { return buf_; }\n  constexpr bool empty() const noexcept { return len_ == 0; }\n  constexpr size_t size() const noexcept { return len_; }\n  constexpr void clear() noexcept { len_ = 0; }\n\nprivate:\n  constexpr int compare(const char *rdata, std::size_t rlen) const noexcept\n  {\n    int result{std::memcmp(buf_, rdata, std::min(len_, rlen))};\n    if (result == 0)\n    {\n      result = mgbubble::compare(len_, rlen);\n    }\n    return result;\n  }\n  constexpr void assign(const char *rdata, std::size_t rlen) const noexcept\n  {\n    len_ = std::min(MaxN, rlen);\n    if (len_ > 0)\n    {\n      std::memcpy(buf_, rdata, len_);\n    }\n  }\n  // Length in the first cache-line.\n  std::size_t len_;\n  char buf_[MaxN];\n};\n\ntemplate <std::size_t MaxN>\nconstexpr string_view operator+(const String<MaxN> &s) noexcept\n{\n  return {s.data(), s.size()};\n}\n\ntemplate <std::size_t MaxL, std::size_t MaxR>\nconstexpr bool operator==(const String<MaxL> &lhs, const String<MaxR> &rhs) noexcept\n{\n  return lhs.compare(rhs) == 0;\n}\n\ntemplate <std::size_t MaxN>\nconstexpr bool operator==(const String<MaxN> &lhs, string_view rhs) noexcept\n{\n  return lhs.compare(rhs) == 0;\n}\n\ntemplate <std::size_t MaxN>\nconstexpr bool operator==(string_view lhs, const String<MaxN> &rhs) noexcept\n{\n  return 0 == rhs.compare(lhs);\n}\n\ntemplate <std::size_t MaxL, std::size_t MaxR>\nconstexpr bool operator!=(const String<MaxL> &lhs, const String<MaxR> &rhs) noexcept\n{\n  return lhs.compare(rhs) != 0;\n}\n\ntemplate <std::size_t MaxN>\nconstexpr bool operator!=(const String<MaxN> &lhs, string_view rhs) noexcept\n{\n  return lhs.compare(rhs) != 0;\n}\n\ntemplate <std::size_t MaxN>\nconstexpr bool operator!=(string_view lhs, const String<MaxN> &rhs) noexcept\n{\n  return 0 != rhs.compare(lhs);\n}\n\ntemplate <std::size_t MaxL, std::size_t MaxR>\nconstexpr bool operator<(const String<MaxL> &lhs, const String<MaxR> &rhs) noexcept\n{\n  return lhs.compare(rhs) < 0;\n}\n\ntemplate <std::size_t MaxN>\nconstexpr bool operator<(const String<MaxN> &lhs, string_view rhs) noexcept\n{\n  return lhs.compare(rhs) < 0;\n}\n\ntemplate <std::size_t MaxN>\nconstexpr bool operator<(string_view lhs, const String<MaxN> &rhs) noexcept\n{\n  return 0 < rhs.compare(lhs);\n}\n\ntemplate <std::size_t MaxL, std::size_t MaxR>\nconstexpr bool operator<=(const String<MaxL> &lhs, const String<MaxR> &rhs) noexcept\n{\n  return lhs.compare(rhs) <= 0;\n}\n\ntemplate <std::size_t MaxN>\nconstexpr bool operator<=(const String<MaxN> &lhs, string_view rhs) noexcept\n{\n  return lhs.compare(rhs) <= 0;\n}\n\ntemplate <std::size_t MaxN>\nconstexpr bool operator<=(string_view lhs, const String<MaxN> &rhs) noexcept\n{\n  return 0 <= rhs.compare(lhs);\n}\n\ntemplate <std::size_t MaxL, std::size_t MaxR>\nconstexpr bool operator>(const String<MaxL> &lhs, const String<MaxR> &rhs) noexcept\n{\n  return lhs.compare(rhs) > 0;\n}\n\ntemplate <std::size_t MaxN>\nconstexpr bool operator>(const String<MaxN> &lhs, string_view rhs) noexcept\n{\n  return lhs.compare(rhs) > 0;\n}\n\ntemplate <std::size_t MaxN>\nconstexpr bool operator>(string_view lhs, const String<MaxN> &rhs) noexcept\n{\n  return 0 > rhs.compare(lhs);\n}\n\ntemplate <std::size_t MaxL, std::size_t MaxR>\nconstexpr bool operator>=(const String<MaxL> &lhs, const String<MaxR> &rhs) noexcept\n{\n  return lhs.compare(rhs) >= 0;\n}\n\ntemplate <std::size_t MaxN>\nconstexpr bool operator>=(const String<MaxN> &lhs, string_view rhs) noexcept\n{\n  return lhs.compare(rhs) >= 0;\n}\n\ntemplate <std::size_t MaxN>\nconstexpr bool operator>=(string_view lhs, const String<MaxN> &rhs) noexcept\n{\n  return 0 >= rhs.compare(lhs);\n}\n\ntemplate <std::size_t MaxN>\nconstexpr std::ostream &operator<<(std::ostream &os, const String<MaxN> &rhs) noexcept\n{\n  return os << +rhs;\n}\n\ntemplate <typename ValueT, typename std::enable_if_t<std::is_arithmetic<ValueT>::value> * = nullptr>\nstd::string toString(ValueT val)\n{\n  return std::to_string(val);\n}\n\ntemplate <typename ValueT, typename std::enable_if_t<!std::is_arithmetic<ValueT>::value> * = nullptr>\nstd::string toString(const ValueT &val)\n{\n  std::stringstream ss;\n  ss << val;\n  return ss.str();\n}\n\nUC_API unsigned long stoul(string_view sv) noexcept;\n\n} // namespace mgbubble\n\n/** @} */\n"
  },
  {
    "path": "include/UChainService/api/restful/utility/Tokeniser.hpp",
    "content": "/*\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS) - UChain.\n *\n * This program is free software; you can redistribute it and/or modify it under the terms of the\n * GNU General Public License as published by the Free Software Foundation; either version 2 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along with this program; if\n * not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n * 02110-1301, USA.\n */\n\n#pragma once\n\n#include <UChainService/api/restful/utility/String.hpp>\n\n#include <algorithm>\n\n/**\n * @addtogroup Util\n * @{\n */\n\nnamespace mgbubble\n{\n\ntemplate <char DelimN>\nclass Tokeniser\n{\npublic:\n  explicit Tokeniser(string_view buf) noexcept { reset(buf); }\n  explicit Tokeniser() noexcept { reset(\"\"); }\n  ~Tokeniser() noexcept = default;\n\n  // Copy.\n  Tokeniser(const Tokeniser &rhs) noexcept = default;\n  Tokeniser &operator=(const Tokeniser &rhs) noexcept = default;\n\n  // Move.\n  Tokeniser(Tokeniser &&) noexcept = default;\n  Tokeniser &operator=(Tokeniser &&) noexcept = default;\n\n  string_view top() const noexcept { return buf_.substr(i_ - buf_.cbegin(), j_ - i_); }\n  bool empty() const noexcept { return i_ == buf_.cend(); }\n  void reset(string_view buf) noexcept\n  {\n    buf_ = buf;\n    i_ = buf_.cbegin();\n    j_ = std::find(i_, buf_.cend(), DelimN);\n  }\n  void pop() noexcept\n  {\n    if (j_ != buf_.cend())\n    {\n      i_ = j_ + 1;\n      j_ = std::find(i_, buf_.cend(), DelimN);\n    }\n    else\n    {\n      i_ = j_;\n    }\n  }\n\nprivate:\n  string_view buf_;\n  string_view::const_iterator i_, j_;\n};\n\n} // namespace mgbubble\n\n/** @} */\n"
  },
  {
    "path": "include/UChainService/consensus/consensus.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-consensus.\n *\n * UChain-consensus is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CONSENSUS_CONSENSUS_HPP\n#define UC_CONSENSUS_CONSENSUS_HPP\n\n#include <cstddef>\n#include <UChainService/consensus/define.hpp>\n#include <UChainService/consensus/export.hpp>\n#include \"pubkey.h\"\n#include \"script/script_error.h\"\n\nnamespace libbitcoin\n{\nnamespace consensus\n{\n\n// Helper class, not published. This is tested internal to verify_script.\nclass BCK_API TxInputStream\n{\n  public:\n    TxInputStream(const unsigned char *transaction, size_t transaction_size);\n    TxInputStream &read(char *destination, size_t size);\n\n  private:\n    static ECCVerifyHandle secp256k1_context_;\n    const unsigned char *source_;\n    size_t remaining_;\n};\n\n// These are not published in the public header but are exposed here for test.\nBCK_API verify_result_type script_error_to_verify_result(ScriptError_t code);\nBCK_API unsigned int verify_flags_to_script_flags(unsigned int flags);\n\n} // namespace consensus\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainService/consensus/define.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-consensus.\n *\n * UChain-consensus is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CONSENSUS_DEFINE_HPP\n#define UC_CONSENSUS_DEFINE_HPP\n\n// See http://gcc.gnu.org/wiki/Visibility\n\n// Generic helper definitions for shared library support\n#if defined _MSC_VER || defined __CYGWIN__\n#define BCK_HELPER_DLL_IMPORT __declspec(dllimport)\n#define BCK_HELPER_DLL_EXPORT __declspec(dllexport)\n#define BCK_HELPER_DLL_LOCAL\n#else\n#if __GNUC__ >= 4\n#define BCK_HELPER_DLL_IMPORT __attribute__((visibility(\"default\")))\n#define BCK_HELPER_DLL_EXPORT __attribute__((visibility(\"default\")))\n#define BCK_HELPER_DLL_LOCAL __attribute__((visibility(\"internal\")))\n#else\n#define BCK_HELPER_DLL_IMPORT\n#define BCK_HELPER_DLL_EXPORT\n#define BCK_HELPER_DLL_LOCAL\n#endif\n#endif\n\n// Now we use the generic helper definitions above to\n// define BCK_API and BCK_INTERNAL.\n// BCK_API is used for the public API symbols. It either DLL imports or\n// DLL exports (or does nothing for static build)\n// BCK_INTERNAL is used for non-api symbols.\n\n#if defined BCK_STATIC\n#define BCK_API\n#define BCK_INTERNAL\n#elif defined BCK_DLL\n#define BCK_API BCK_HELPER_DLL_EXPORT\n#define BCK_INTERNAL BCK_HELPER_DLL_LOCAL\n#else\n#define BCK_API BCK_HELPER_DLL_IMPORT\n#define BCK_INTERNAL BCK_HELPER_DLL_LOCAL\n#endif\n\n#endif\n"
  },
  {
    "path": "include/UChainService/consensus/export.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-consensus.\n *\n * UChain-consensus is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CONSENSUS_EXPORT_HPP\n#define UC_CONSENSUS_EXPORT_HPP\n\n#include <cstddef>\n#include <UChainService/consensus/define.hpp>\n#include <UChainService/consensus/version.hpp>\n\nnamespace libbitcoin\n{\nnamespace consensus\n{\n\n/**\n * Result values from calling verify_script.\n */\ntypedef enum verify_result_type\n{\n    // Logical result\n    verify_result_eval_false = 0,\n    verify_result_eval_true,\n\n    // Max size errors\n    verify_result_script_size,\n    verify_result_push_size,\n    verify_result_op_count,\n    verify_result_stack_size,\n    verify_result_sig_count,\n    verify_result_pubkey_count,\n\n    // Failed verify operations\n    verify_result_verify,\n    verify_result_equalverify,\n    verify_result_checkmultisigverify,\n    verify_result_checksigverify,\n    verify_result_numequalverify,\n\n    // Logical/Format/Canonical errors\n    verify_result_bad_opcode,\n    verify_result_disabled_opcode,\n    verify_result_invalid_stack_operation,\n    verify_result_invalid_altstack_operation,\n    verify_result_unbalanced_conditional,\n\n    // BIP62 errors\n    verify_result_sig_hashtype,\n    verify_result_sig_der,\n    verify_result_minimaldata,\n    verify_result_sig_pushonly,\n    verify_result_sig_high_s,\n    verify_result_sig_nulldummy,\n    verify_result_pubkeytype,\n    verify_result_cleanstack,\n\n    // Softfork safeness\n    verify_result_discourage_upgradable_nops,\n\n    // Other\n    verify_result_op_return,\n    verify_result_unknown_error,\n\n    // augmention codes for tx deserialization\n    verify_result_tx_invalid,\n    verify_result_tx_size_invalid,\n    verify_result_tx_input_invalid,\n\n    // BIP65 errors\n    verify_result_negative_locktime,\n    verify_result_unsatisfied_locktime\n} verify_result;\n\n/**\n * Flags to use when calling verify_script.\n */\ntypedef enum verify_flags_type\n{\n    /**\n     * Set no flags.\n     */\n    verify_flags_none = 0,\n\n    /**\n     * Evaluate P2SH subscripts (softfork safe, BIP16).\n     */\n    verify_flags_p2sh = (1U << 0),\n\n    /**\n     * Passing a non-strict-DER signature or one with undefined hashtype to a\n     * checksig operation causes script failure. Evaluating a pubkey that is\n     * not (0x04 + 64 bytes) or (0x02 or 0x03 + 32 bytes) by checksig causes\n     * script failure. (softfork safe, but not used or intended as a consensus\n     * rule).\n     */\n    verify_flags_strictenc = (1U << 1),\n\n    /**\n     * Passing a non-strict-DER signature to a checksig operation causes script\n     * failure (softfork safe, BIP62 rule 1).\n     */\n    verify_flags_dersig = (1U << 2),\n\n    /**\n     * Passing a non-strict-DER signature or one with S > order/2 to a checksig\n     * operation causes script failure\n     * (softfork safe, BIP62 rule 5).\n     */\n    verify_flags_low_s = (1U << 3),\n\n    /**\n     * verify dummy stack item consumed by CHECKMULTISIG is of zero-length\n     * (softfork safe, BIP62 rule 7).\n     */\n    verify_flags_nulldummy = (1U << 4),\n\n    /**\n     * Using a non-push operator in the scriptSig causes script failure\n     * (softfork safe, BIP62 rule 2).\n     */\n    verify_flags_sigpushonly = (1U << 5),\n\n    /**\n     * Require minimal encodings for all push operations (OP_0... OP_16,\n     * OP_1NEGATE where possible, direct pushes up to 75 bytes, OP_PUSHDATA\n     * up to 255 bytes, OP_PUSHDATA2 for anything larger). Evaluating any other\n     * push causes the script to fail (BIP62 rule 3). In addition, whenever a\n     * stack element is interpreted as a number, it must be of minimal length\n     * (BIP62 rule 4).(softfork safe)\n     */\n    verify_flags_minimaldata = (1U << 6),\n\n    /**\n     * Discourage use of NOPs reserved for upgrades (NOP1,3-10)\n     * Provided so that nodes can avoid accepting or mining transactions\n     * containing executed NOP's whose meaning may change after a soft-fork,\n     * thus rendering the script invalid; with this flag set executing\n     * discouraged NOPs fails the script. This verification flag will never be\n     * a mandatory flag applied to scripts in a block. NOPs that are not\n     * executed, e.g.  within an unexecuted IF ENDIF block, are *not* rejected.\n     */\n    verify_flags_discourage_upgradable_nops = (1U << 7),\n\n    /**\n     * Require that only a single stack element remains after evaluation. This\n     * changes the success criterion from \"At least one stack element must\n     * remain, and when interpreted as a boolean, it must be true\" to \"Exactly\n     * one stack element must remain, and when interpreted as a boolean, it\n     * must be true\". (softfork safe, BIP62 rule 6)\n     * Note: verify_flags_cleanstack must be used with verify_flags_p2sh.\n     */\n    verify_flags_cleanstack = (1U << 8),\n\n    /**\n     * Verify CHECKLOCKTIMEVERIFY, see BIP65 for details.\n     */\n    verify_flags_checklocktimeverify = (1U << 9),\n\n    /**\n     * Verify CHECKATTENUATIONVERIFY\n     */\n    verify_flags_checkattenuationverify = (1U << 10)\n} verify_flags;\n\n/**\n * Verify that the transaction input correctly spends the previous output,\n * considering any additional constraints specified by flags.\n * @param[in]  transaction         The transaction with the script to verify.\n * @param[in]  transaction_size    The byte length of the transaction.\n * @param[in]  prevout_script      The script public key to verify against.\n * @param[in]  prevout_script_size The byte length of the script public key.\n * @param[in]  tx_input_index      The zero-based index of the transaction\n *                                 input with signature to be verified.\n * @param[in]  flags               Verification constraint flags.\n * @returns                        A script verification result code.\n */\nBCK_API verify_result_type verify_script(const unsigned char *transaction,\n                                         size_t transaction_size, const unsigned char *prevout_script,\n                                         size_t prevout_script_size, unsigned int tx_input_index,\n                                         unsigned int flags);\n\n} // namespace consensus\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainService/consensus/libdevcore/Base64.h",
    "content": "/*\n   base64.cpp and base64.h\n\n   Copyright (C) 2004-2008 René Nyffenegger\n\n   This source code is provided 'as-is', without any express or implied\n   warranty. In no event will the author be held liable for any damages\n   arising from the use of this software.\n\n   Permission is granted to anyone to use this software for any purpose,\n   including commercial applications, and to alter it and redistribute it\n   freely, subject to the following restrictions:\n\n   1. The origin of this source code must not be misrepresented; you must not\n      claim that you wrote the original source code. If you use this source code\n      in a product, an acknowledgment in the product documentation would be\n      appreciated but is not required.\n\n   2. Altered source versions must be plainly marked as such, and must not be\n      misrepresented as being the original source code.\n\n   3. This notice may not be removed or altered from any source distribution.\n\n   René Nyffenegger rene.nyffenegger@adp-gmbh.ch\n*/\n/// Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c\n/// Originally by René Nyffenegger.\n/// DEVified by Gav Wood.\n#pragma once\n\n#include <string>\n#include \"Common.h\"\n#include \"FixedHash.h\"\n\nnamespace libbitcoin\n{\n\nstd::string toBase64(bytesConstRef _in);\nbytes fromBase64(std::string const &_in);\n\ntemplate <size_t N>\ninline std::string toBase36(FixedHash<N> const &_h)\n{\n    static char const *c_alphabet = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n    typename FixedHash<N>::Arith a = _h;\n    std::string ret;\n    for (; a > 0; a /= 36)\n    {\n        unsigned r = (unsigned)(a - a / 36 * 36); // boost's % is broken\n        ret = c_alphabet[r] + ret;\n    }\n    return ret;\n}\n\ntemplate <size_t N>\ninline FixedHash<N> fromBase36(std::string const &_h)\n{\n    typename FixedHash<N>::Arith ret = 0;\n    for (char c : _h)\n        ret = ret * 36 + (c < 'A' ? c - '0' : (c - 'A' + 10));\n    return ret;\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/consensus/libdevcore/BuildInfo.h",
    "content": "#pragma once\n\n#define ETH_PROJECT_VERSION \"1.3.0\"\n#define ETH_COMMIT_HASH b27e9df6eede86bff729318193338284fba3b543\n#define ETH_CLEAN_REPO 1\n#define ETH_BUILD_TYPE RelWithDebInfo\n#define ETH_BUILD_OS Linux\n#define ETH_BUILD_COMPILER g++\n#define ETH_BUILD_JIT_MODE Interpreter\n#define ETH_BUILD_PLATFORM Linux / g++ / Interpreter\n#define ETH_BUILD_NUMBER 65535\n#define ETH_VERSION_SUFFIX \"\"\n"
  },
  {
    "path": "include/UChainService/consensus/libdevcore/Common.h",
    "content": "/*\n    This file is part of cpp-ethereum.\n\n    cpp-ethereum is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    cpp-ethereum is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/** @file Common.h\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n *\n * Very common stuff (i.e. that every other header needs except vector_ref.h).\n */\n\n#pragma once\n\n// way to many unsigned to size_t warnings in 32 bit build\n#ifdef _M_IX86\n#pragma warning(disable : 4244)\n#endif\n\n#if _MSC_VER && _MSC_VER < 1900\n#define _ALLOW_KEYWORD_MACROS\n#define noexcept throw()\n#endif\n\n//#ifdef __INTEL_COMPILER\n//#pragma warning(disable:3682) //call through incomplete class\n//#endif\n\n#include <map>\n#include <unordered_map>\n#include <vector>\n#include <set>\n#include <unordered_set>\n#include <functional>\n#include <string>\n#include <chrono>\n//#pragma warning(push)\n//#pragma GCC diagnostic push\n//#pragma GCC diagnostic ignored \"-Wunused-parameter\"\n#include <boost/version.hpp>\n/*#if (BOOST_VERSION == 105800)\n    #include \"boost_multiprecision_number_compare_bug_workaround.hpp\"\n#endif*/\n//#include <boost/multiprecision/detail/number_compare.hpp>\n#include <boost/multiprecision/cpp_int.hpp>\n#include <UChain/coin/math/hash.hpp>\n//#pragma warning(pop)\n//#pragma GCC diagnostic pop\n#include \"vector_ref.h\"\n\n// CryptoPP defines byte in the global namespace, so must we.\nusing byte = uint8_t;\n\n// Quote a given token stream to turn it into a string.\n#define DEV_QUOTED_HELPER(s) #s\n#define DEV_QUOTED(s) DEV_QUOTED_HELPER(s)\n\n#define DEV_IGNORE_EXCEPTIONS(X) \\\n    try                          \\\n    {                            \\\n        X;                       \\\n    }                            \\\n    catch (...)                  \\\n    {                            \\\n    }\n\n#define DEV_IF_NO_ELSE(X) \\\n    if (!(X))             \\\n    {                     \\\n    }                     \\\n    else\n#define DEV_IF_THROWS(X) \\\n    try                  \\\n    {                    \\\n        X;               \\\n    }                    \\\n    catch (...)\n\nnamespace libbitcoin\n{\n\nextern char const *Version;\n\nstatic const std::string EmptyString;\n\n// Binary data types.\nusing bytes = std::vector<byte>;\nusing bytesRef = vector_ref<byte>;\nusing bytesConstRef = vector_ref<byte const>;\n\ntemplate <class T>\nclass secure_vector\n{\n  public:\n    secure_vector() {}\n    secure_vector(secure_vector<T> const & /*_c*/) = default; // See https://github.com/ethereum/libweb3core/pull/44\n    explicit secure_vector(unsigned _size) : m_data(_size) {}\n    explicit secure_vector(unsigned _size, T _item) : m_data(_size, _item) {}\n    explicit secure_vector(std::vector<T> const &_c) : m_data(_c) {}\n    explicit secure_vector(vector_ref<T> _c) : m_data(_c.data(), _c.data() + _c.size()) {}\n    explicit secure_vector(vector_ref<const T> _c) : m_data(_c.data(), _c.data() + _c.size()) {}\n    ~secure_vector() { ref().cleanse(); }\n\n    secure_vector<T> &operator=(secure_vector<T> const &_c)\n    {\n        if (&_c == this)\n            return *this;\n\n        ref().cleanse();\n        m_data = _c.m_data;\n        return *this;\n    }\n    std::vector<T> &writable()\n    {\n        clear();\n        return m_data;\n    }\n    std::vector<T> const &makeInsecure() const { return m_data; }\n\n    void clear() { ref().cleanse(); }\n\n    vector_ref<T> ref() { return vector_ref<T>(&m_data); }\n    vector_ref<T const> ref() const { return vector_ref<T const>(&m_data); }\n\n    size_t size() const { return m_data.size(); }\n    bool empty() const { return m_data.empty(); }\n\n    void swap(secure_vector<T> &io_other) { m_data.swap(io_other.m_data); }\n\n  private:\n    std::vector<T> m_data;\n};\n\nusing bytesSec = secure_vector<byte>;\n\n// Numeric types.\nusing bigint = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>>;\nusing u64 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<64, 64, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;\nusing u128 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<128, 128, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;\nusing u256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;\nusing s256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>>;\nusing u160 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<160, 160, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;\nusing s160 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<160, 160, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>>;\nusing u512 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<512, 512, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;\nusing s512 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<512, 512, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>>;\nusing u256s = std::vector<u256>;\nusing u160s = std::vector<u160>;\nusing u256Set = std::set<u256>;\nusing u160Set = std::set<u160>;\n\n// Map types.\nusing StringMap = std::map<std::string, std::string>;\nusing BytesMap = std::map<bytes, bytes>;\nusing u256Map = std::map<u256, u256>;\nusing HexMap = std::map<bytes, bytes>;\n\n// Hash types.\nusing StringHashMap = std::unordered_map<std::string, std::string>;\nusing u256HashMap = std::unordered_map<u256, u256>;\n\n// String types.\nusing strings = std::vector<std::string>;\n\n// Fixed-length string types.\nusing string32 = std::array<char, 32>;\nstatic const string32 ZeroString32 = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};\n\n// Null/Invalid values for convenience.\nstatic const bytes NullBytes;\nstatic const std::map<u256, u256> EmptyMapU256U256;\nextern const u256 Invalid256;\n\n/// Interprets @a _u as a two's complement signed number and returns the resulting s256.\ninline s256 u2s(u256 _u)\n{\n    static const bigint c_end = bigint(1) << 256;\n    if (boost::multiprecision::bit_test(_u, 255))\n        return s256(-(c_end - _u));\n    else\n        return s256(_u);\n}\n\n/// @returns the two's complement signed representation of the signed number _u.\ninline u256 s2u(s256 _u)\n{\n    static const bigint c_end = bigint(1) << 256;\n    if (_u >= 0)\n        return u256(_u);\n    else\n        return u256(c_end + _u);\n}\n\n/// Converts given int to a string and appends one of a series of units according to its size.\nstd::string inUnits(bigint const &_b, strings const &_units);\n\n/// @returns the smallest n >= 0 such that (1 << n) >= _x\ninline unsigned int toLog2(u256 _x)\n{\n    unsigned ret;\n    for (ret = 0; _x >>= 1; ++ret)\n    {\n    }\n    return ret;\n}\n\ntemplate <size_t n>\ninline u256 exp10()\n{\n    return exp10<n - 1>() * u256(10);\n}\n\ntemplate <>\ninline u256 exp10<0>()\n{\n    return u256(1);\n}\n\n/// @returns the absolute distance between _a and _b.\ntemplate <class N>\ninline N diff(N const &_a, N const &_b)\n{\n    return std::max(_a, _b) - std::min(_a, _b);\n}\n\n/// RAII utility class whose destructor calls a given function.\nclass ScopeGuard\n{\n  public:\n    ScopeGuard(std::function<void(void)> _f) : m_f(_f) {}\n    ~ScopeGuard() { m_f(); }\n\n  private:\n    std::function<void(void)> m_f;\n};\n\n/// Inheritable for classes that have invariants.\nclass HasInvariants\n{\n  public:\n    /// Reimplement to specify the invariants.\n    virtual bool invariants() const = 0;\n};\n\n/// RAII checker for invariant assertions.\nclass InvariantChecker\n{\n  public:\n    InvariantChecker(HasInvariants *_this, char const *_fn, char const *_file, int _line) : m_this(_this), m_function(_fn), m_file(_file), m_line(_line) { checkInvariants(_this, _fn, _file, _line, true); }\n    ~InvariantChecker() { checkInvariants(m_this, m_function, m_file, m_line, false); }\n    /// Check invariants are met, throw if not.\n    static void checkInvariants(HasInvariants const *_this, char const *_fn, char const *_file, int line, bool _pre);\n\n  private:\n    HasInvariants const *m_this;\n    char const *m_function;\n    char const *m_file;\n    int m_line;\n};\n\n/// Scope guard for invariant check in a class derived from HasInvariants.\n#if ETH_DEBUG\n#define DEV_INVARIANT_CHECK ::dev::InvariantChecker __dev_invariantCheck(this, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)\n#define DEV_INVARIANT_CHECK_HERE ::dev::InvariantChecker::checkInvariants(this, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__, true)\n#else\n#define DEV_INVARIANT_CHECK (void)0;\n#define DEV_INVARIANT_CHECK_HERE (void)0;\n#endif\n\n/// Simple scope-based timer helper.\nclass TimerHelper\n{\n  public:\n    TimerHelper(std::string const &_id, unsigned _msReportWhenGreater = 0) : m_t(std::chrono::high_resolution_clock::now()), m_id(_id), m_ms(_msReportWhenGreater) {}\n    ~TimerHelper();\n\n  private:\n    std::chrono::high_resolution_clock::time_point m_t;\n    std::string m_id;\n    unsigned m_ms;\n};\n\nclass Timer\n{\n  public:\n    Timer() { restart(); }\n\n    std::chrono::high_resolution_clock::duration duration() const { return std::chrono::high_resolution_clock::now() - m_t; }\n    double elapsed() const { return std::chrono::duration_cast<std::chrono::microseconds>(duration()).count() / 1000000.0; }\n    void restart() { m_t = std::chrono::high_resolution_clock::now(); }\n\n  private:\n    std::chrono::high_resolution_clock::time_point m_t;\n};\n\n#define DEV_TIMED(S) for (::std::pair<::dev::TimerHelper, bool> __eth_t(S, true); __eth_t.second; __eth_t.second = false)\n#define DEV_TIMED_SCOPE(S) ::dev::TimerHelper __eth_t(S)\n#if defined(_WIN32)\n#define DEV_TIMED_FUNCTION DEV_TIMED_SCOPE(__FUNCSIG__)\n#else\n#define DEV_TIMED_FUNCTION DEV_TIMED_SCOPE(__PRETTY_FUNCTION__)\n#endif\n\n#define DEV_TIMED_ABOVE(S, MS) for (::std::pair<::dev::TimerHelper, bool> __eth_t(::dev::TimerHelper(S, MS), true); __eth_t.second; __eth_t.second = false)\n#define DEV_TIMED_SCOPE_ABOVE(S, MS) ::dev::TimerHelper __eth_t(S, MS)\n#if defined(_WIN32)\n#define DEV_TIMED_FUNCTION_ABOVE(MS) DEV_TIMED_SCOPE_ABOVE(__FUNCSIG__, MS)\n#else\n#define DEV_TIMED_FUNCTION_ABOVE(MS) DEV_TIMED_SCOPE_ABOVE(__PRETTY_FUNCTION__, MS)\n#endif\n\n#ifdef _MSC_VER\n// TODO.\n#define DEV_UNUSED\n#else\n#define DEV_UNUSED __attribute__((unused))\n#endif\n\nenum class WithExisting : int\n{\n    Trust = 0,\n    Verify,\n    Rescue,\n    Kill\n};\n\n/// Get the current time in seconds since the epoch in UTC\nuint64_t utcTime();\n\n} // namespace libbitcoin\n\nnamespace std\n{\n\ninline libbitcoin::WithExisting max(libbitcoin::WithExisting _a, libbitcoin::WithExisting _b)\n{\n    return static_cast<libbitcoin::WithExisting>(max(static_cast<int>(_a), static_cast<int>(_b)));\n}\n\ntemplate <>\nstruct hash<libbitcoin::u256>\n{\n    size_t operator()(libbitcoin::u256 const &_a) const\n    {\n        unsigned size = _a.backend().size();\n        auto limbs = _a.backend().limbs();\n        return libbitcoin::hash_range(limbs, limbs + size);\n    }\n};\n\n} // namespace std\n"
  },
  {
    "path": "include/UChainService/consensus/libdevcore/CommonData.h",
    "content": "/*\n    This file is part of cpp-ethereum.\n\n    cpp-ethereum is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    cpp-ethereum is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/** @file CommonData.h\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n *\n * Shared algorithms and data types.\n */\n\n#pragma once\n\n#include <vector>\n#include <algorithm>\n#include <unordered_set>\n#include <type_traits>\n#include <cstring>\n#include <string>\n#include \"Common.h\"\n\nnamespace libbitcoin\n{\n\n// String conversion functions, mainly to/from hex/nibble/byte representations.\n\nenum class WhenError\n{\n    DontThrow = 0,\n    Throw = 1,\n};\n\nenum class HexPrefix\n{\n    DontAdd = 0,\n    Add = 1,\n};\n/// Convert a series of bytes to the corresponding string of hex duplets.\n/// @param _w specifies the width of the first of the elements. Defaults to two - enough to represent a byte.\n/// @example toHex(\"A\\x69\") == \"4169\"\ntemplate <class T>\nstd::string toHex(T const &_data, int _w = 2, HexPrefix _prefix = HexPrefix::DontAdd)\n{\n    std::ostringstream ret;\n    unsigned ii = 0;\n    for (auto i : _data)\n        ret << std::hex << std::setfill('0') << std::setw(ii++ ? 2 : _w) << (int)(typename std::make_unsigned<decltype(i)>::type)i;\n    return (_prefix == HexPrefix::Add) ? \"0x\" + ret.str() : ret.str();\n}\n\n/// Converts a (printable) ASCII hex string into the corresponding byte stream.\n/// @example fromHex(\"41626261\") == asBytes(\"Abba\")\n/// If _throw = ThrowType::DontThrow, it replaces bad hex characters with 0's, otherwise it will throw an exception.\nbytes fromHex(std::string const &_s, WhenError _throw = WhenError::DontThrow);\n\n/// @returns true if @a _s is a hex string.\nbool isHex(std::string const &_s) noexcept;\n\n/// @returns true if @a _hash is a hash conforming to FixedHash type @a T.\ntemplate <class T>\nstatic bool isHash(std::string const &_hash)\n{\n    return (_hash.size() == T::size * 2 || (_hash.size() == T::size * 2 + 2 && _hash.substr(0, 2) == \"0x\")) && isHex(_hash);\n}\n\n/// Converts byte array to a string containing the same (binary) data. Unless\n/// the byte array happens to contain ASCII data, this won't be printable.\ninline std::string asString(bytes const &_b)\n{\n    return std::string((char const *)_b.data(), (char const *)(_b.data() + _b.size()));\n}\n\n/// Converts byte array ref to a string containing the same (binary) data. Unless\n/// the byte array happens to contain ASCII data, this won't be printable.\ninline std::string asString(bytesConstRef _b)\n{\n    return std::string((char const *)_b.data(), (char const *)(_b.data() + _b.size()));\n}\n\n/// Converts a string to a byte array containing the string's (byte) data.\ninline bytes asBytes(std::string const &_b)\n{\n    return bytes((byte const *)_b.data(), (byte const *)(_b.data() + _b.size()));\n}\n\n/// Converts a string into the big-endian base-16 stream of integers (NOT ASCII).\n/// @example asNibbles(\"A\")[0] == 4 && asNibbles(\"A\")[1] == 1\nbytes asNibbles(bytesConstRef const &_s);\n\n// Big-endian to/from host endian conversion functions.\n\n/// Converts a templated integer value to the big-endian byte-stream represented on a templated collection.\n/// The size of the collection object will be unchanged. If it is too small, it will not represent the\n/// value properly, if too big then the additional elements will be zeroed out.\n/// @a Out will typically be either std::string or bytes.\n/// @a T will typically by unsigned, u160, u256 or bigint.\ntemplate <class T, class Out>\ninline void toBigEndian(T _val, Out &o_out)\n{\n    static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, \"only unsigned types or bigint supported\"); //bigint does not carry sign bit on shift\n    for (auto i = o_out.size(); i != 0; _val >>= 8, i--)\n    {\n        T v = _val & (T)0xff;\n        o_out[i - 1] = (typename Out::value_type)(uint8_t)v;\n    }\n}\n\n/// Converts a big-endian byte-stream represented on a templated collection to a templated integer value.\n/// @a _In will typically be either std::string or bytes.\n/// @a T will typically by unsigned, u160, u256 or bigint.\ntemplate <class T, class _In>\ninline T fromBigEndian(_In const &_bytes)\n{\n    T ret = (T)0;\n    for (auto i : _bytes)\n        ret = (T)((ret << 8) | (byte)(typename std::make_unsigned<decltype(i)>::type)i);\n    return ret;\n}\n\n/// Convenience functions for toBigEndian\ninline std::string toBigEndianString(u256 _val)\n{\n    std::string ret(32, '\\0');\n    toBigEndian(_val, ret);\n    return ret;\n}\ninline std::string toBigEndianString(u160 _val)\n{\n    std::string ret(20, '\\0');\n    toBigEndian(_val, ret);\n    return ret;\n}\ninline bytes toBigEndian(u256 _val)\n{\n    bytes ret(32);\n    toBigEndian(_val, ret);\n    return ret;\n}\ninline bytes toBigEndian(u160 _val)\n{\n    bytes ret(20);\n    toBigEndian(_val, ret);\n    return ret;\n}\n\n/// Convenience function for toBigEndian.\n/// @returns a byte array just big enough to represent @a _val.\ntemplate <class T>\ninline bytes toCompactBigEndian(T _val, unsigned _min = 0)\n{\n    static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, \"only unsigned types or bigint supported\"); //bigint does not carry sign bit on shift\n    int i = 0;\n    for (T v = _val; v; ++i, v >>= 8)\n    {\n    }\n    bytes ret(std::max<unsigned>(_min, i), 0);\n    toBigEndian(_val, ret);\n    return ret;\n}\ninline bytes toCompactBigEndian(byte _val, unsigned _min = 0)\n{\n    return (_min || _val) ? bytes{_val} : bytes{};\n}\n\n/// Convenience function for toBigEndian.\n/// @returns a string just big enough to represent @a _val.\ntemplate <class T>\ninline std::string toCompactBigEndianString(T _val, unsigned _min = 0)\n{\n    static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, \"only unsigned types or bigint supported\"); //bigint does not carry sign bit on shift\n    int i = 0;\n    for (T v = _val; v; ++i, v >>= 8)\n    {\n    }\n    std::string ret(std::max<unsigned>(_min, i), '\\0');\n    toBigEndian(_val, ret);\n    return ret;\n}\n\n/// Convenience function for conversion of a u256 to hex\ninline std::string toHex(u256 val, HexPrefix prefix = HexPrefix::DontAdd)\n{\n    std::string str = toHex(toBigEndian(val));\n    return (prefix == HexPrefix::Add) ? \"0x\" + str : str;\n}\n\ninline std::string toCompactHex(u256 val, HexPrefix prefix = HexPrefix::DontAdd, unsigned _min = 0)\n{\n    std::string str = toHex(toCompactBigEndian(val, _min));\n    return (prefix == HexPrefix::Add) ? \"0x\" + str : str;\n}\n\n// Algorithms for string and string-like collections.\n\n/// Escapes a string into the C-string representation.\n/// @p _all if true will escape all characters, not just the unprintable ones.\nstd::string escaped(std::string const &_s, bool _all = true);\n\n/// Determines the length of the common prefix of the two collections given.\n/// @returns the number of elements both @a _t and @a _u share, in order, at the beginning.\n/// @example commonPrefix(\"Hello world!\", \"Hello, world!\") == 5\ntemplate <class T, class _U>\nunsigned commonPrefix(T const &_t, _U const &_u)\n{\n    unsigned s = std::min<unsigned>(_t.size(), _u.size());\n    for (unsigned i = 0;; ++i)\n        if (i == s || _t[i] != _u[i])\n            return i;\n    return s;\n}\n\n/// Creates a random, printable, word.\nstd::string randomWord();\n\n/// Determine bytes required to encode the given integer value. @returns 0 if @a _i is zero.\ntemplate <class T>\ninline unsigned bytesRequired(T _i)\n{\n    static_assert(std::is_same<bigint, T>::value || !std::numeric_limits<T>::is_signed, \"only unsigned types or bigint supported\"); //bigint does not carry sign bit on shift\n    unsigned i = 0;\n    for (; _i != 0; ++i, _i >>= 8)\n    {\n    }\n    return i;\n}\n\n/// Trims a given number of elements from the front of a collection.\n/// Only works for POD element types.\ntemplate <class T>\nvoid trimFront(T &_t, unsigned _elements)\n{\n    static_assert(std::is_pod<typename T::value_type>::value, \"\");\n    memmove(_t.data(), _t.data() + _elements, (_t.size() - _elements) * sizeof(_t[0]));\n    _t.resize(_t.size() - _elements);\n}\n\n/// Pushes an element on to the front of a collection.\n/// Only works for POD element types.\ntemplate <class T, class _U>\nvoid pushFront(T &_t, _U _e)\n{\n    static_assert(std::is_pod<typename T::value_type>::value, \"\");\n    _t.push_back(_e);\n    memmove(_t.data() + 1, _t.data(), (_t.size() - 1) * sizeof(_e));\n    _t[0] = _e;\n}\n\n/// Concatenate two vectors of elements of POD types.\ntemplate <class T>\ninline std::vector<T> &operator+=(std::vector<typename std::enable_if<std::is_pod<T>::value, T>::type> &_a, std::vector<T> const &_b)\n{\n    auto s = _a.size();\n    _a.resize(_a.size() + _b.size());\n    memcpy(_a.data() + s, _b.data(), _b.size() * sizeof(T));\n    return _a;\n}\n\n/// Concatenate two vectors of elements.\ntemplate <class T>\ninline std::vector<T> &operator+=(std::vector<typename std::enable_if<!std::is_pod<T>::value, T>::type> &_a, std::vector<T> const &_b)\n{\n    _a.reserve(_a.size() + _b.size());\n    for (auto &i : _b)\n        _a.push_back(i);\n    return _a;\n}\n\n/// Insert the contents of a container into a set\ntemplate <class T, class U>\nstd::set<T> &operator+=(std::set<T> &_a, U const &_b)\n{\n    for (auto const &i : _b)\n        _a.insert(i);\n    return _a;\n}\n\n/// Insert the contents of a container into an unordered_set\ntemplate <class T, class U>\nstd::unordered_set<T> &operator+=(std::unordered_set<T> &_a, U const &_b)\n{\n    for (auto const &i : _b)\n        _a.insert(i);\n    return _a;\n}\n\n/// Concatenate the contents of a container onto a vector\ntemplate <class T, class U>\nstd::vector<T> &operator+=(std::vector<T> &_a, U const &_b)\n{\n    for (auto const &i : _b)\n        _a.push_back(i);\n    return _a;\n}\n\n/// Insert the contents of a container into a set\ntemplate <class T, class U>\nstd::set<T> operator+(std::set<T> _a, U const &_b)\n{\n    return _a += _b;\n}\n\n/// Insert the contents of a container into an unordered_set\ntemplate <class T, class U>\nstd::unordered_set<T> operator+(std::unordered_set<T> _a, U const &_b)\n{\n    return _a += _b;\n}\n\n/// Concatenate the contents of a container onto a vector\ntemplate <class T, class U>\nstd::vector<T> operator+(std::vector<T> _a, U const &_b)\n{\n    return _a += _b;\n}\n\n/// Concatenate two vectors of elements.\ntemplate <class T>\ninline std::vector<T> operator+(std::vector<T> const &_a, std::vector<T> const &_b)\n{\n    std::vector<T> ret(_a);\n    return ret += _b;\n}\n\n/// Merge two sets of elements.\ntemplate <class T>\ninline std::set<T> &operator+=(std::set<T> &_a, std::set<T> const &_b)\n{\n    for (auto &i : _b)\n        _a.insert(i);\n    return _a;\n}\n\n/// Merge two sets of elements.\ntemplate <class T>\ninline std::set<T> operator+(std::set<T> const &_a, std::set<T> const &_b)\n{\n    std::set<T> ret(_a);\n    return ret += _b;\n}\n\ntemplate <class A, class B>\nstd::unordered_map<A, B> &operator+=(std::unordered_map<A, B> &_x, std::unordered_map<A, B> const &_y)\n{\n    for (auto const &i : _y)\n        _x.insert(i);\n    return _x;\n}\n\ntemplate <class A, class B>\nstd::unordered_map<A, B> operator+(std::unordered_map<A, B> const &_x, std::unordered_map<A, B> const &_y)\n{\n    std::unordered_map<A, B> ret(_x);\n    return ret += _y;\n}\n\n/// Make normal string from fixed-length string.\nstd::string toString(string32 const &_s);\n\ntemplate <class T, class U>\nstd::vector<T> keysOf(std::map<T, U> const &_m)\n{\n    std::vector<T> ret;\n    for (auto const &i : _m)\n        ret.push_back(i.first);\n    return ret;\n}\n\ntemplate <class T, class U>\nstd::vector<T> keysOf(std::unordered_map<T, U> const &_m)\n{\n    std::vector<T> ret;\n    for (auto const &i : _m)\n        ret.push_back(i.first);\n    return ret;\n}\n\ntemplate <class T, class U>\nstd::vector<U> valuesOf(std::map<T, U> const &_m)\n{\n    std::vector<U> ret;\n    ret.reserve(_m.size());\n    for (auto const &i : _m)\n        ret.push_back(i.second);\n    return ret;\n}\n\ntemplate <class T, class U>\nstd::vector<U> valuesOf(std::unordered_map<T, U> const &_m)\n{\n    std::vector<U> ret;\n    ret.reserve(_m.size());\n    for (auto const &i : _m)\n        ret.push_back(i.second);\n    return ret;\n}\n\ntemplate <class T, class V>\nbool contains(T const &_t, V const &_v)\n{\n    return std::end(_t) != std::find(std::begin(_t), std::end(_t), _v);\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/consensus/libdevcore/CommonIO.h",
    "content": "/*\n    This file is part of cpp-ethereum.\n\n    cpp-ethereum is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    cpp-ethereum is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/** @file CommonIO.h\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n *\n * File & stream I/O routines.\n */\n\n#pragma once\n\n#include <map>\n#include <set>\n#include <unordered_map>\n#include <unordered_set>\n#include <array>\n#include <list>\n#include <memory>\n#include <vector>\n#include <array>\n#include <sstream>\n#include <string>\n#include <iostream>\n#include <chrono>\n#include \"Common.h\"\n#include \"Base64.h\"\n\nnamespace libbitcoin\n{\n\n/// Requests the user to enter a password on the console.\nstd::string getPassword(std::string const &_prompt);\n\n/// Retrieve and returns the contents of the given file.\n/// If the file doesn't exist or isn't readable, returns an empty container / bytes.\nbytes contents(std::string const &_file);\n/// Secure variation.\nbytesSec contentsSec(std::string const &_file);\n/// Retrieve and returns the contents of the given file as a std::string.\n/// If the file doesn't exist or isn't readable, returns an empty container / bytes.\nstd::string contentsString(std::string const &_file);\n/// Retrieve and returns the allocated contents of the given file; if @_dest is given, don't allocate, use it directly.\n/// If the file doesn't exist or isn't readable, returns bytesRef(). Don't forget to delete [] the returned value's data when finished.\nbytesRef contentsNew(std::string const &_file, bytesRef _dest = bytesRef());\n\n/// Write the given binary data into the given file, replacing the file if it pre-exists.\n/// Throws exception on error.\n/// @param _writeDeleteRename useful not to lose any data: If set, first writes to another file in\n/// the same directory and then moves that file.\nvoid writeFile(std::string const &_file, bytesConstRef _data, bool _writeDeleteRename = false);\n/// Write the given binary data into the given file, replacing the file if it pre-exists.\ninline void writeFile(std::string const &_file, bytes const &_data, bool _writeDeleteRename = false) { writeFile(_file, bytesConstRef(&_data), _writeDeleteRename); }\ninline void writeFile(std::string const &_file, std::string const &_data, bool _writeDeleteRename = false) { writeFile(_file, bytesConstRef(_data), _writeDeleteRename); }\n\n/// Nicely renders the given bytes to a string, optionally as HTML.\n/// @a _bytes: bytes array to be rendered as string. @a _width of a bytes line.\nstd::string memDump(bytes const &_bytes, unsigned _width = 8, bool _html = false);\n\n// Stream I/O functions.\n// Provides templated stream I/O for all STL collections so they can be shifted on to any iostream-like interface.\n\ntemplate <class S, class T>\nstruct StreamOut\n{\n    static S &bypass(S &_out, T const &_t)\n    {\n        _out << _t;\n        return _out;\n    }\n};\ntemplate <class S>\nstruct StreamOut<S, uint8_t>\n{\n    static S &bypass(S &_out, uint8_t const &_t)\n    {\n        _out << (int)_t;\n        return _out;\n    }\n};\n\ntemplate <class T>\ninline std::ostream &operator<<(std::ostream &_out, std::vector<T> const &_e);\ntemplate <class T, std::size_t Z>\ninline std::ostream &operator<<(std::ostream &_out, std::array<T, Z> const &_e);\ntemplate <class T, class U>\ninline std::ostream &operator<<(std::ostream &_out, std::pair<T, U> const &_e);\ntemplate <class T>\ninline std::ostream &operator<<(std::ostream &_out, std::list<T> const &_e);\ntemplate <class T1, class T2, class T3>\ninline std::ostream &operator<<(std::ostream &_out, std::tuple<T1, T2, T3> const &_e);\ntemplate <class T, class U>\ninline std::ostream &operator<<(std::ostream &_out, std::map<T, U> const &_e);\ntemplate <class T, class U>\ninline std::ostream &operator<<(std::ostream &_out, std::unordered_map<T, U> const &_e);\ntemplate <class T, class U>\ninline std::ostream &operator<<(std::ostream &_out, std::set<T, U> const &_e);\ntemplate <class T, class U>\ninline std::ostream &operator<<(std::ostream &_out, std::unordered_set<T, U> const &_e);\ntemplate <class T, class U>\ninline std::ostream &operator<<(std::ostream &_out, std::multimap<T, U> const &_e);\ntemplate <class _S, class _T>\n_S &operator<<(_S &_out, std::shared_ptr<_T> const &_p);\n\n#if defined(_WIN32)\ntemplate <class T>\ninline std::string toString(std::chrono::time_point<T> const &_e, std::string _format = \"%Y-%m-%d %H:%M:%S\")\n#else\ntemplate <class T>\ninline std::string toString(std::chrono::time_point<T> const &_e, std::string _format = \"%F %T\")\n#endif\n{\n    unsigned long milliSecondsSinceEpoch = std::chrono::duration_cast<std::chrono::milliseconds>(_e.time_since_epoch()).count();\n    auto const durationSinceEpoch = std::chrono::milliseconds(milliSecondsSinceEpoch);\n    std::chrono::time_point<std::chrono::system_clock> const tpAfterDuration(durationSinceEpoch);\n\n    tm timeValue;\n    auto time = std::chrono::system_clock::to_time_t(tpAfterDuration);\n#if defined(_WIN32)\n    gmtime_s(&timeValue, &time);\n#else\n    gmtime_r(&time, &timeValue);\n#endif\n\n    unsigned const millisRemainder = milliSecondsSinceEpoch % 1000;\n    char buffer[1024];\n    if (strftime(buffer, sizeof(buffer), _format.c_str(), &timeValue))\n        return std::string(buffer) + \".\" + (millisRemainder < 1 ? \"000\" : millisRemainder < 10 ? \"00\" : millisRemainder < 100 ? \"0\" : \"\") + std::to_string(millisRemainder) + \"Z\";\n    return std::string();\n}\n\ntemplate <class S, class T>\ninline S &streamout(S &_out, std::vector<T> const &_e)\n{\n    _out << \"[\";\n    if (!_e.empty())\n    {\n        StreamOut<S, T>::bypass(_out, _e.front());\n        for (auto i = ++_e.begin(); i != _e.end(); ++i)\n            StreamOut<S, T>::bypass(_out << \",\", *i);\n    }\n    _out << \"]\";\n    return _out;\n}\n\ntemplate <class T>\ninline std::ostream &operator<<(std::ostream &_out, std::vector<T> const &_e)\n{\n    streamout(_out, _e);\n    return _out;\n}\n\ntemplate <class S, class T, std::size_t Z>\ninline S &streamout(S &_out, std::array<T, Z> const &_e)\n{\n    _out << \"[\";\n    if (!_e.empty())\n    {\n        StreamOut<S, T>::bypass(_out, _e.front());\n        auto i = _e.begin();\n        for (++i; i != _e.end(); ++i)\n            StreamOut<S, T>::bypass(_out << \",\", *i);\n    }\n    _out << \"]\";\n    return _out;\n}\ntemplate <class T, std::size_t Z>\ninline std::ostream &operator<<(std::ostream &_out, std::array<T, Z> const &_e)\n{\n    streamout(_out, _e);\n    return _out;\n}\n\ntemplate <class S, class T>\ninline S &streamout(S &_out, std::list<T> const &_e)\n{\n    _out << \"[\";\n    if (!_e.empty())\n    {\n        _out << _e.front();\n        for (auto i = ++_e.begin(); i != _e.end(); ++i)\n            _out << \",\" << *i;\n    }\n    _out << \"]\";\n    return _out;\n}\ntemplate <class T>\ninline std::ostream &operator<<(std::ostream &_out, std::list<T> const &_e)\n{\n    streamout(_out, _e);\n    return _out;\n}\n\ntemplate <class S, class T, class U>\ninline S &streamout(S &_out, std::pair<T, U> const &_e)\n{\n    _out << \"(\" << _e.first << \",\" << _e.second << \")\";\n    return _out;\n}\ntemplate <class T, class U>\ninline std::ostream &operator<<(std::ostream &_out, std::pair<T, U> const &_e)\n{\n    streamout(_out, _e);\n    return _out;\n}\n\ntemplate <class S, class T1, class T2, class T3>\ninline S &streamout(S &_out, std::tuple<T1, T2, T3> const &_t)\n{\n    _out << \"(\" << std::get<0>(_t) << \",\" << std::get<1>(_t) << \",\" << std::get<2>(_t) << \")\";\n    return _out;\n}\ntemplate <class T1, class T2, class T3>\ninline std::ostream &operator<<(std::ostream &_out, std::tuple<T1, T2, T3> const &_e)\n{\n    streamout(_out, _e);\n    return _out;\n}\n\ntemplate <class S, class T, class U>\nS &streamout(S &_out, std::map<T, U> const &_v)\n{\n    if (_v.empty())\n        return _out << \"{}\";\n    int i = 0;\n    for (auto p : _v)\n        _out << (!(i++) ? \"{ \" : \"; \") << p.first << \" => \" << p.second;\n    return _out << \" }\";\n}\ntemplate <class T, class U>\ninline std::ostream &operator<<(std::ostream &_out, std::map<T, U> const &_e)\n{\n    streamout(_out, _e);\n    return _out;\n}\n\ntemplate <class S, class T, class U>\nS &streamout(S &_out, std::unordered_map<T, U> const &_v)\n{\n    if (_v.empty())\n        return _out << \"{}\";\n    int i = 0;\n    for (auto p : _v)\n        _out << (!(i++) ? \"{ \" : \"; \") << p.first << \" => \" << p.second;\n    return _out << \" }\";\n}\ntemplate <class T, class U>\ninline std::ostream &operator<<(std::ostream &_out, std::unordered_map<T, U> const &_e)\n{\n    streamout(_out, _e);\n    return _out;\n}\n\ntemplate <class S, class T>\nS &streamout(S &_out, std::set<T> const &_v)\n{\n    if (_v.empty())\n        return _out << \"{}\";\n    int i = 0;\n    for (auto p : _v)\n        _out << (!(i++) ? \"{ \" : \", \") << p;\n    return _out << \" }\";\n}\ntemplate <class T>\ninline std::ostream &operator<<(std::ostream &_out, std::set<T> const &_e)\n{\n    streamout(_out, _e);\n    return _out;\n}\n\ntemplate <class S, class T>\nS &streamout(S &_out, std::unordered_set<T> const &_v)\n{\n    if (_v.empty())\n        return _out << \"{}\";\n    int i = 0;\n    for (auto p : _v)\n        _out << (!(i++) ? \"{ \" : \", \") << p;\n    return _out << \" }\";\n}\ntemplate <class T>\ninline std::ostream &operator<<(std::ostream &_out, std::unordered_set<T> const &_e)\n{\n    streamout(_out, _e);\n    return _out;\n}\n\ntemplate <class S, class T>\nS &streamout(S &_out, std::multiset<T> const &_v)\n{\n    if (_v.empty())\n        return _out << \"{}\";\n    int i = 0;\n    for (auto p : _v)\n        _out << (!(i++) ? \"{ \" : \", \") << p;\n    return _out << \" }\";\n}\ntemplate <class T>\ninline std::ostream &operator<<(std::ostream &_out, std::multiset<T> const &_e)\n{\n    streamout(_out, _e);\n    return _out;\n}\n\ntemplate <class S, class T, class U>\nS &streamout(S &_out, std::multimap<T, U> const &_v)\n{\n    if (_v.empty())\n        return _out << \"{}\";\n    T l;\n    int i = 0;\n    for (auto p : _v)\n        if (!(i++))\n            _out << \"{ \" << (l = p.first) << \" => \" << p.second;\n        else if (l == p.first)\n            _out << \", \" << p.second;\n        else\n            _out << \"; \" << (l = p.first) << \" => \" << p.second;\n    return _out << \" }\";\n}\ntemplate <class T, class U>\ninline std::ostream &operator<<(std::ostream &_out, std::multimap<T, U> const &_e)\n{\n    streamout(_out, _e);\n    return _out;\n}\n\ntemplate <class _S, class _T>\n_S &operator<<(_S &_out, std::shared_ptr<_T> const &_p)\n{\n    if (_p)\n        _out << \"@\" << (*_p);\n    else\n        _out << \"nullptr\";\n    return _out;\n}\n\n// Functions that use streaming stuff.\n\n/// Converts arbitrary value to string representation using std::stringstream.\ntemplate <class _T>\nstd::string toString(_T const &_t)\n{\n    std::ostringstream o;\n    o << _t;\n    return o.str();\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/consensus/libdevcore/Exceptions.h",
    "content": "/*\n    This file is part of cpp-ethereum.\n\n    cpp-ethereum is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    cpp-ethereum is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/** @file Exceptions.h\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n */\n\n#pragma once\n\n#include <exception>\n#include <string>\n#include <boost/exception/exception.hpp>\n#include <boost/exception/info.hpp>\n#include <boost/exception/info_tuple.hpp>\n#include <boost/exception/diagnostic_information.hpp>\n#include <boost/throw_exception.hpp>\n#include <boost/tuple/tuple.hpp>\n#include \"CommonData.h\"\n#include \"FixedHash.h\"\n\nnamespace libbitcoin\n{\n\n/// Base class for all exceptions.\nstruct Exception : virtual std::exception, virtual boost::exception\n{\n    Exception(std::string _message = std::string()) : m_message(std::move(_message)) {}\n    const char *what() const noexcept override { return m_message.empty() ? std::exception::what() : m_message.c_str(); }\n\n  private:\n    std::string m_message;\n};\n\n#define DEV_SIMPLE_EXCEPTION(X)                                   \\\n    struct X : virtual Exception                                  \\\n    {                                                             \\\n        const char *what() const noexcept override { return #X; } \\\n    }\n\n/// Base class for all RLP exceptions.\nstruct RLPException : virtual Exception\n{\n    RLPException(std::string _message = std::string()) : Exception(_message) {}\n};\n#define DEV_SIMPLE_EXCEPTION_RLP(X)                               \\\n    struct X : virtual RLPException                               \\\n    {                                                             \\\n        const char *what() const noexcept override { return #X; } \\\n    }\n\nDEV_SIMPLE_EXCEPTION_RLP(BadCast);\nDEV_SIMPLE_EXCEPTION_RLP(BadRLP);\nDEV_SIMPLE_EXCEPTION_RLP(OversizeRLP);\nDEV_SIMPLE_EXCEPTION_RLP(UndersizeRLP);\n\nDEV_SIMPLE_EXCEPTION(BadHexCharacter);\nDEV_SIMPLE_EXCEPTION(NoNetworking);\nDEV_SIMPLE_EXCEPTION(NoUPnPDevice);\nDEV_SIMPLE_EXCEPTION(RootNotFound);\nstruct BadRoot : virtual Exception\n{\n  public:\n    BadRoot(h256 const &_root) : Exception(\"BadRoot \" + _root.hex()), root(_root) {}\n    h256 root;\n};\nDEV_SIMPLE_EXCEPTION(FileError);\nDEV_SIMPLE_EXCEPTION(Overflow);\nDEV_SIMPLE_EXCEPTION(FailedInvariant);\nDEV_SIMPLE_EXCEPTION(ValueTooLarge);\n\nstruct InterfaceNotSupported : virtual Exception\n{\n  public:\n    InterfaceNotSupported(std::string _f) : Exception(\"Interface \" + _f + \" not supported.\") {}\n};\nstruct ExternalFunctionFailure : virtual Exception\n{\n  public:\n    ExternalFunctionFailure(std::string _f) : Exception(\"Function \" + _f + \"() failed.\") {}\n};\n\n// error information to be added to exceptions\nusing errinfo_invalidSymbol = boost::error_info<struct tag_invalidSymbol, char>;\nusing errinfo_wrongAddress = boost::error_info<struct tag_address, std::string>;\nusing errinfo_comment = boost::error_info<struct tag_comment, std::string>;\nusing errinfo_required = boost::error_info<struct tag_required, bigint>;\nusing errinfo_got = boost::error_info<struct tag_got, bigint>;\nusing errinfo_min = boost::error_info<struct tag_min, bigint>;\nusing errinfo_max = boost::error_info<struct tag_max, bigint>;\nusing RequirementError = boost::tuple<errinfo_required, errinfo_got>;\nusing errinfo_hash256 = boost::error_info<struct tag_hash, h256>;\nusing errinfo_required_h256 = boost::error_info<struct tag_required_h256, h256>;\nusing errinfo_got_h256 = boost::error_info<struct tag_get_h256, h256>;\nusing Hash256RequirementError = boost::tuple<errinfo_required_h256, errinfo_got_h256>;\nusing errinfo_extraData = boost::error_info<struct tag_extraData, bytes>;\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/consensus/libdevcore/FixedHash.h",
    "content": "/*\n    This file is part of cpp-ethereum.\n\n    cpp-ethereum is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    cpp-ethereum is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/** @file FixedHash.h\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n *\n * The FixedHash fixed-size \"hash\" container type.\n */\n\n#pragma once\n\n#include <array>\n#include <cstdint>\n#include <algorithm>\n#include <chrono>\n#include <cstdint>\n#include <stdexcept>\n#ifdef __MINGW32__\n#include <boost/random/random_device.hpp>\n#else\n#include <random>\n#endif\n#include <boost/random/uniform_int_distribution.hpp>\n#include <boost/functional/hash.hpp>\n#include \"CommonData.h\"\nnamespace libbitcoin\n{\n\n/// Compile-time calculation of Log2 of constant values.\ntemplate <unsigned N>\nstruct StaticLog2\n{\n    enum\n    {\n        result = 1 + StaticLog2<N / 2>::result\n    };\n};\ntemplate <>\nstruct StaticLog2<1>\n{\n    enum\n    {\n        result = 0\n    };\n};\n#ifdef __MINGW32__\nextern boost::random_device s_fixedHashEngine;\n#else\nextern std::random_device s_fixedHashEngine;\n#endif\n\n/// Fixed-size raw-byte array container type, with an API optimised for storing hashes.\n/// Transparently converts to/from the corresponding arithmetic type; this will\n/// assume the data contained in the hash is big-endian.\ntemplate <unsigned N>\nclass FixedHash\n{\n  public:\n    /// The corresponding arithmetic type.\n    using Arith = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<N * 8, N * 8, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;\n\n    /// The size of the container.\n    enum\n    {\n        size = N\n    };\n\n    /// A dummy flag to avoid accidental construction from pointer.\n    enum ConstructFromPointerType\n    {\n        ConstructFromPointer\n    };\n\n    /// Method to convert from a string.\n    enum ConstructFromStringType\n    {\n        FromHex,\n        FromBinary\n    };\n\n    /// Method to convert from a string.\n    enum ConstructFromHashType\n    {\n        AlignLeft,\n        AlignRight,\n        FailIfDifferent\n    };\n\n    /// Construct an empty hash.\n    FixedHash() { m_data.fill(0); }\n\n    /// Construct from another hash, filling with zeroes or cropping as necessary.\n    template <unsigned M>\n    explicit FixedHash(FixedHash<M> const &_h, ConstructFromHashType _t = AlignLeft)\n    {\n        m_data.fill(0);\n        unsigned c = std::min(M, N);\n        for (unsigned i = 0; i < c; ++i)\n            m_data[_t == AlignRight ? N - 1 - i : i] = _h[_t == AlignRight ? M - 1 - i : i];\n    }\n\n    /// Convert from the corresponding arithmetic type.\n    FixedHash(Arith const &_arith) { toBigEndian(_arith, m_data); }\n\n    /// Convert from unsigned\n    explicit FixedHash(unsigned _u) { toBigEndian(_u, m_data); }\n\n    /// Explicitly construct, copying from a byte array.\n    explicit FixedHash(bytes const &_b, ConstructFromHashType _t = FailIfDifferent)\n    {\n        if (_b.size() == N)\n            memcpy(m_data.data(), _b.data(), std::min<unsigned>(_b.size(), N));\n        else\n        {\n            m_data.fill(0);\n            if (_t != FailIfDifferent)\n            {\n                auto c = std::min<unsigned>(_b.size(), N);\n                for (unsigned i = 0; i < c; ++i)\n                    m_data[_t == AlignRight ? N - 1 - i : i] = _b[_t == AlignRight ? _b.size() - 1 - i : i];\n            }\n        }\n    }\n\n    /// Explicitly construct, copying from a byte array.\n    explicit FixedHash(bytesConstRef _b, ConstructFromHashType _t = FailIfDifferent)\n    {\n        if (_b.size() == N)\n            memcpy(m_data.data(), _b.data(), std::min<unsigned>(_b.size(), N));\n        else\n        {\n            m_data.fill(0);\n            if (_t != FailIfDifferent)\n            {\n                auto c = std::min<unsigned>(_b.size(), N);\n                for (unsigned i = 0; i < c; ++i)\n                    m_data[_t == AlignRight ? N - 1 - i : i] = _b[_t == AlignRight ? _b.size() - 1 - i : i];\n            }\n        }\n    }\n\n    /// Explicitly construct, copying from a bytes in memory with given pointer.\n    explicit FixedHash(byte const *_bs, ConstructFromPointerType) { memcpy(m_data.data(), _bs, N); }\n\n    /// Explicitly construct, copying from a  string.\n    explicit FixedHash(std::string const &_s, ConstructFromStringType _t = FromHex, ConstructFromHashType _ht = FailIfDifferent) : FixedHash(_t == FromHex ? fromHex(_s, WhenError::Throw) : libbitcoin::asBytes(_s), _ht) {}\n\n    /// Convert to arithmetic type.\n    operator Arith() const { return fromBigEndian<Arith>(m_data); }\n\n    /// @returns true iff this is the empty hash.\n    explicit operator bool() const\n    {\n        return std::any_of(m_data.begin(), m_data.end(), [](byte _b) { return _b != 0; });\n    }\n\n    // The obvious comparison operators.\n    bool operator==(FixedHash const &_c) const { return m_data == _c.m_data; }\n    bool operator!=(FixedHash const &_c) const { return m_data != _c.m_data; }\n    bool operator<(FixedHash const &_c) const\n    {\n        for (unsigned i = 0; i < N; ++i)\n            if (m_data[i] < _c.m_data[i])\n                return true;\n            else if (m_data[i] > _c.m_data[i])\n                return false;\n        return false;\n    }\n    bool operator>=(FixedHash const &_c) const { return !operator<(_c); }\n    bool operator<=(FixedHash const &_c) const { return operator==(_c) || operator<(_c); }\n    bool operator>(FixedHash const &_c) const { return !operator<=(_c); }\n\n    // The obvious binary operators.\n    FixedHash &operator^=(FixedHash const &_c)\n    {\n        for (unsigned i = 0; i < N; ++i)\n            m_data[i] ^= _c.m_data[i];\n        return *this;\n    }\n    FixedHash operator^(FixedHash const &_c) const { return FixedHash(*this) ^= _c; }\n    FixedHash &operator|=(FixedHash const &_c)\n    {\n        for (unsigned i = 0; i < N; ++i)\n            m_data[i] |= _c.m_data[i];\n        return *this;\n    }\n    FixedHash operator|(FixedHash const &_c) const { return FixedHash(*this) |= _c; }\n    FixedHash &operator&=(FixedHash const &_c)\n    {\n        for (unsigned i = 0; i < N; ++i)\n            m_data[i] &= _c.m_data[i];\n        return *this;\n    }\n    FixedHash operator&(FixedHash const &_c) const { return FixedHash(*this) &= _c; }\n    FixedHash operator~() const\n    {\n        FixedHash ret;\n        for (unsigned i = 0; i < N; ++i)\n            ret[i] = ~m_data[i];\n        return ret;\n    }\n\n    // Big-endian increment.\n    FixedHash &operator++()\n    {\n        for (unsigned i = size; i > 0 && !++m_data[--i];)\n        {\n        }\n        return *this;\n    }\n\n    /// @returns true if all one-bits in @a _c are set in this object.\n    bool contains(FixedHash const &_c) const { return (*this & _c) == _c; }\n\n    /// @returns a particular byte from the hash.\n    byte &operator[](unsigned _i) { return m_data[_i]; }\n    /// @returns a particular byte from the hash.\n    byte operator[](unsigned _i) const { return m_data[_i]; }\n\n    /// @returns an abridged version of the hash as a user-readable hex string.\n    std::string abridged() const { return toHex(ref().cropped(0, 4)) + \"\\342\\200\\246\"; }\n\n    /// @returns a version of the hash as a user-readable hex string that leaves out the middle part.\n    std::string abridgedMiddle() const { return toHex(ref().cropped(0, 4)) + \"\\342\\200\\246\" + toHex(ref().cropped(N - 4)); }\n\n    /// @returns the hash as a user-readable hex string.\n    std::string hex() const { return toHex(ref()); }\n\n    /// @returns a mutable byte vector_ref to the object's data.\n    bytesRef ref() { return bytesRef(m_data.data(), N); }\n\n    /// @returns a constant byte vector_ref to the object's data.\n    bytesConstRef ref() const { return bytesConstRef(m_data.data(), N); }\n\n    /// @returns a mutable byte pointer to the object's data.\n    byte *data() { return m_data.data(); }\n\n    /// @returns a constant byte pointer to the object's data.\n    byte const *data() const { return m_data.data(); }\n\n    /// @returns a copy of the object's data as a byte vector.\n    bytes asBytes() const { return bytes(data(), data() + N); }\n\n    /// @returns a mutable reference to the object's data as an STL array.\n    std::array<byte, N> &asArray() { return m_data; }\n\n    /// @returns a constant reference to the object's data as an STL array.\n    std::array<byte, N> const &asArray() const { return m_data; }\n\n    /// Populate with random data.\n    template <class Engine>\n    void randomize(Engine &_eng)\n    {\n        for (auto &i : m_data)\n            i = (uint8_t)boost::random::uniform_int_distribution<uint16_t>(0, 255)(_eng);\n    }\n\n    /// @returns a random valued object.\n    static FixedHash random()\n    {\n        FixedHash ret;\n        ret.randomize(s_fixedHashEngine);\n        return ret;\n    }\n\n    struct hash\n    {\n        /// Make a hash of the object's data.\n        size_t operator()(FixedHash const &_value) const { return libbitcoin::hash_range(_value.m_data.cbegin(), _value.m_data.cend()); }\n    };\n\n    template <unsigned P, unsigned M>\n    inline FixedHash &shiftBloom(FixedHash<M> const &_h)\n    {\n        return (*this |= _h.template bloomPart<P, N>());\n    }\n\n    template <unsigned P, unsigned M>\n    inline bool containsBloom(FixedHash<M> const &_h)\n    {\n        return contains(_h.template bloomPart<P, N>());\n    }\n\n    template <unsigned P, unsigned M>\n    inline FixedHash<M> bloomPart() const\n    {\n        unsigned const c_bloomBits = M * 8;\n        unsigned const c_mask = c_bloomBits - 1;\n        unsigned const c_bloomBytes = (StaticLog2<c_bloomBits>::result + 7) / 8;\n\n        static_assert((M & (M - 1)) == 0, \"M must be power-of-two\");\n        static_assert(P * c_bloomBytes <= N, \"out of range\");\n\n        FixedHash<M> ret;\n        byte const *p = data();\n        for (unsigned i = 0; i < P; ++i)\n        {\n            unsigned index = 0;\n            for (unsigned j = 0; j < c_bloomBytes; ++j, ++p)\n                index = (index << 8) | *p;\n            index &= c_mask;\n            ret[M - 1 - index / 8] |= (1 << (index % 8));\n        }\n        return ret;\n    }\n\n    /// Returns the index of the first bit set to one, or size() * 8 if no bits are set.\n    inline unsigned firstBitSet() const\n    {\n        unsigned ret = 0;\n        for (auto d : m_data)\n            if (d)\n                for (;; ++ret, d <<= 1)\n                    if (d & 0x80)\n                        return ret;\n                    else\n                    {\n                    }\n            else\n                ret += 8;\n        return ret;\n    }\n\n    void clear() { m_data.fill(0); }\n\n  private:\n    std::array<byte, N> m_data; ///< The binary data.\n};\n\ntemplate <unsigned T>\nclass SecureFixedHash : private FixedHash<T>\n{\n  public:\n    using ConstructFromHashType = typename FixedHash<T>::ConstructFromHashType;\n    using ConstructFromStringType = typename FixedHash<T>::ConstructFromStringType;\n    using ConstructFromPointerType = typename FixedHash<T>::ConstructFromPointerType;\n    SecureFixedHash() = default;\n    explicit SecureFixedHash(bytes const &_b, ConstructFromHashType _t = FixedHash<T>::FailIfDifferent) : FixedHash<T>(_b, _t) {}\n    explicit SecureFixedHash(bytesConstRef _b, ConstructFromHashType _t = FixedHash<T>::FailIfDifferent) : FixedHash<T>(_b, _t) {}\n    explicit SecureFixedHash(bytesSec const &_b, ConstructFromHashType _t = FixedHash<T>::FailIfDifferent) : FixedHash<T>(_b.ref(), _t) {}\n    template <unsigned M>\n    explicit SecureFixedHash(FixedHash<M> const &_h, ConstructFromHashType _t = FixedHash<T>::AlignLeft) : FixedHash<T>(_h, _t) {}\n    template <unsigned M>\n    explicit SecureFixedHash(SecureFixedHash<M> const &_h, ConstructFromHashType _t = FixedHash<T>::AlignLeft) : FixedHash<T>(_h.makeInsecure(), _t) {}\n    explicit SecureFixedHash(std::string const &_s, ConstructFromStringType _t = FixedHash<T>::FromHex, ConstructFromHashType _ht = FixedHash<T>::FailIfDifferent) : FixedHash<T>(_s, _t, _ht) {}\n    explicit SecureFixedHash(bytes const *_d, ConstructFromPointerType _t) : FixedHash<T>(_d, _t) {}\n    ~SecureFixedHash() { ref().cleanse(); }\n\n    SecureFixedHash<T> &operator=(SecureFixedHash<T> const &_c)\n    {\n        if (&_c == this)\n            return *this;\n        ref().cleanse();\n        FixedHash<T>::operator=(static_cast<FixedHash<T> const &>(_c));\n        return *this;\n    }\n\n    using FixedHash<T>::size;\n\n    bytesSec asBytesSec() const { return bytesSec(ref()); }\n\n    FixedHash<T> const &makeInsecure() const { return static_cast<FixedHash<T> const &>(*this); }\n    FixedHash<T> &writable()\n    {\n        clear();\n        return static_cast<FixedHash<T> &>(*this);\n    }\n\n    using FixedHash<T>::operator bool;\n\n    // The obvious comparison operators.\n    bool operator==(SecureFixedHash const &_c) const { return static_cast<FixedHash<T> const &>(*this).operator==(static_cast<FixedHash<T> const &>(_c)); }\n    bool operator!=(SecureFixedHash const &_c) const { return static_cast<FixedHash<T> const &>(*this).operator!=(static_cast<FixedHash<T> const &>(_c)); }\n    bool operator<(SecureFixedHash const &_c) const { return static_cast<FixedHash<T> const &>(*this).operator<(static_cast<FixedHash<T> const &>(_c)); }\n    bool operator>=(SecureFixedHash const &_c) const { return static_cast<FixedHash<T> const &>(*this).operator>=(static_cast<FixedHash<T> const &>(_c)); }\n    bool operator<=(SecureFixedHash const &_c) const { return static_cast<FixedHash<T> const &>(*this).operator<=(static_cast<FixedHash<T> const &>(_c)); }\n    bool operator>(SecureFixedHash const &_c) const { return static_cast<FixedHash<T> const &>(*this).operator>(static_cast<FixedHash<T> const &>(_c)); }\n\n    using FixedHash<T>::operator==;\n    using FixedHash<T>::operator!=;\n    using FixedHash<T>::operator<;\n    using FixedHash<T>::operator>=;\n    using FixedHash<T>::operator<=;\n    using FixedHash<T>::operator>;\n\n    // The obvious binary operators.\n    SecureFixedHash &operator^=(FixedHash<T> const &_c)\n    {\n        static_cast<FixedHash<T> &>(*this).operator^=(_c);\n        return *this;\n    }\n    SecureFixedHash operator^(FixedHash<T> const &_c) const { return SecureFixedHash(*this) ^= _c; }\n    SecureFixedHash &operator|=(FixedHash<T> const &_c)\n    {\n        static_cast<FixedHash<T> &>(*this).operator^=(_c);\n        return *this;\n    }\n    SecureFixedHash operator|(FixedHash<T> const &_c) const { return SecureFixedHash(*this) |= _c; }\n    SecureFixedHash &operator&=(FixedHash<T> const &_c)\n    {\n        static_cast<FixedHash<T> &>(*this).operator^=(_c);\n        return *this;\n    }\n    SecureFixedHash operator&(FixedHash<T> const &_c) const { return SecureFixedHash(*this) &= _c; }\n\n    SecureFixedHash &operator^=(SecureFixedHash const &_c)\n    {\n        static_cast<FixedHash<T> &>(*this).operator^=(static_cast<FixedHash<T> const &>(_c));\n        return *this;\n    }\n    SecureFixedHash operator^(SecureFixedHash const &_c) const { return SecureFixedHash(*this) ^= _c; }\n    SecureFixedHash &operator|=(SecureFixedHash const &_c)\n    {\n        static_cast<FixedHash<T> &>(*this).operator^=(static_cast<FixedHash<T> const &>(_c));\n        return *this;\n    }\n    SecureFixedHash operator|(SecureFixedHash const &_c) const { return SecureFixedHash(*this) |= _c; }\n    SecureFixedHash &operator&=(SecureFixedHash const &_c)\n    {\n        static_cast<FixedHash<T> &>(*this).operator^=(static_cast<FixedHash<T> const &>(_c));\n        return *this;\n    }\n    SecureFixedHash operator&(SecureFixedHash const &_c) const { return SecureFixedHash(*this) &= _c; }\n    SecureFixedHash operator~() const\n    {\n        auto r = ~static_cast<FixedHash<T> const &>(*this);\n        return static_cast<SecureFixedHash const &>(r);\n    }\n\n    using FixedHash<T>::abridged;\n    using FixedHash<T>::abridgedMiddle;\n\n    bytesConstRef ref() const { return FixedHash<T>::ref(); }\n    byte const *data() const { return FixedHash<T>::data(); }\n    // #ifdef __MINGW32__\n    // std::default_random_engine sm{)};\n    // static SecureFixedHash<T> random() { SecureFixedHash<T> ret; ret.randomize(sm); return ret; }\n    // #else\n    static SecureFixedHash<T> random()\n    {\n        SecureFixedHash<T> ret;\n        ret.randomize(s_fixedHashEngine);\n        return ret;\n    }\n    //#endif\n    using FixedHash<T>::firstBitSet;\n\n    void clear() { ref().cleanse(); }\n};\n\n/// Fast equality operator for h256.\ntemplate <>\ninline bool FixedHash<32>::operator==(FixedHash<32> const &_other) const\n{\n    const uint64_t *hash1 = (const uint64_t *)data();\n    const uint64_t *hash2 = (const uint64_t *)_other.data();\n    return (hash1[0] == hash2[0]) && (hash1[1] == hash2[1]) && (hash1[2] == hash2[2]) && (hash1[3] == hash2[3]);\n}\n\n/// Fast std::hash compatible hash function object for h256.\ntemplate <>\ninline size_t FixedHash<32>::hash::operator()(FixedHash<32> const &value) const\n{\n    uint64_t const *data = reinterpret_cast<uint64_t const *>(value.data());\n    return libbitcoin::hash_range(data, data + 4);\n}\n\n/// Stream I/O for the FixedHash class.\ntemplate <unsigned N>\ninline std::ostream &operator<<(std::ostream &_out, FixedHash<N> const &_h)\n{\n    _out << std::noshowbase << std::hex << std::setfill('0');\n    for (unsigned i = 0; i < N; ++i)\n        _out << std::setw(2) << (int)_h[i];\n    _out << std::dec;\n    return _out;\n}\n\n/// Stream I/O for the SecureFixedHash class.\ntemplate <unsigned N>\ninline std::ostream &operator<<(std::ostream &_out, SecureFixedHash<N> const &_h)\n{\n    _out << \"SecureFixedHash#\" << std::hex << typename FixedHash<N>::hash()(_h.makeInsecure()) << std::dec;\n    return _out;\n}\n\n// Common types of FixedHash.\nusing h2048 = FixedHash<256>;\nusing h1024 = FixedHash<128>;\nusing h520 = FixedHash<65>;\nusing h512 = FixedHash<64>;\nusing h256 = FixedHash<32>;\nusing h160 = FixedHash<20>;\nusing h128 = FixedHash<16>;\nusing h64 = FixedHash<8>;\nusing Nonce = h64;\nusing h512s = std::vector<h512>;\nusing h256s = std::vector<h256>;\nusing h160s = std::vector<h160>;\nusing h256Set = std::set<h256>;\nusing h160Set = std::set<h160>;\nusing h256Hash = std::unordered_set<h256>;\nusing h160Hash = std::unordered_set<h160>;\nusing Secret = SecureFixedHash<32>;\n\n/// Convert the given value into h160 (160-bit unsigned integer) using the right 20 bytes.\ninline h160 right160(h256 const &_t)\n{\n    h160 ret;\n    memcpy(ret.data(), _t.data() + 12, 20);\n    return ret;\n}\n\n/// Convert the given value into h160 (160-bit unsigned integer) using the left 20 bytes.\ninline h160 left160(h256 const &_t)\n{\n    h160 ret;\n    memcpy(&ret[0], _t.data(), 20);\n    return ret;\n}\n\nh128 fromUUID(std::string const &_uuid);\n\nstd::string toUUID(h128 const &_uuid);\n\ninline std::string toString(h256s const &_bs)\n{\n    std::ostringstream out;\n    out << \"[ \";\n    for (auto i : _bs)\n        out << i.abridged() << \", \";\n    out << \"]\";\n    return out.str();\n}\n\n} // namespace libbitcoin\n\nnamespace std\n{\n/// Forward std::hash<dev::FixedHash> to dev::FixedHash::hash.\ntemplate <>\nstruct hash<libbitcoin::h64> : libbitcoin::h64::hash\n{\n};\ntemplate <>\nstruct hash<libbitcoin::h128> : libbitcoin::h128::hash\n{\n};\ntemplate <>\nstruct hash<libbitcoin::h160> : libbitcoin::h160::hash\n{\n};\ntemplate <>\nstruct hash<libbitcoin::h256> : libbitcoin::h256::hash\n{\n};\ntemplate <>\nstruct hash<libbitcoin::h512> : libbitcoin::h512::hash\n{\n};\n} // namespace std\n"
  },
  {
    "path": "include/UChainService/consensus/libdevcore/Guards.h",
    "content": "/*\n    This file is part of cpp-ethereum.\n\n    cpp-ethereum is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    cpp-ethereum is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/** @file Guards.h\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n */\n\n#pragma once\n\n#include <mutex>\n#include <condition_variable>\n#include <atomic>\n//#pragma warning(push)\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wunused-parameter\"\n#include <boost/thread.hpp>\n//#pragma warning(pop)\n#pragma GCC diagnostic pop\n\nnamespace libbitcoin\n{\n\nusing Mutex = std::mutex;\nusing RecursiveMutex = std::recursive_mutex;\nusing SharedMutex = boost::shared_mutex;\n\nusing Guard = std::lock_guard<std::mutex>;\nusing UniqueGuard = std::unique_lock<std::mutex>;\nusing RecursiveGuard = std::lock_guard<std::recursive_mutex>;\nusing ReadGuard = boost::shared_lock<boost::shared_mutex>;\nusing UpgradableGuard = boost::upgrade_lock<boost::shared_mutex>;\nusing UpgradeGuard = boost::upgrade_to_unique_lock<boost::shared_mutex>;\nusing WriteGuard = boost::unique_lock<boost::shared_mutex>;\n\ntemplate <class GuardType, class MutexType>\nstruct GenericGuardBool : GuardType\n{\n    GenericGuardBool(MutexType &_m) : GuardType(_m) {}\n    bool b = true;\n};\ntemplate <class MutexType>\nstruct GenericUnguardBool\n{\n    GenericUnguardBool(MutexType &_m) : m(_m) { m.unlock(); }\n    ~GenericUnguardBool() { m.lock(); }\n    bool b = true;\n    MutexType &m;\n};\ntemplate <class MutexType>\nstruct GenericUnguardSharedBool\n{\n    GenericUnguardSharedBool(MutexType &_m) : m(_m) { m.unlock_shared(); }\n    ~GenericUnguardSharedBool() { m.lock_shared(); }\n    bool b = true;\n    MutexType &m;\n};\n\n/** @brief Simple lock that waits for release without making context switch */\nclass SpinLock\n{\n  public:\n    SpinLock() { m_lock.clear(); }\n    void lock()\n    {\n        while (m_lock.test_and_set(std::memory_order_acquire))\n        {\n        }\n    }\n    void unlock() { m_lock.clear(std::memory_order_release); }\n\n  private:\n    std::atomic_flag m_lock;\n};\nusing SpinGuard = std::lock_guard<SpinLock>;\n\ntemplate <class N>\nclass Notified\n{\n  public:\n    Notified() {}\n    Notified(N const &_v) : m_value(_v) {}\n    Notified(Notified const &) = delete;\n    Notified &operator=(N const &_v)\n    {\n        UniqueGuard l(m_mutex);\n        m_value = _v;\n        m_cv.notify_all();\n        return *this;\n    }\n\n    operator N() const\n    {\n        UniqueGuard l(m_mutex);\n        return m_value;\n    }\n\n    void wait() const\n    {\n        N old;\n        {\n            UniqueGuard l(m_mutex);\n            old = m_value;\n        }\n        waitNot(old);\n    }\n    void wait(N const &_v) const\n    {\n        UniqueGuard l(m_mutex);\n        m_cv.wait(l, [&]() { return m_value == _v; });\n    }\n    void waitNot(N const &_v) const\n    {\n        UniqueGuard l(m_mutex);\n        m_cv.wait(l, [&]() { return m_value != _v; });\n    }\n    template <class F>\n    void wait(F const &_f) const\n    {\n        UniqueGuard l(m_mutex);\n        m_cv.wait(l, _f);\n    }\n\n    template <class R, class P>\n    void wait(std::chrono::duration<R, P> _d) const\n    {\n        N old;\n        {\n            UniqueGuard l(m_mutex);\n            old = m_value;\n        }\n        waitNot(_d, old);\n    }\n    template <class R, class P>\n    void wait(std::chrono::duration<R, P> _d, N const &_v) const\n    {\n        UniqueGuard l(m_mutex);\n        m_cv.wait_for(l, _d, [&]() { return m_value == _v; });\n    }\n    template <class R, class P>\n    void waitNot(std::chrono::duration<R, P> _d, N const &_v) const\n    {\n        UniqueGuard l(m_mutex);\n        m_cv.wait_for(l, _d, [&]() { return m_value != _v; });\n    }\n    template <class R, class P, class F>\n    void wait(std::chrono::duration<R, P> _d, F const &_f) const\n    {\n        UniqueGuard l(m_mutex);\n        m_cv.wait_for(l, _d, _f);\n    }\n\n  private:\n    mutable Mutex m_mutex;\n    mutable std::condition_variable m_cv;\n    N m_value;\n};\n\n/** @brief Simple block guard.\n * The expression/block following is guarded though the given mutex.\n * Usage:\n * @code\n * Mutex m;\n * unsigned d;\n * ...\n * ETH_(m) d = 1;\n * ...\n * ETH_(m) { for (auto d = 10; d > 0; --d) foo(d); d = 0; }\n * @endcode\n *\n * There are several variants of this basic mechanism for different Mutex types and Guards.\n *\n * There is also the UNGUARD variant which allows an unguarded expression/block to exist within a\n * guarded expression. eg:\n *\n * @code\n * Mutex m;\n * int d;\n * ...\n * ETH_GUARDED(m)\n * {\n *   for (auto d = 50; d > 25; --d)\n *     foo(d);\n *   ETH_UNGUARDED(m)\n *     bar();\n *   for (; d > 0; --d)\n *     foo(d);\n * }\n * @endcode\n */\n\n#define DEV_GUARDED(MUTEX) \\\n    for (GenericGuardBool<Guard, Mutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false)\n#define DEV_READ_GUARDED(MUTEX) \\\n    for (GenericGuardBool<ReadGuard, SharedMutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false)\n#define DEV_WRITE_GUARDED(MUTEX) \\\n    for (GenericGuardBool<WriteGuard, SharedMutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false)\n#define DEV_RECURSIVE_GUARDED(MUTEX) \\\n    for (GenericGuardBool<RecursiveGuard, RecursiveMutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false)\n#define DEV_UNGUARDED(MUTEX) \\\n    for (GenericUnguardBool<Mutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false)\n#define DEV_READ_UNGUARDED(MUTEX) \\\n    for (GenericUnguardSharedBool<SharedMutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false)\n#define DEV_WRITE_UNGUARDED(MUTEX) \\\n    for (GenericUnguardBool<SharedMutex> __eth_l(MUTEX); __eth_l.b; __eth_l.b = false)\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/consensus/libdevcore/Log.h",
    "content": "/*\n    This file is part of cpp-ethereum.\n\n    cpp-ethereum is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    cpp-ethereum is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/** @file Log.h\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n *\n * The logging subsystem.\n */\n\n#pragma once\n\n#include <ctime>\n#include <chrono>\n#include \"vector_ref.h\"\n#include \"Common.h\"\n#include \"CommonIO.h\"\n#include \"CommonData.h\"\n#include \"FixedHash.h\"\n#include \"Terminal.h\"\n\nnamespace boost\n{\nnamespace asio\n{\nnamespace ip\n{\ntemplate <class T>\nclass basic_endpoint;\nclass tcp;\n} // namespace ip\n} // namespace asio\n} // namespace boost\n\nnamespace libbitcoin\n{\n\n/// The null output stream. Used when logging is disabled.\nclass NullOutputStream\n{\n  public:\n    template <class T>\n    NullOutputStream &operator<<(T const &) { return *this; }\n};\n\n/// A simple log-output function that prints log messages to stdout.\nvoid simpleDebugOut(std::string const &, char const *);\n\n/// The logging system's current verbosity.\nextern int g_logVerbosity;\n\n/// The current method that the logging system uses to output the log messages. Defaults to simpleDebugOut().\nextern std::function<void(std::string const &, char const *)> g_logPost;\n\nclass LogOverrideAux\n{\n  protected:\n    LogOverrideAux(std::type_info const *_ch, bool _value);\n    ~LogOverrideAux();\n\n  private:\n    std::type_info const *m_ch;\n    static const int c_null = -1;\n    int m_old;\n};\n\ntemplate <class Channel>\nclass LogOverride : LogOverrideAux\n{\n  public:\n    LogOverride(bool _value) : LogOverrideAux(&typeid(Channel), _value) {}\n};\n\nbool isChannelVisible(std::type_info const *_ch, bool _default);\ntemplate <class Channel>\nbool isChannelVisible() { return isChannelVisible(&typeid(Channel), Channel::verbosity <= g_logVerbosity); }\n\n/// Temporary changes system's verbosity for specific function. Restores the old verbosity when function returns.\n/// Not thread-safe, use with caution!\nstruct VerbosityHolder\n{\n    VerbosityHolder(int _temporaryValue, bool _force = false) : oldLogVerbosity(g_logVerbosity)\n    {\n        if (g_logVerbosity >= 0 || _force)\n            g_logVerbosity = _temporaryValue;\n    }\n    ~VerbosityHolder() { g_logVerbosity = oldLogVerbosity; }\n    int oldLogVerbosity;\n};\n\n#define ETH_THREAD_CONTEXT(name) for (std::pair<libbitcoin::ThreadContext, bool> __eth_thread_context(name, true); p.second; p.second = false)\n\nclass ThreadContext\n{\n  public:\n    ThreadContext(std::string const &_info) { push(_info); }\n    ~ThreadContext() { pop(); }\n\n    static void push(std::string const &_n);\n    static void pop();\n    static std::string join(std::string const &_prior);\n};\n\n/// Set the current thread's log name.\n///\n/// It appears that there is not currently any cross-platform way of setting\n/// thread names either in Boost or in the C++11 runtime libraries.   What is\n/// more, the API for 'pthread_setname_np' is not even consistent across\n/// platforms which implement it.\n///\n/// A proposal to add such functionality on the Boost mailing list, which\n/// I assume never happened, but which I should follow-up and ask about.\n/// http://boost.2283326.n4.nabble.com/Adding-an-option-to-set-the-name-of-a-boost-thread-td4638283.html\n///\n/// man page for 'pthread_setname_np', including this crucial snippet of\n/// information ... \"These functions are nonstandard GNU extensions.\"\n/// http://man7.org/linux/man-pages/man3/pthread_setname_np.3.html\n///\n/// Stack Overflow \"Can I set the name of a thread in pthreads / linux?\"\n/// which includes useful information on the minor API differences between\n/// Linux, BSD and OS X.\n/// http://stackoverflow.com/questions/2369738/can-i-set-the-name-of-a-thread-in-pthreads-linux/7989973#7989973\n///\n/// musl mailng list posting \"pthread set name on MIPs\" which includes the\n/// information that musl doesn't currently implement 'pthread_setname_np'\n/// https://marc.info/?l=musl&m=146171729013062&w=1\nvoid setThreadName(std::string const &_n);\n\n/// Set the current thread's log name.\nstd::string getThreadName();\n\n/// The default logging channels. Each has an associated verbosity and three-letter prefix (name() ).\n/// Channels should inherit from LogChannel and define name() and verbosity.\nstruct LogChannel\n{\n    static const char *name();\n    static const int verbosity = 1;\n    static const bool debug = true;\n};\nstruct LeftChannel : public LogChannel\n{\n    static const char *name();\n};\nstruct RightChannel : public LogChannel\n{\n    static const char *name();\n};\nstruct WarnChannel : public LogChannel\n{\n    static const char *name();\n    static const int verbosity = 0;\n    static const bool debug = false;\n};\nstruct NoteChannel : public LogChannel\n{\n    static const char *name();\n    static const bool debug = false;\n};\nstruct DebugChannel : public LogChannel\n{\n    static const char *name();\n    static const int verbosity = 0;\n};\nstruct TraceChannel : public LogChannel\n{\n    static const char *name();\n    static const int verbosity = 4;\n    static const bool debug = true;\n};\n\nenum class LogTag\n{\n    None,\n    Url,\n    Error,\n    Special\n};\n\nclass LogOutputStreamBase\n{\n  public:\n    LogOutputStreamBase(char const *_id, std::type_info const *_info, unsigned _v, bool _autospacing);\n\n    void comment(std::string const &_t)\n    {\n        switch (m_logTag)\n        {\n        case LogTag::Url:\n            m_sstr << EthNavyUnder;\n            break;\n        case LogTag::Error:\n            m_sstr << EthRedBold;\n            break;\n        case LogTag::Special:\n            m_sstr << EthWhiteBold;\n            break;\n        default:;\n        }\n        m_sstr << _t << EthReset;\n        m_logTag = LogTag::None;\n    }\n\n    void append(unsigned long _t) { m_sstr << EthBlue << _t << EthReset; }\n    void append(long _t) { m_sstr << EthBlue << _t << EthReset; }\n    void append(unsigned int _t) { m_sstr << EthBlue << _t << EthReset; }\n    void append(int _t) { m_sstr << EthBlue << _t << EthReset; }\n    void append(bigint const &_t) { m_sstr << EthNavy << _t << EthReset; }\n    void append(u256 const &_t) { m_sstr << EthNavy << _t << EthReset; }\n    void append(u160 const &_t) { m_sstr << EthNavy << _t << EthReset; }\n    void append(double _t) { m_sstr << EthBlue << _t << EthReset; }\n    template <unsigned N>\n    void append(FixedHash<N> const &_t) { m_sstr << EthTeal \"#\" << _t.abridged() << EthReset; }\n    void append(h160 const &_t) { m_sstr << EthRed \"@\" << _t.abridged() << EthReset; }\n    void append(h256 const &_t) { m_sstr << EthCyan \"#\" << _t.abridged() << EthReset; }\n    void append(h512 const &_t) { m_sstr << EthTeal \"##\" << _t.abridged() << EthReset; }\n    void append(std::string const &_t) { m_sstr << EthGreen \"\\\"\" + _t + \"\\\"\" EthReset; }\n    void append(bytes const &_t) { m_sstr << EthYellow \"%\" << toHex(_t) << EthReset; }\n    void append(bytesConstRef _t) { m_sstr << EthYellow \"%\" << toHex(_t) << EthReset; }\n#if !defined(ETH_EMSCRIPTEN)\n    void append(boost::asio::ip::basic_endpoint<boost::asio::ip::tcp> const &_t);\n#endif\n    template <class T>\n    void append(std::vector<T> const &_t)\n    {\n        m_sstr << EthWhite \"[\" EthReset;\n        int n = 0;\n        for (auto const &i : _t)\n        {\n            m_sstr << (n++ ? EthWhite \", \" EthReset : \"\");\n            append(i);\n        }\n        m_sstr << EthWhite \"]\" EthReset;\n    }\n    template <class T>\n    void append(std::set<T> const &_t)\n    {\n        m_sstr << EthYellow \"{\" EthReset;\n        int n = 0;\n        for (auto const &i : _t)\n        {\n            m_sstr << (n++ ? EthYellow \", \" EthReset : \"\");\n            append(i);\n        }\n        m_sstr << EthYellow \"}\" EthReset;\n    }\n    template <class T, class U>\n    void append(std::map<T, U> const &_t)\n    {\n        m_sstr << EthLime \"{\" EthReset;\n        int n = 0;\n        for (auto const &i : _t)\n        {\n            m_sstr << (n++ ? EthLime \", \" EthReset : \"\");\n            append(i.first);\n            m_sstr << (n++ ? EthLime \": \" EthReset : \"\");\n            append(i.second);\n        }\n        m_sstr << EthLime \"}\" EthReset;\n    }\n    template <class T>\n    void append(std::unordered_set<T> const &_t)\n    {\n        m_sstr << EthYellow \"{\" EthReset;\n        int n = 0;\n        for (auto const &i : _t)\n        {\n            m_sstr << (n++ ? EthYellow \", \" EthReset : \"\");\n            append(i);\n        }\n        m_sstr << EthYellow \"}\" EthReset;\n    }\n    template <class T, class U>\n    void append(std::unordered_map<T, U> const &_t)\n    {\n        m_sstr << EthLime \"{\" EthReset;\n        int n = 0;\n        for (auto const &i : _t)\n        {\n            m_sstr << (n++ ? EthLime \", \" EthReset : \"\");\n            append(i.first);\n            m_sstr << (n++ ? EthLime \": \" EthReset : \"\");\n            append(i.second);\n        }\n        m_sstr << EthLime \"}\" EthReset;\n    }\n    template <class T, class U>\n    void append(std::pair<T, U> const &_t)\n    {\n        m_sstr << EthPurple \"(\" EthReset;\n        append(_t.first);\n        m_sstr << EthPurple \", \" EthReset;\n        append(_t.second);\n        m_sstr << EthPurple \")\" EthReset;\n    }\n    template <class T>\n    void append(T const &_t)\n    {\n        m_sstr << toString(_t);\n    }\n\n  protected:\n    bool m_autospacing = false;\n    unsigned m_verbosity = 0;\n    std::stringstream m_sstr; ///< The accrued log entry.\n    LogTag m_logTag = LogTag::None;\n};\n\n/// Logging class, iostream-like, that can be shifted to.\ntemplate <class Id, bool _AutoSpacing = true>\nclass LogOutputStream : LogOutputStreamBase\n{\n  public:\n    /// Construct a new object.\n    /// If _term is true the the prefix info is terminated with a ']' character; if not it ends only with a '|' character.\n    LogOutputStream() : LogOutputStreamBase(Id::name(), &typeid(Id), Id::verbosity, _AutoSpacing) {}\n\n    /// Destructor. Posts the accrued log entry to the g_logPost function.\n    ~LogOutputStream()\n    {\n        if (Id::verbosity <= g_logVerbosity)\n            g_logPost(m_sstr.str(), Id::name());\n    }\n\n    LogOutputStream &operator<<(std::string const &_t)\n    {\n        if (Id::verbosity <= g_logVerbosity)\n        {\n            if (_AutoSpacing && m_sstr.str().size() && m_sstr.str().back() != ' ')\n                m_sstr << \" \";\n            comment(_t);\n        }\n        return *this;\n    }\n\n    LogOutputStream &operator<<(LogTag _t)\n    {\n        m_logTag = _t;\n        return *this;\n    }\n\n    /// Shift arbitrary data to the log. Spaces will be added between items as required.\n    template <class T>\n    LogOutputStream &operator<<(T const &_t)\n    {\n        if (Id::verbosity <= g_logVerbosity)\n        {\n            if (_AutoSpacing && m_sstr.str().size() && m_sstr.str().back() != ' ')\n                m_sstr << \" \";\n            append(_t);\n        }\n        return *this;\n    }\n};\n\n/// A \"hacky\" way to execute the next statement on COND.\n/// We need such a thing due to the dangling else problem and the need\n/// for the logging macros to end with the stream object and not a closing brace '}'\n#define DEV_STATEMENT_IF(COND) for (bool i_eth_if_ = (COND); i_eth_if_; i_eth_if_ = false)\n/// A \"hacky\" way to skip the next statement.\n/// We need such a thing due to the dangling else problem and the need\n/// for the logging macros to end with the stream object and not a closing brace '}'\n#define DEV_STATEMENT_SKIP() while (/*CONSTCOND*/ false) /*NOTREACHED*/\n// Kill all logs when when NLOG is defined.\n#if NLOG\n#define clog(X) nlog(X)\n#define cslog(X) nslog(X)\n#else\n#if NDEBUG\n#define clog(X) DEV_STATEMENT_IF(!(X::debug)) \\\nlibbitcoin::LogOutputStream<X, true>()\n#define cslog(X) DEV_STATEMENT_IF(!(X::debug)) \\\nlibbitcoin::LogOutputStream<X, false>()\n#else\n#define clog(X) libbitcoin::LogOutputStream<X, true>()\n#define cslog(X) libbitcoin::LogOutputStream<X, false>()\n#endif\n#endif\n\n// Simple cout-like stream objects for accessing common log channels.\n// Dirties the global namespace, but oh so convenient...\n#define cdebug clog(libbitcoin::DebugChannel)\n#define cnote clog(libbitcoin::NoteChannel)\n#define cwarn clog(libbitcoin::WarnChannel)\n#define ctrace clog(libbitcoin::TraceChannel)\n\n// Null stream-like objects.\n#define ndebug DEV_STATEMENT_SKIP() \\\nlibbitcoin::NullOutputStream()\n#define nlog(X) DEV_STATEMENT_SKIP() \\\nlibbitcoin::NullOutputStream()\n#define nslog(X) DEV_STATEMENT_SKIP() \\\nlibbitcoin::NullOutputStream()\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/consensus/libdevcore/RLP.h",
    "content": "/*\n    This file is part of cpp-ethereum.\n\n    cpp-ethereum is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    cpp-ethereum is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/** @file RLP.h\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n *\n * RLP (de-)serialisation.\n */\n\n#pragma once\n\n#include <vector>\n#include <array>\n#include <exception>\n#include <iostream>\n#include <iomanip>\n#include \"vector_ref.h\"\n#include \"Common.h\"\n#include \"Exceptions.h\"\n#include \"FixedHash.h\"\n\nnamespace libbitcoin\n{\n\nclass RLP;\nusing RLPs = std::vector<RLP>;\n\ntemplate <class _T>\nstruct intTraits\n{\n    static const unsigned maxSize = sizeof(_T);\n};\ntemplate <>\nstruct intTraits<u160>\n{\n    static const unsigned maxSize = 20;\n};\ntemplate <>\nstruct intTraits<u256>\n{\n    static const unsigned maxSize = 32;\n};\ntemplate <>\nstruct intTraits<bigint>\n{\n    static const unsigned maxSize = ~(unsigned)0;\n};\n\nstatic const byte c_rlpMaxLengthBytes = 8;\nstatic const byte c_rlpDataImmLenStart = 0x80;\nstatic const byte c_rlpListStart = 0xc0;\n\nstatic const byte c_rlpDataImmLenCount = c_rlpListStart - c_rlpDataImmLenStart - c_rlpMaxLengthBytes;\nstatic const byte c_rlpDataIndLenZero = c_rlpDataImmLenStart + c_rlpDataImmLenCount - 1;\nstatic const byte c_rlpListImmLenCount = 256 - c_rlpListStart - c_rlpMaxLengthBytes;\nstatic const byte c_rlpListIndLenZero = c_rlpListStart + c_rlpListImmLenCount - 1;\n\ntemplate <class T>\nstruct Converter\n{\n    static T convert(RLP const &, int) { BOOST_THROW_EXCEPTION(BadCast()); }\n};\n\n/**\n * @brief Class for interpreting Recursive Linear-Prefix Data.\n * @by Gav Wood, 2013\n *\n * Class for reading byte arrays of data in RLP format.\n */\nclass RLP\n{\n  public:\n    /// Conversion flags\n    enum\n    {\n        AllowNonCanon = 1,\n        ThrowOnFail = 4,\n        FailIfTooBig = 8,\n        FailIfTooSmall = 16,\n        Strict = ThrowOnFail | FailIfTooBig,\n        VeryStrict = ThrowOnFail | FailIfTooBig | FailIfTooSmall,\n        LaissezFaire = AllowNonCanon\n    };\n\n    using Strictness = int;\n\n    /// Construct a null node.\n    RLP() {}\n\n    /// Construct a node of value given in the bytes.\n    explicit RLP(bytesConstRef _d, Strictness _s = VeryStrict);\n\n    /// Construct a node of value given in the bytes.\n    explicit RLP(bytes const &_d, Strictness _s = VeryStrict) : RLP(&_d, _s) {}\n\n    /// Construct a node to read RLP data in the bytes given.\n    RLP(byte const *_b, unsigned _s, Strictness _st = VeryStrict) : RLP(bytesConstRef(_b, _s), _st) {}\n\n    /// Construct a node to read RLP data in the string.\n    explicit RLP(std::string const &_s, Strictness _st = VeryStrict) : RLP(bytesConstRef((byte const *)_s.data(), _s.size()), _st) {}\n\n    /// The bare data of the RLP.\n    bytesConstRef data() const { return m_data; }\n\n    /// @returns true if the RLP is non-null.\n    explicit operator bool() const { return !isNull(); }\n\n    /// No value.\n    bool isNull() const { return m_data.size() == 0; }\n\n    /// Contains a zero-length string or zero-length list.\n    bool isEmpty() const { return !isNull() && (m_data[0] == c_rlpDataImmLenStart || m_data[0] == c_rlpListStart); }\n\n    /// String value.\n    bool isData() const { return !isNull() && m_data[0] < c_rlpListStart; }\n\n    /// List value.\n    bool isList() const { return !isNull() && m_data[0] >= c_rlpListStart; }\n\n    /// Integer value. Must not have a leading zero.\n    bool isInt() const;\n\n    /// @returns the number of items in the list, or zero if it isn't a list.\n    size_t itemCount() const { return isList() ? items() : 0; }\n    size_t itemCountStrict() const\n    {\n        if (!isList())\n            BOOST_THROW_EXCEPTION(BadCast());\n        return items();\n    }\n\n    /// @returns the number of bytes in the data, or zero if it isn't data.\n    size_t size() const { return isData() ? length() : 0; }\n    size_t sizeStrict() const\n    {\n        if (!isData())\n            BOOST_THROW_EXCEPTION(BadCast());\n        return length();\n    }\n\n    /// Equality operators; does best-effort conversion and checks for equality.\n    bool operator==(char const *_s) const { return isData() && toString() == _s; }\n    bool operator!=(char const *_s) const { return isData() && toString() != _s; }\n    bool operator==(std::string const &_s) const { return isData() && toString() == _s; }\n    bool operator!=(std::string const &_s) const { return isData() && toString() != _s; }\n    template <unsigned _N>\n    bool operator==(FixedHash<_N> const &_h) const { return isData() && toHash<_N>() == _h; }\n    template <unsigned _N>\n    bool operator!=(FixedHash<_N> const &_s) const { return isData() && toHash<_N>() != _s; }\n    bool operator==(unsigned const &_i) const { return isInt() && toInt<unsigned>() == _i; }\n    bool operator!=(unsigned const &_i) const { return isInt() && toInt<unsigned>() != _i; }\n    bool operator==(u256 const &_i) const { return isInt() && toInt<u256>() == _i; }\n    bool operator!=(u256 const &_i) const { return isInt() && toInt<u256>() != _i; }\n    bool operator==(bigint const &_i) const { return isInt() && toInt<bigint>() == _i; }\n    bool operator!=(bigint const &_i) const { return isInt() && toInt<bigint>() != _i; }\n\n    /// Subscript operator.\n    /// @returns the list item @a _i if isList() and @a _i < listItems(), or RLP() otherwise.\n    /// @note if used to access items in ascending order, this is efficient.\n    RLP operator[](size_t _i) const;\n\n    using element_type = RLP;\n\n    /// @brief Iterator class for iterating through items of RLP list.\n    class iterator\n    {\n        friend class RLP;\n\n      public:\n        using value_type = RLP;\n        using element_type = RLP;\n\n        iterator &operator++();\n        iterator operator++(int)\n        {\n            auto ret = *this;\n            operator++();\n            return ret;\n        }\n        RLP operator*() const { return RLP(m_currentItem); }\n        bool operator==(iterator const &_cmp) const { return m_currentItem == _cmp.m_currentItem; }\n        bool operator!=(iterator const &_cmp) const { return !operator==(_cmp); }\n\n      private:\n        iterator() {}\n        iterator(RLP const &_parent, bool _begin);\n\n        size_t m_remaining = 0;\n        bytesConstRef m_currentItem;\n    };\n\n    /// @brief Iterator into beginning of sub-item list (valid only if we are a list).\n    iterator begin() const { return iterator(*this, true); }\n\n    /// @brief Iterator into end of sub-item list (valid only if we are a list).\n    iterator end() const { return iterator(*this, false); }\n\n    template <class T>\n    inline T convert(int _flags) const;\n\n    /// Best-effort conversion operators.\n    explicit operator std::string() const { return toString(); }\n    explicit operator bytes() const { return toBytes(); }\n    explicit operator RLPs() const { return toList(); }\n    explicit operator uint8_t() const { return toInt<uint8_t>(); }\n    explicit operator uint16_t() const { return toInt<uint16_t>(); }\n    explicit operator uint32_t() const { return toInt<uint32_t>(); }\n    explicit operator uint64_t() const { return toInt<uint64_t>(); }\n    explicit operator u160() const { return toInt<u160>(); }\n    explicit operator u256() const { return toInt<u256>(); }\n    explicit operator bigint() const { return toInt<bigint>(); }\n    template <unsigned N>\n    explicit operator FixedHash<N>() const { return toHash<FixedHash<N>>(); }\n    template <class T, class U>\n    explicit operator std::pair<T, U>() const { return toPair<T, U>(); }\n    template <class T>\n    explicit operator std::vector<T>() const { return toVector<T>(); }\n    template <class T>\n    explicit operator std::set<T>() const { return toSet<T>(); }\n    template <class T, size_t N>\n    explicit operator std::array<T, N>() const { return toArray<T, N>(); }\n\n    /// Converts to bytearray. @returns the empty byte array if not a string.\n    bytes toBytes(int _flags = LaissezFaire) const\n    {\n        if (!isData())\n        {\n            if (_flags & ThrowOnFail)\n                BOOST_THROW_EXCEPTION(BadCast());\n            else\n                return bytes();\n        }\n        return bytes(payload().data(), payload().data() + length());\n    }\n    /// Converts to bytearray. @returns the empty byte array if not a string.\n    bytesConstRef toBytesConstRef(int _flags = LaissezFaire) const\n    {\n        if (!isData())\n        {\n            if (_flags & ThrowOnFail)\n                BOOST_THROW_EXCEPTION(BadCast());\n            else\n                return bytesConstRef();\n        }\n        return payload().cropped(0, length());\n    }\n    /// Converts to string. @returns the empty string if not a string.\n    std::string toString(int _flags = LaissezFaire) const\n    {\n        if (!isData())\n        {\n            if (_flags & ThrowOnFail)\n                BOOST_THROW_EXCEPTION(BadCast());\n            else\n                return std::string();\n        }\n        return payload().cropped(0, length()).toString();\n    }\n    /// Converts to string. @throws BadCast if not a string.\n    std::string toStringStrict() const { return toString(Strict); }\n\n    template <class T>\n    std::vector<T> toVector(int _flags = LaissezFaire) const\n    {\n        std::vector<T> ret;\n        if (isList())\n        {\n            ret.reserve(itemCount());\n            for (auto const &i : *this)\n                ret.push_back(i.convert<T>(_flags));\n        }\n        else if (_flags & ThrowOnFail)\n            BOOST_THROW_EXCEPTION(BadCast());\n        return ret;\n    }\n\n    template <class T>\n    std::set<T> toSet(int _flags = LaissezFaire) const\n    {\n        std::set<T> ret;\n        if (isList())\n            for (auto const &i : *this)\n                ret.insert(i.convert<T>(_flags));\n        else if (_flags & ThrowOnFail)\n            BOOST_THROW_EXCEPTION(BadCast());\n        return ret;\n    }\n\n    template <class T>\n    std::unordered_set<T> toUnorderedSet(int _flags = LaissezFaire) const\n    {\n        std::unordered_set<T> ret;\n        if (isList())\n            for (auto const &i : *this)\n                ret.insert(i.convert<T>(_flags));\n        else if (_flags & ThrowOnFail)\n            BOOST_THROW_EXCEPTION(BadCast());\n        return ret;\n    }\n\n    template <class T, class U>\n    std::pair<T, U> toPair(int _flags = Strict) const\n    {\n        std::pair<T, U> ret;\n        if (itemCountStrict() != 2)\n        {\n            if (_flags & ThrowOnFail)\n                BOOST_THROW_EXCEPTION(BadCast());\n            else\n                return ret;\n        }\n        ret.first = (*this)[0].convert<T>(_flags);\n        ret.second = (*this)[1].convert<U>(_flags);\n        return ret;\n    }\n\n    template <class T, size_t N>\n    std::array<T, N> toArray(int _flags = LaissezFaire) const\n    {\n        if (itemCountStrict() != N)\n        {\n            if (_flags & ThrowOnFail)\n                BOOST_THROW_EXCEPTION(BadCast());\n            else\n                return std::array<T, N>();\n        }\n        std::array<T, N> ret;\n        for (size_t i = 0; i < N; ++i)\n            ret[i] = operator[](i).convert<T>(_flags);\n        return ret;\n    }\n\n    /// Converts to int of type given; if isString(), decodes as big-endian bytestream. @returns 0 if not an int or string.\n    template <class _T = unsigned>\n    _T toInt(int _flags = Strict) const\n    {\n        requireGood();\n        if ((!isInt() && !(_flags & AllowNonCanon)) || isList() || isNull())\n        {\n            if (_flags & ThrowOnFail)\n                BOOST_THROW_EXCEPTION(BadCast());\n            else\n                return 0;\n        }\n\n        auto p = payload();\n        if (p.size() > intTraits<_T>::maxSize && (_flags & FailIfTooBig))\n        {\n            if (_flags & ThrowOnFail)\n                BOOST_THROW_EXCEPTION(BadCast());\n            else\n                return 0;\n        }\n\n        return fromBigEndian<_T>(p);\n    }\n\n    template <class _N>\n    _N toHash(int _flags = Strict) const\n    {\n        requireGood();\n        auto p = payload();\n        auto l = p.size();\n        if (!isData() || (l > _N::size && (_flags & FailIfTooBig)) || (l < _N::size && (_flags & FailIfTooSmall)))\n        {\n            if (_flags & ThrowOnFail)\n                BOOST_THROW_EXCEPTION(BadCast());\n            else\n                return _N();\n        }\n\n        _N ret;\n        size_t s = std::min<size_t>(_N::size, l);\n        memcpy(ret.data() + _N::size - s, p.data(), s);\n        return ret;\n    }\n\n    /// Converts to RLPs collection object. Useful if you need random access to sub items or will iterate over multiple times.\n    RLPs toList(int _flags = Strict) const;\n\n    /// @returns the data payload. Valid for all types.\n    bytesConstRef payload() const\n    {\n        auto l = length();\n        if (l > m_data.size())\n            BOOST_THROW_EXCEPTION(BadRLP());\n        return m_data.cropped(payloadOffset(), l);\n    }\n\n    /// @returns the theoretical size of this item as encoded in the data.\n    /// @note Under normal circumstances, is equivalent to m_data.size() - use that unless you know it won't work.\n    size_t actualSize() const;\n\n  private:\n    /// Disable construction from rvalue\n    explicit RLP(bytes const &&) {}\n\n    /// Throws if is non-canonical data (i.e. single byte done in two bytes that could be done in one).\n    void requireGood() const;\n\n    /// Single-byte data payload.\n    bool isSingleByte() const { return !isNull() && m_data[0] < c_rlpDataImmLenStart; }\n\n    /// @returns the amount of bytes used to encode the length of the data. Valid for all types.\n    unsigned lengthSize() const\n    {\n        if (isData() && m_data[0] > c_rlpDataIndLenZero)\n            return m_data[0] - c_rlpDataIndLenZero;\n        if (isList() && m_data[0] > c_rlpListIndLenZero)\n            return m_data[0] - c_rlpListIndLenZero;\n        return 0;\n    }\n\n    /// @returns the size in bytes of the payload, as given by the RLP as opposed to as inferred from m_data.\n    size_t length() const;\n\n    /// @returns the number of bytes into the data that the payload starts.\n    size_t payloadOffset() const { return isSingleByte() ? 0 : (1 + lengthSize()); }\n\n    /// @returns the number of data items.\n    size_t items() const;\n\n    /// @returns the size encoded into the RLP in @a _data and throws if _data is too short.\n    static size_t sizeAsEncoded(bytesConstRef _data) { return RLP(_data, ThrowOnFail | FailIfTooSmall).actualSize(); }\n\n    /// Our byte data.\n    bytesConstRef m_data;\n\n    /// The list-indexing cache.\n    mutable size_t m_lastIndex = (size_t)-1;\n    mutable size_t m_lastEnd = 0;\n    mutable bytesConstRef m_lastItem;\n};\n\ntemplate <>\nstruct Converter<std::string>\n{\n    static std::string convert(RLP const &_r, int _flags) { return _r.toString(_flags); }\n};\ntemplate <>\nstruct Converter<bytes>\n{\n    static bytes convert(RLP const &_r, int _flags) { return _r.toBytes(_flags); }\n};\ntemplate <>\nstruct Converter<RLPs>\n{\n    static RLPs convert(RLP const &_r, int _flags) { return _r.toList(_flags); }\n};\ntemplate <>\nstruct Converter<uint8_t>\n{\n    static uint8_t convert(RLP const &_r, int _flags) { return _r.toInt<uint8_t>(_flags); }\n};\ntemplate <>\nstruct Converter<uint16_t>\n{\n    static uint16_t convert(RLP const &_r, int _flags) { return _r.toInt<uint16_t>(_flags); }\n};\ntemplate <>\nstruct Converter<uint32_t>\n{\n    static uint32_t convert(RLP const &_r, int _flags) { return _r.toInt<uint32_t>(_flags); }\n};\ntemplate <>\nstruct Converter<uint64_t>\n{\n    static uint64_t convert(RLP const &_r, int _flags) { return _r.toInt<uint64_t>(_flags); }\n};\ntemplate <>\nstruct Converter<u160>\n{\n    static u160 convert(RLP const &_r, int _flags) { return _r.toInt<u160>(_flags); }\n};\ntemplate <>\nstruct Converter<u256>\n{\n    static u256 convert(RLP const &_r, int _flags) { return _r.toInt<u256>(_flags); }\n};\ntemplate <>\nstruct Converter<bigint>\n{\n    static bigint convert(RLP const &_r, int _flags) { return _r.toInt<bigint>(_flags); }\n};\ntemplate <unsigned N>\nstruct Converter<FixedHash<N>>\n{\n    static FixedHash<N> convert(RLP const &_r, int _flags) { return _r.toHash<FixedHash<N>>(_flags); }\n};\ntemplate <class T, class U>\nstruct Converter<std::pair<T, U>>\n{\n    static std::pair<T, U> convert(RLP const &_r, int _flags) { return _r.toPair<T, U>(_flags); }\n};\ntemplate <class T>\nstruct Converter<std::vector<T>>\n{\n    static std::vector<T> convert(RLP const &_r, int _flags) { return _r.toVector<T>(_flags); }\n};\ntemplate <class T>\nstruct Converter<std::set<T>>\n{\n    static std::set<T> convert(RLP const &_r, int _flags) { return _r.toSet<T>(_flags); }\n};\ntemplate <class T>\nstruct Converter<std::unordered_set<T>>\n{\n    static std::unordered_set<T> convert(RLP const &_r, int _flags) { return _r.toUnorderedSet<T>(_flags); }\n};\ntemplate <class T, size_t N>\nstruct Converter<std::array<T, N>>\n{\n    static std::array<T, N> convert(RLP const &_r, int _flags) { return _r.toArray<T, N>(_flags); }\n};\n\ntemplate <class T>\ninline T RLP::convert(int _flags) const { return Converter<T>::convert(*this, _flags); }\n\n/**\n * @brief Class for writing to an RLP bytestream.\n */\nclass RLPStream\n{\n  public:\n    /// Initializes empty RLPStream.\n    RLPStream() {}\n\n    /// Initializes the RLPStream as a list of @a _listItems items.\n    explicit RLPStream(size_t _listItems) { appendList(_listItems); }\n\n    ~RLPStream() {}\n\n    /// Append given datum to the byte stream.\n    RLPStream &append(unsigned _s) { return append(bigint(_s)); }\n    RLPStream &append(u160 _s) { return append(bigint(_s)); }\n    RLPStream &append(u256 _s) { return append(bigint(_s)); }\n    RLPStream &append(bigint _s);\n    RLPStream &append(bytesConstRef _s, bool _compact = false);\n    RLPStream &append(bytes const &_s) { return append(bytesConstRef(&_s)); }\n    RLPStream &append(std::string const &_s) { return append(bytesConstRef(_s)); }\n    RLPStream &append(char const *_s) { return append(std::string(_s)); }\n    template <unsigned N>\n    RLPStream &append(FixedHash<N> _s, bool _compact = false, bool _allOrNothing = false) { return _allOrNothing && !_s ? append(bytesConstRef()) : append(_s.ref(), _compact); }\n\n    /// Appends an arbitrary RLP fragment - this *must* be a single item unless @a _itemCount is given.\n    RLPStream &append(RLP const &_rlp, size_t _itemCount = 1) { return appendRaw(_rlp.data(), _itemCount); }\n\n    /// Appends a sequence of data to the stream as a list.\n    template <class _T>\n    RLPStream &append(std::vector<_T> const &_s) { return appendVector(_s); }\n    template <class _T>\n    RLPStream &appendVector(std::vector<_T> const &_s)\n    {\n        appendList(_s.size());\n        for (auto const &i : _s)\n            append(i);\n        return *this;\n    }\n    template <class _T, size_t S>\n    RLPStream &append(std::array<_T, S> const &_s)\n    {\n        appendList(_s.size());\n        for (auto const &i : _s)\n            append(i);\n        return *this;\n    }\n    template <class _T>\n    RLPStream &append(std::set<_T> const &_s)\n    {\n        appendList(_s.size());\n        for (auto const &i : _s)\n            append(i);\n        return *this;\n    }\n    template <class _T>\n    RLPStream &append(std::unordered_set<_T> const &_s)\n    {\n        appendList(_s.size());\n        for (auto const &i : _s)\n            append(i);\n        return *this;\n    }\n    template <class T, class U>\n    RLPStream &append(std::pair<T, U> const &_s)\n    {\n        appendList(2);\n        append(_s.first);\n        append(_s.second);\n        return *this;\n    }\n\n    /// Appends a list.\n    RLPStream &appendList(size_t _items);\n    RLPStream &appendList(bytesConstRef _rlp);\n    RLPStream &appendList(bytes const &_rlp) { return appendList(&_rlp); }\n    RLPStream &appendList(RLPStream const &_s) { return appendList(&_s.out()); }\n\n    /// Appends raw (pre-serialised) RLP data. Use with caution.\n    RLPStream &appendRaw(bytesConstRef _rlp, size_t _itemCount = 1);\n    RLPStream &appendRaw(bytes const &_rlp, size_t _itemCount = 1) { return appendRaw(&_rlp, _itemCount); }\n\n    /// Shift operators for appending data items.\n    template <class T>\n    RLPStream &operator<<(T _data) { return append(_data); }\n\n    /// Clear the output stream so far.\n    void clear()\n    {\n        m_out.clear();\n        m_listStack.clear();\n    }\n\n    /// Read the byte stream.\n    bytes const &out() const\n    {\n        if (!m_listStack.empty())\n            BOOST_THROW_EXCEPTION(RLPException() << errinfo_comment(\"listStack is not empty\"));\n        return m_out;\n    }\n\n    /// Invalidate the object and steal the output byte stream.\n    bytes &&invalidate()\n    {\n        if (!m_listStack.empty())\n            BOOST_THROW_EXCEPTION(RLPException() << errinfo_comment(\"listStack is not empty\"));\n        return std::move(m_out);\n    }\n\n    /// Swap the contents of the output stream out for some other byte array.\n    void swapOut(bytes &_dest)\n    {\n        if (!m_listStack.empty())\n            BOOST_THROW_EXCEPTION(RLPException() << errinfo_comment(\"listStack is not empty\"));\n        swap(m_out, _dest);\n    }\n\n  private:\n    void noteAppended(size_t _itemCount = 1);\n\n    /// Push the node-type byte (using @a _base) along with the item count @a _count.\n    /// @arg _count is number of characters for strings, data-bytes for ints, or items for lists.\n    void pushCount(size_t _count, byte _offset);\n\n    /// Push an integer as a raw big-endian byte-stream.\n    template <class _T>\n    void pushInt(_T _i, size_t _br)\n    {\n        m_out.resize(m_out.size() + _br);\n        byte *b = &m_out.back();\n        for (; _i; _i >>= 8)\n            *(b--) = (byte)_i;\n    }\n\n    /// Our output byte stream.\n    bytes m_out;\n\n    std::vector<std::pair<size_t, size_t>> m_listStack;\n};\n\ntemplate <class _T>\nvoid rlpListAux(RLPStream &_out, _T _t) { _out << _t; }\ntemplate <class _T, class... _Ts>\nvoid rlpListAux(RLPStream &_out, _T _t, _Ts... _ts) { rlpListAux(_out << _t, _ts...); }\n\n/// Export a single item in RLP format, returning a byte array.\ntemplate <class _T>\nbytes rlp(_T _t) { return (RLPStream() << _t).out(); }\n\n/// Export a list of items in RLP format, returning a byte array.\ninline bytes rlpList() { return RLPStream(0).out(); }\ntemplate <class... _Ts>\nbytes rlpList(_Ts... _ts)\n{\n    RLPStream out(sizeof...(_Ts));\n    rlpListAux(out, _ts...);\n    return out.out();\n}\n\n/// The empty string in RLP format.\nextern bytes RLPNull;\n\n/// The empty list in RLP format.\nextern bytes RLPEmptyList;\n\n/// Human readable version of RLP.\nstd::ostream &operator<<(std::ostream &_out, libbitcoin::RLP const &_d);\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/consensus/libdevcore/SHA3.h",
    "content": "/*\n    This file is part of cpp-ethereum.\n\n    cpp-ethereum is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    cpp-ethereum is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/** @file SHA3.h\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n *\n * The FixedHash fixed-size \"hash\" container type.\n */\n\n#pragma once\n\n#include <string>\n#include \"FixedHash.h\"\n#include \"vector_ref.h\"\n\nnamespace libbitcoin\n{\n\n// SHA-3 convenience routines.\n\n/// Calculate SHA3-256 hash of the given input and load it into the given output.\n/// @returns false if o_output.size() != 32.\nbool sha3(bytesConstRef _input, bytesRef o_output);\n\n/// Calculate SHA3-256 hash of the given input, returning as a 256-bit hash.\ninline h256 sha3(bytesConstRef _input)\n{\n    h256 ret;\n    sha3(_input, ret.ref());\n    return ret;\n}\ninline SecureFixedHash<32> sha3Secure(bytesConstRef _input)\n{\n    SecureFixedHash<32> ret;\n    sha3(_input, ret.writable().ref());\n    return ret;\n}\n\n/// Calculate SHA3-256 hash of the given input, returning as a 256-bit hash.\ninline h256 sha3(bytes const &_input) { return sha3(bytesConstRef(&_input)); }\ninline SecureFixedHash<32> sha3Secure(bytes const &_input) { return sha3Secure(bytesConstRef(&_input)); }\n\n/// Calculate SHA3-256 hash of the given input (presented as a binary-filled string), returning as a 256-bit hash.\ninline h256 sha3(std::string const &_input) { return sha3(bytesConstRef(_input)); }\ninline SecureFixedHash<32> sha3Secure(std::string const &_input) { return sha3Secure(bytesConstRef(_input)); }\n\n/// Calculate SHA3-256 hash of the given input (presented as a FixedHash), returns a 256-bit hash.\ntemplate <unsigned N>\ninline h256 sha3(FixedHash<N> const &_input) { return sha3(_input.ref()); }\ntemplate <unsigned N>\ninline SecureFixedHash<32> sha3Secure(FixedHash<N> const &_input) { return sha3Secure(_input.ref()); }\n\n/// Fully secure variants are equivalent for sha3 and sha3Secure.\ninline SecureFixedHash<32> sha3(bytesSec const &_input) { return sha3Secure(_input.ref()); }\ninline SecureFixedHash<32> sha3Secure(bytesSec const &_input) { return sha3Secure(_input.ref()); }\ntemplate <unsigned N>\ninline SecureFixedHash<32> sha3(SecureFixedHash<N> const &_input) { return sha3Secure(_input.ref()); }\ntemplate <unsigned N>\ninline SecureFixedHash<32> sha3Secure(SecureFixedHash<N> const &_input) { return sha3Secure(_input.ref()); }\n\n/// Calculate SHA3-256 hash of the given input, possibly interpreting it as nibbles, and return the hash as a string filled with binary data.\ninline std::string sha3(std::string const &_input, bool _isNibbles) { return asString((_isNibbles ? sha3(fromHex(_input)) : sha3(bytesConstRef(&_input))).asBytes()); }\n\n/// Calculate SHA3-256 MAC\ninline void sha3mac(bytesConstRef _secret, bytesConstRef _plain, bytesRef _output) { sha3(_secret.toBytes() + _plain.toBytes()).ref().populate(_output); }\n\nextern h256 EmptySHA3;\n\nextern h256 EmptyListSHA3;\n\nextern unsigned g_sha3Counter;\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/consensus/libdevcore/Terminal.h",
    "content": "#pragma once\n\nnamespace libbitcoin\n{\nnamespace con\n{\n\n#if defined(_WIN32)\n\n#define EthReset \"\" // Text Reset\n\n#define EthReset \"\" // Text Reset\n\n// Regular Colors\n#define EthBlack \"\"  // Black\n#define EthCoal \"\"   // Black\n#define EthGray \"\"   // White\n#define EthWhite \"\"  // White\n#define EthMaroon \"\" // Red\n#define EthRed \"\"    // Red\n#define EthGreen \"\"  // Green\n#define EthLime \"\"   // Green\n#define EthOrange \"\" // Yellow\n#define EthYellow \"\" // Yellow\n#define EthNavy \"\"   // Blue\n#define EthBlue \"\"   // Blue\n#define EthViolet \"\" // Purple\n#define EthPurple \"\" // Purple\n#define EthTeal \"\"   // Cyan\n#define EthCyan \"\"   // Cyan\n\n#define EthBlackBold \"\"  // Black\n#define EthCoalBold \"\"   // Black\n#define EthGrayBold \"\"   // White\n#define EthWhiteBold \"\"  // White\n#define EthMaroonBold \"\" // Red\n#define EthRedBold \"\"    // Red\n#define EthGreenBold \"\"  // Green\n#define EthLimeBold \"\"   // Green\n#define EthOrangeBold \"\" // Yellow\n#define EthYellowBold \"\" // Yellow\n#define EthNavyBold \"\"   // Blue\n#define EthBlueBold \"\"   // Blue\n#define EthVioletBold \"\" // Purple\n#define EthPurpleBold \"\" // Purple\n#define EthTealBold \"\"   // Cyan\n#define EthCyanBold \"\"   // Cyan\n\n// Background\n#define EthOnBlack \"\"  // Black\n#define EthOnCoal \"\"   // Black\n#define EthOnGray \"\"   // White\n#define EthOnWhite \"\"  // White\n#define EthOnMaroon \"\" // Red\n#define EthOnRed \"\"    // Red\n#define EthOnGreen \"\"  // Green\n#define EthOnLime \"\"   // Green\n#define EthOnOrange \"\" // Yellow\n#define EthOnYellow \"\" // Yellow\n#define EthOnNavy \"\"   // Blue\n#define EthOnBlue \"\"   // Blue\n#define EthOnViolet \"\" // Purple\n#define EthOnPurple \"\" // Purple\n#define EthOnTeal \"\"   // Cyan\n#define EthOnCyan \"\"   // Cyan\n\n// Underline\n#define EthBlackUnder \"\"  // Black\n#define EthGrayUnder \"\"   // White\n#define EthMaroonUnder \"\" // Red\n#define EthGreenUnder \"\"  // Green\n#define EthOrangeUnder \"\" // Yellow\n#define EthNavyUnder \"\"   // Blue\n#define EthVioletUnder \"\" // Purple\n#define EthTealUnder \"\"   // Cyan\n\n#else\n\n#define EthReset \"\\x1b[0m\"   // Text Reset\n\n// Regular Colors\n#define EthBlack \"\\x1b[30m\"  // Black\n#define EthCoal \"\\x1b[90m\"   // Black\n#define EthGray \"\\x1b[37m\"   // White\n#define EthWhite \"\\x1b[97m\"  // White\n#define EthMaroon \"\\x1b[31m\" // Red\n#define EthRed \"\\x1b[91m\"    // Red\n#define EthGreen \"\\x1b[32m\"  // Green\n#define EthLime \"\\x1b[92m\"   // Green\n#define EthOrange \"\\x1b[33m\" // Yellow\n#define EthYellow \"\\x1b[93m\" // Yellow\n#define EthNavy \"\\x1b[34m\"   // Blue\n#define EthBlue \"\\x1b[94m\"   // Blue\n#define EthViolet \"\\x1b[35m\" // Purple\n#define EthPurple \"\\x1b[95m\" // Purple\n#define EthTeal \"\\x1b[36m\"   // Cyan\n#define EthCyan \"\\x1b[96m\"   // Cyan\n\n#define EthBlackBold \"\\x1b[1;30m\"   // Black\n#define EthCoalBold \"\\x1b[1;90m\"    // Black\n#define EthGrayBold \"\\x1b[1;37m\"    // White\n#define EthWhiteBold \"\\x1b[1;97m\"   // White\n#define EthMaroonBold \"\\x1b[1;31m\"  // Red\n#define EthRedBold \"\\x1b[1;91m\"     // Red\n#define EthGreenBold \"\\x1b[1;32m\"   // Green\n#define EthLimeBold \"\\x1b[1;92m\"    // Green\n#define EthOrangeBold \"\\x1b[1;33m\"  // Yellow\n#define EthYellowBold \"\\x1b[1;93m\"  // Yellow\n#define EthNavyBold \"\\x1b[1;34m\"    // Blue\n#define EthBlueBold \"\\x1b[1;94m\"    // Blue\n#define EthVioletBold \"\\x1b[1;35m\"  // Purple\n#define EthPurpleBold \"\\x1b[1;95m\"  // Purple\n#define EthTealBold \"\\x1b[1;36m\"    // Cyan\n#define EthCyanBold \"\\x1b[1;96m\"    // Cyan\n\n// Background\n#define EthOnBlack \"\\x1b[40m\"       // Black\n#define EthOnCoal \"\\x1b[100m\"       // Black\n#define EthOnGray \"\\x1b[47m\"        // White\n#define EthOnWhite \"\\x1b[107m\"      // White\n#define EthOnMaroon \"\\x1b[41m\"      // Red\n#define EthOnRed \"\\x1b[101m\"        // Red\n#define EthOnGreen \"\\x1b[42m\"       // Green\n#define EthOnLime \"\\x1b[102m\"       // Green\n#define EthOnOrange \"\\x1b[43m\"      // Yellow\n#define EthOnYellow \"\\x1b[103m\"     // Yellow\n#define EthOnNavy \"\\x1b[44m\"        // Blue\n#define EthOnBlue \"\\x1b[104m\"       // Blue\n#define EthOnViolet \"\\x1b[45m\"      // Purple\n#define EthOnPurple \"\\x1b[105m\"     // Purple\n#define EthOnTeal \"\\x1b[46m\"        // Cyan\n#define EthOnCyan \"\\x1b[106m\"       // Cyan\n\n// Underline\n#define EthBlackUnder \"\\x1b[4;30m\"  // Black\n#define EthGrayUnder \"\\x1b[4;37m\"   // White\n#define EthMaroonUnder \"\\x1b[4;31m\" // Red\n#define EthGreenUnder \"\\x1b[4;32m\"  // Green\n#define EthOrangeUnder \"\\x1b[4;33m\" // Yellow\n#define EthNavyUnder \"\\x1b[4;34m\"   // Blue\n#define EthVioletUnder \"\\x1b[4;35m\" // Purple\n#define EthTealUnder \"\\x1b[4;36m\"   // Cyan\n\n#endif\n\n} // namespace con\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/consensus/libdevcore/picosha2.h",
    "content": "/*\nThe MIT License (MIT)\n\nCopyright (C) 2014 okdshin\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n*/\n#ifndef PICOSHA2_H\n#define PICOSHA2_H\n//picosha2:20140213\n#include <cstdint>\n#include <iostream>\n#include <vector>\n#include <iterator>\n#include <cassert>\n#include <sstream>\n#include <algorithm>\n\nnamespace picosha2\n{\n\nnamespace detail\n{\n\ninline uint8_t mask_8bit(uint8_t x)\n{\n    return x & 0xff;\n}\n\ninline uint32_t mask_32bit(uint32_t x)\n{\n    return x & 0xffffffff;\n}\n\nstatic const uint32_t add_constant[64] = {\n    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,\n    0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,\n    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,\n    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,\n    0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,\n    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,\n    0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,\n    0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,\n    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};\n\nstatic const uint32_t initial_message_digest[8] = {\n    0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,\n    0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};\n\ninline uint32_t ch(uint32_t x, uint32_t y, uint32_t z)\n{\n    return (x & y) ^ ((~x) & z);\n}\n\ninline uint32_t maj(uint32_t x, uint32_t y, uint32_t z)\n{\n    return (x & y) ^ (x & z) ^ (y & z);\n}\n\ninline uint32_t rotr(uint32_t x, std::size_t n)\n{\n    assert(n < 32);\n    return mask_32bit((x >> n) | (x << (32 - n)));\n}\n\ninline uint32_t bsig0(uint32_t x)\n{\n    return rotr(x, 2) ^ rotr(x, 13) ^ rotr(x, 22);\n}\n\ninline uint32_t bsig1(uint32_t x)\n{\n    return rotr(x, 6) ^ rotr(x, 11) ^ rotr(x, 25);\n}\n\ninline uint32_t shr(uint32_t x, std::size_t n)\n{\n    assert(n < 32);\n    return x >> n;\n}\n\ninline uint32_t ssig0(uint32_t x)\n{\n    return rotr(x, 7) ^ rotr(x, 18) ^ shr(x, 3);\n}\n\ninline uint32_t ssig1(uint32_t x)\n{\n    return rotr(x, 17) ^ rotr(x, 19) ^ shr(x, 10);\n}\n\ntemplate <typename RaIter1, typename RaIter2>\nvoid hash256_block(RaIter1 message_digest, RaIter2 first, RaIter2 last)\n{\n    (void)last; // FIXME: check this is valid\n    uint32_t w[64];\n    std::fill(w, w + 64, 0);\n    for (std::size_t i = 0; i < 16; ++i)\n    {\n        w[i] = (static_cast<uint32_t>(mask_8bit(*(first + i * 4))) << 24) | (static_cast<uint32_t>(mask_8bit(*(first + i * 4 + 1))) << 16) | (static_cast<uint32_t>(mask_8bit(*(first + i * 4 + 2))) << 8) | (static_cast<uint32_t>(mask_8bit(*(first + i * 4 + 3))));\n    }\n    for (std::size_t i = 16; i < 64; ++i)\n    {\n        w[i] = mask_32bit(ssig1(w[i - 2]) + w[i - 7] + ssig0(w[i - 15]) + w[i - 16]);\n    }\n\n    uint32_t a = *message_digest;\n    uint32_t b = *(message_digest + 1);\n    uint32_t c = *(message_digest + 2);\n    uint32_t d = *(message_digest + 3);\n    uint32_t e = *(message_digest + 4);\n    uint32_t f = *(message_digest + 5);\n    uint32_t g = *(message_digest + 6);\n    uint32_t h = *(message_digest + 7);\n\n    for (std::size_t i = 0; i < 64; ++i)\n    {\n        uint32_t temp1 = h + bsig1(e) + ch(e, f, g) + add_constant[i] + w[i];\n        uint32_t temp2 = bsig0(a) + maj(a, b, c);\n        h = g;\n        g = f;\n        f = e;\n        e = mask_32bit(d + temp1);\n        d = c;\n        c = b;\n        b = a;\n        a = mask_32bit(temp1 + temp2);\n    }\n    *message_digest += a;\n    *(message_digest + 1) += b;\n    *(message_digest + 2) += c;\n    *(message_digest + 3) += d;\n    *(message_digest + 4) += e;\n    *(message_digest + 5) += f;\n    *(message_digest + 6) += g;\n    *(message_digest + 7) += h;\n    for (std::size_t i = 0; i < 8; ++i)\n    {\n        *(message_digest + i) = mask_32bit(*(message_digest + i));\n    }\n}\n\n} //namespace detail\n\ntemplate <typename InIter>\nvoid output_hex(InIter first, InIter last, std::ostream &os)\n{\n    os.setf(std::ios::hex, std::ios::basefield);\n    while (first != last)\n    {\n        os.width(2);\n        os.fill('0');\n        os << static_cast<unsigned int>(*first);\n        ++first;\n    }\n    os.setf(std::ios::dec, std::ios::basefield);\n}\n\ntemplate <typename InIter>\nvoid bytes_to_hex_string(InIter first, InIter last, std::string &hex_str)\n{\n    std::ostringstream oss;\n    output_hex(first, last, oss);\n    hex_str.assign(oss.str());\n}\n\ntemplate <typename InContainer>\nvoid bytes_to_hex_string(const InContainer &bytes, std::string &hex_str)\n{\n    bytes_to_hex_string(bytes.begin(), bytes.end(), hex_str);\n}\n\ntemplate <typename InIter>\nstd::string bytes_to_hex_string(InIter first, InIter last)\n{\n    std::string hex_str;\n    bytes_to_hex_string(first, last, hex_str);\n    return hex_str;\n}\n\ntemplate <typename InContainer>\nstd::string bytes_to_hex_string(const InContainer &bytes)\n{\n    std::string hex_str;\n    bytes_to_hex_string(bytes, hex_str);\n    return hex_str;\n}\n\nclass hash256_one_by_one\n{\n  public:\n    hash256_one_by_one()\n    {\n        init();\n    }\n\n    void init()\n    {\n        buffer_.clear();\n        std::fill(data_length_digits_, data_length_digits_ + 4, 0);\n        std::copy(detail::initial_message_digest, detail::initial_message_digest + 8, h_);\n    }\n\n    template <typename RaIter>\n    void process(RaIter first, RaIter last)\n    {\n        add_to_data_length(std::distance(first, last));\n        std::copy(first, last, std::back_inserter(buffer_));\n        std::size_t i = 0;\n        for (; i + 64 <= buffer_.size(); i += 64)\n        {\n            detail::hash256_block(h_, buffer_.begin() + i, buffer_.begin() + i + 64);\n        }\n        buffer_.erase(buffer_.begin(), buffer_.begin() + i);\n    }\n\n    void finish()\n    {\n        uint8_t temp[64];\n        std::fill(temp, temp + 64, 0);\n        std::size_t remains = buffer_.size();\n        std::copy(buffer_.begin(), buffer_.end(), temp);\n        temp[remains] = 0x80;\n\n        if (remains > 55)\n        {\n            std::fill(temp + remains + 1, temp + 64, 0);\n            detail::hash256_block(h_, temp, temp + 64);\n            std::fill(temp, temp + 64 - 4, 0);\n        }\n        else\n        {\n            std::fill(temp + remains + 1, temp + 64 - 4, 0);\n        }\n\n        write_data_bit_length(&(temp[56]));\n        detail::hash256_block(h_, temp, temp + 64);\n    }\n\n    template <typename OutIter>\n    void get_hash_bytes(OutIter first, OutIter last) const\n    {\n        for (const uint32_t *iter = h_; iter != h_ + 8; ++iter)\n        {\n            for (std::size_t i = 0; i < 4 && first != last; ++i)\n            {\n                *(first++) = detail::mask_8bit(static_cast<uint8_t>((*iter >> (24 - 8 * i))));\n            }\n        }\n    }\n\n  private:\n    void add_to_data_length(uint32_t n)\n    {\n        uint32_t carry = 0;\n        data_length_digits_[0] += n;\n        for (std::size_t i = 0; i < 4; ++i)\n        {\n            data_length_digits_[i] += carry;\n            if (data_length_digits_[i] >= 65536u)\n            {\n                data_length_digits_[i] -= 65536u;\n                carry = 1;\n            }\n            else\n            {\n                break;\n            }\n        }\n    }\n    void write_data_bit_length(uint8_t *begin)\n    {\n        uint32_t data_bit_length_digits[4];\n        std::copy(\n            data_length_digits_, data_length_digits_ + 4,\n            data_bit_length_digits);\n\n        // convert byte length to bit length (multiply 8 or shift 3 times left)\n        uint32_t carry = 0;\n        for (std::size_t i = 0; i < 4; ++i)\n        {\n            uint32_t before_val = data_bit_length_digits[i];\n            data_bit_length_digits[i] <<= 3;\n            data_bit_length_digits[i] |= carry;\n            data_bit_length_digits[i] &= 65535u;\n            carry = (before_val >> (16 - 3)) & 65535u;\n        }\n\n        // write data_bit_length\n        for (int i = 3; i >= 0; --i)\n        {\n            (*begin++) = static_cast<uint8_t>(data_bit_length_digits[i] >> 8);\n            (*begin++) = static_cast<uint8_t>(data_bit_length_digits[i]);\n        }\n    }\n    std::vector<uint8_t> buffer_;\n    uint32_t data_length_digits_[4]; //as 64bit integer (16bit x 4 integer)\n    uint32_t h_[8];\n};\n\ninline void get_hash_hex_string(const hash256_one_by_one &hasher, std::string &hex_str)\n{\n    uint8_t hash[32];\n    hasher.get_hash_bytes(hash, hash + 32);\n    return bytes_to_hex_string(hash, hash + 32, hex_str);\n}\n\ninline std::string get_hash_hex_string(const hash256_one_by_one &hasher)\n{\n    std::string hex_str;\n    get_hash_hex_string(hasher, hex_str);\n    return hex_str;\n}\n\ntemplate <typename RaIter, typename OutIter>\nvoid hash256(RaIter first, RaIter last, OutIter first2, OutIter last2)\n{\n    hash256_one_by_one hasher;\n    //hasher.init();\n    hasher.process(first, last);\n    hasher.finish();\n    hasher.get_hash_bytes(first2, last2);\n}\n\ntemplate <typename RaIter, typename OutContainer>\nvoid hash256(RaIter first, RaIter last, OutContainer &dst)\n{\n    hash256(first, last, dst.begin(), dst.end());\n}\n\ntemplate <typename RaContainer, typename OutIter>\nvoid hash256(const RaContainer &src, OutIter first, OutIter last)\n{\n    hash256(src.begin(), src.end(), first, last);\n}\n\ntemplate <typename RaContainer, typename OutContainer>\nvoid hash256(const RaContainer &src, OutContainer &dst)\n{\n    hash256(src.begin(), src.end(), dst.begin(), dst.end());\n}\n\ntemplate <typename RaIter>\nvoid hash256_hex_string(RaIter first, RaIter last, std::string &hex_str)\n{\n    uint8_t hashed[32];\n    hash256(first, last, hashed, hashed + 32);\n    std::ostringstream oss;\n    output_hex(hashed, hashed + 32, oss);\n    hex_str.assign(oss.str());\n}\n\ntemplate <typename RaIter>\nstd::string hash256_hex_string(RaIter first, RaIter last)\n{\n    std::string hex_str;\n    hash256_hex_string(first, last, hex_str);\n    return hex_str;\n}\n\ninline void hash256_hex_string(const std::string &src, std::string &hex_str)\n{\n    hash256_hex_string(src.begin(), src.end(), hex_str);\n}\n\ntemplate <typename RaContainer>\nvoid hash256_hex_string(const RaContainer &src, std::string &hex_str)\n{\n    hash256_hex_string(src.begin(), src.end(), hex_str);\n}\n\ntemplate <typename RaContainer>\nstd::string hash256_hex_string(const RaContainer &src)\n{\n    return hash256_hex_string(src.begin(), src.end());\n}\n\n} //namespace picosha2\n\n#endif //PICOSHA2_H\n"
  },
  {
    "path": "include/UChainService/consensus/libdevcore/vector_ref.h",
    "content": "#pragma once\n\n#include <cstring>\n#include <cassert>\n#include <type_traits>\n#include <vector>\n#include <string>\n\n#ifdef __INTEL_COMPILER\n#pragma warning(disable : 597) //will not be called for implicit or explicit conversions\n#endif\n\nnamespace libbitcoin\n{\n\n/**\n * A modifiable reference to an existing object or vector in memory.\n */\ntemplate <class _T>\nclass vector_ref\n{\n  public:\n    using value_type = _T;\n    using element_type = _T;\n    using mutable_value_type = typename std::conditional<std::is_const<_T>::value, typename std::remove_const<_T>::type, _T>::type;\n\n    static_assert(std::is_pod<value_type>::value, \"vector_ref can only be used with PODs due to its low-level treatment of data.\");\n\n    vector_ref() : m_data(nullptr), m_count(0) {}\n    /// Creates a new vector_ref to point to @a _count elements starting at @a _data.\n    vector_ref(_T *_data, size_t _count) : m_data(_data), m_count(_count) {}\n    /// Creates a new vector_ref pointing to the data part of a string (given as pointer).\n    vector_ref(typename std::conditional<std::is_const<_T>::value, std::string const *, std::string *>::type _data) : m_data(reinterpret_cast<_T *>(_data->data())), m_count(_data->size() / sizeof(_T)) {}\n    /// Creates a new vector_ref pointing to the data part of a vector (given as pointer).\n    vector_ref(typename std::conditional<std::is_const<_T>::value, std::vector<typename std::remove_const<_T>::type> const *, std::vector<_T> *>::type _data) : m_data(_data->data()), m_count(_data->size()) {}\n    /// Creates a new vector_ref pointing to the data part of a string (given as reference).\n    vector_ref(typename std::conditional<std::is_const<_T>::value, std::string const &, std::string &>::type _data) : m_data(reinterpret_cast<_T *>(_data.data())), m_count(_data.size() / sizeof(_T)) {}\n#if DEV_LDB\n    vector_ref(ldb::Slice const &_s) : m_data(reinterpret_cast<_T *>(_s.data())), m_count(_s.size() / sizeof(_T))\n    {\n    }\n#endif\n    explicit operator bool() const\n    {\n        return m_data && m_count;\n    }\n\n    bool contentsEqual(std::vector<mutable_value_type> const &_c) const\n    {\n        if (!m_data || m_count == 0)\n            return _c.empty();\n        else\n            return _c.size() == m_count && !memcmp(_c.data(), m_data, m_count * sizeof(_T));\n    }\n    std::vector<mutable_value_type> toVector() const { return std::vector<mutable_value_type>(m_data, m_data + m_count); }\n    std::vector<unsigned char> toBytes() const { return std::vector<unsigned char>(reinterpret_cast<unsigned char const *>(m_data), reinterpret_cast<unsigned char const *>(m_data) + m_count * sizeof(_T)); }\n    std::string toString() const { return std::string((char const *)m_data, ((char const *)m_data) + m_count * sizeof(_T)); }\n\n    template <class _T2>\n    explicit operator vector_ref<_T2>() const\n    {\n        assert(m_count * sizeof(_T) / sizeof(_T2) * sizeof(_T2) / sizeof(_T) == m_count);\n        return vector_ref<_T2>(reinterpret_cast<_T2 *>(m_data), m_count * sizeof(_T) / sizeof(_T2));\n    }\n    operator vector_ref<_T const>() const { return vector_ref<_T const>(m_data, m_count); }\n\n    _T *data() const { return m_data; }\n    /// @returns the number of elements referenced (not necessarily number of bytes).\n    size_t count() const { return m_count; }\n    /// @returns the number of elements referenced (not necessarily number of bytes).\n    size_t size() const { return m_count; }\n    bool empty() const { return !m_count; }\n    /// @returns a new vector_ref pointing at the next chunk of @a size() elements.\n    vector_ref<_T> next() const\n    {\n        if (!m_data)\n            return *this;\n        else\n            return vector_ref<_T>(m_data + m_count, m_count);\n    }\n    /// @returns a new vector_ref which is a shifted and shortened view of the original data.\n    /// If this goes out of bounds in any way, returns an empty vector_ref.\n    /// If @a _count is ~size_t(0), extends the view to the end of the data.\n    vector_ref<_T> cropped(size_t _begin, size_t _count) const\n    {\n        if (m_data && _begin <= m_count && _count <= m_count && _begin + _count <= m_count)\n            return vector_ref<_T>(m_data + _begin, _count == ~size_t(0) ? m_count - _begin : _count);\n        else\n            return vector_ref<_T>();\n    }\n    /// @returns a new vector_ref which is a shifted view of the original data (not going beyond it).\n    vector_ref<_T> cropped(size_t _begin) const\n    {\n        if (m_data && _begin <= m_count)\n            return vector_ref<_T>(m_data + _begin, m_count - _begin);\n        else\n            return vector_ref<_T>();\n    }\n    void retarget(_T *_d, size_t _s)\n    {\n        m_data = _d;\n        m_count = _s;\n    }\n    void retarget(std::vector<_T> const &_t)\n    {\n        m_data = _t.data();\n        m_count = _t.size();\n    }\n    template <class T>\n    bool overlapsWith(vector_ref<T> _t) const\n    {\n        void const *f1 = data();\n        void const *t1 = data() + size();\n        void const *f2 = _t.data();\n        void const *t2 = _t.data() + _t.size();\n        return f1 < t2 && t1 > f2;\n    }\n    /// Copies the contents of this vector_ref to the contents of @a _t, up to the max size of @a _t.\n    void copyTo(vector_ref<typename std::remove_const<_T>::type> _t) const\n    {\n        if (overlapsWith(_t))\n            memmove(_t.data(), m_data, std::min(_t.size(), m_count) * sizeof(_T));\n        else\n            memcpy(_t.data(), m_data, std::min(_t.size(), m_count) * sizeof(_T));\n    }\n    /// Copies the contents of this vector_ref to the contents of @a _t, and zeros further trailing elements in @a _t.\n    void populate(vector_ref<typename std::remove_const<_T>::type> _t) const\n    {\n        copyTo(_t);\n        memset(_t.data() + m_count, 0, std::max(_t.size(), m_count) - m_count);\n    }\n    /// Securely overwrite the memory.\n    /// @note adapted from OpenSSL's implementation.\n    void cleanse()\n    {\n        static unsigned char s_cleanseCounter = 0;\n        uint8_t *p = (uint8_t *)begin();\n        size_t const len = (uint8_t *)end() - p;\n        size_t loop = len;\n        size_t count = s_cleanseCounter;\n        while (loop--)\n        {\n            *(p++) = (uint8_t)count;\n            count += (17 + ((size_t)p & 0xf));\n        }\n        p = (uint8_t *)memchr((uint8_t *)begin(), (uint8_t)count, len);\n        if (p)\n            count += (63 + (size_t)p);\n        s_cleanseCounter = (uint8_t)count;\n        memset((uint8_t *)begin(), 0, len);\n    }\n\n    _T *begin() { return m_data; }\n    _T *end() { return m_data + m_count; }\n    _T const *begin() const { return m_data; }\n    _T const *end() const { return m_data + m_count; }\n\n    _T &operator[](size_t _i)\n    {\n        assert(m_data);\n        assert(_i < m_count);\n        return m_data[_i];\n    }\n    _T const &operator[](size_t _i) const\n    {\n        assert(m_data);\n        assert(_i < m_count);\n        return m_data[_i];\n    }\n\n    bool operator==(vector_ref<_T> const &_cmp) const { return m_data == _cmp.m_data && m_count == _cmp.m_count; }\n    bool operator!=(vector_ref<_T> const &_cmp) const { return !operator==(_cmp); }\n\n#if DEV_LDB\n    operator ldb::Slice() const\n    {\n        return ldb::Slice((char const *)m_data, m_count * sizeof(_T));\n    }\n#endif\n\n    void reset()\n    {\n        m_data = nullptr;\n        m_count = 0;\n    }\n\n  private:\n    _T *m_data;\n    size_t m_count;\n};\n\ntemplate <class _T>\nvector_ref<_T const> ref(_T const &_t) { return vector_ref<_T const>(&_t, 1); }\ntemplate <class _T>\nvector_ref<_T> ref(_T &_t) { return vector_ref<_T>(&_t, 1); }\ntemplate <class _T>\nvector_ref<_T const> ref(std::vector<_T> const &_t) { return vector_ref<_T const>(&_t); }\ntemplate <class _T>\nvector_ref<_T> ref(std::vector<_T> &_t) { return vector_ref<_T>(&_t); }\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/consensus/miner.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-consensus.\n *\n * UChain-consensus is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UC_CONSENSUS_MINER_HPP\n#define UC_CONSENSUS_MINER_HPP\n\n#include <vector>\n#include <boost/thread.hpp>\n\n#include \"UChain/blockchain/block_chain_impl.hpp\"\n#include \"UChain/blockchain/tx_pool.hpp\"\n#include \"UChain/coin/chain/block.hpp\"\n#include \"UChain/coin/chain/input.hpp\"\n#include <UChain/coin/wallet/ec_public.hpp>\n#include <UChain/blockchain/settings.hpp>\n#include <UChain/explorer/config/ec_private.hpp>\n#include <UChain/explorer/config/hashtype.hpp>\n#include <UChain/explorer/config/script.hpp>\n#include <UChainService/txs/token/candidate.hpp>\n#include <mutex>\n\nnamespace libbitcoin\n{\nnamespace node\n{\nclass p2p_node;\n}\n} // namespace libbitcoin\n\nnamespace libbitcoin\n{\nnamespace consensus\n{\n\nBC_CONSTEXPR unsigned int min_tx_fee_per_kb = 10000;\nBC_CONSTEXPR unsigned int median_time_span = 11;\nBC_CONSTEXPR uint32_t version = 1;\n\n//extern int bucket_size;\nextern vector<uint64_t> lock_heights;\n\nclass miner\n{\n  public:\n    typedef message::block_msg block;\n    typedef std::shared_ptr<message::block_msg> block_ptr;\n    typedef chain::header header;\n    typedef chain::transaction transaction;\n    typedef message::tx_message::ptr transaction_ptr;\n    typedef blockchain::block_chain_impl block_chain_impl;\n    typedef blockchain::tx_pool tx_pool;\n    typedef libbitcoin::node::p2p_node p2p_node;\n\n    // prev_output_point -> (prev_block_height, prev_output)\n    typedef std::unordered_map<chain::point, std::pair<uint64_t, chain::output>> previous_out_map_t;\n\n    // tx_hash -> tx_fee\n    typedef std::unordered_map<hash_digest, uint64_t> tx_fee_map_t;\n\n    miner(p2p_node &node);\n    ~miner();\n\n    enum state\n    {\n        init_,\n        exit_,\n        creating_block_\n    };\n\n    bool start(const bc::wallet::payment_address &pay_address, uint16_t number = 0);\n    bool start(const std::string &pay_public_key, uint16_t number = 0);\n    bool stop();\n    static block_ptr create_genesis_block(bool is_mainnet);\n    bool script_hash_signature_operations_count(size_t &count, const chain::input::list &inputs,\n                                                vector<transaction_ptr> &transactions);\n    bool script_hash_signature_operations_count(size_t &count, const chain::input &input,\n                                                vector<transaction_ptr> &transactions);\n    transaction_ptr create_coinbase_tx(const bc::wallet::payment_address &pay_addres,\n                                       uint64_t value, uint64_t block_height);\n    transaction_ptr create_lock_coinbase_tx(const bc::wallet::payment_address &pay_addres,\n                                            uint64_t value, uint64_t block_height, int lock_height, uint32_t reward_lock_time);\n\n    block_ptr get_block(bool is_force_create_block = false);\n    //bool get_work(std::string& seed_hash, std::string& header_hash, std::string& boundary);\n    /*bool put_result(const std::string& nonce, const std::string& mix_hash,\n        const std::string& header_hash, const uint64_t &nounce_mask);*/\n    //bool set_miner_public_key(const string& public_key);\n    uint64_t fetch_utxo(const transaction_ptr &ptx, const bc::wallet::payment_address &address);\n    bool get_spendable_output(chain::output &output, const chain::history &row, uint64_t height);\n    bool set_miner_payment_address(const bc::wallet::payment_address &address);\n    const std::string get_miner_address() const;\n    bool set_miner_pri_key(const std::string &pri_key);\n    //void set_user(const std::string& name, const std::string& passwd);\n    void get_state(uint64_t &height, uint32_t &miners, /*uint64_t &rate, string& difficulty,*/ bool &is_mining);\n    vector<candidate_info> &get_miners();\n    vector<std::string> &get_miner_addresses();\n    void generate_miner_list();\n    bool is_creating_block() const;\n    bool is_address_inturn(const string &pay_address) const;\n    bool get_block_header(chain::header &block_header, const string &para);\n\n    bool is_address_in_turn_with_now_height(uint64_t height, const string &pay_address) const;\n    bool is_index_in_turn_with_now_height(uint64_t height, const int index) const;\n    bool is_time_inturn_with_this_cycle(int64_t cycle_starttime) const;\n    uint16_t get_lost_block(uint64_t height, const int index);\n\n    static int get_lock_heights_index(uint64_t height);\n    static uint64_t calculate_block_subsidy(uint64_t height, bool is_testnet);\n    static uint64_t calculate_lockblock_reward(uint64_t lcok_heights, uint64_t num);\n    int get_mine_index(const string &pay_address) const;\n\n  private:\n    void work(const bc::wallet::payment_address pay_address);\n\n    block_ptr create_new_block(const bc::wallet::payment_address &pay_addres, uint64_t current_block_height = max_uint64);\n    unsigned int get_adjust_time(uint64_t height) const;\n    unsigned int get_median_time_past(uint64_t height) const;\n    bool get_transaction(std::vector<transaction_ptr> &, previous_out_map_t &, tx_fee_map_t &) const;\n    uint64_t store_block(block_ptr block);\n    uint64_t get_height() const;\n    bool get_input_ucn(const transaction &, const std::vector<transaction_ptr> &, uint64_t &, previous_out_map_t &) const;\n    bool is_stop_miner(uint64_t block_height) const;\n\n  private:\n    p2p_node &node_;\n    std::shared_ptr<boost::thread> thread_;\n    mutable state state_;\n    uint16_t new_block_number_;\n    uint16_t new_block_limit_;\n\n    block_ptr new_block_;\n    bc::wallet::payment_address pay_address_;\n    const blockchain::settings &setting_;\n    std::string pri_key;\n    std::string name_;\n    std::string passwd_;\n    vector<candidate_info> mine_candidate_list;\n    vector<std::string> mine_address_list;\n    uint16_t createblockms_;\n};\n\n} // namespace consensus\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainService/consensus/version.hpp",
    "content": "///////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 2014-2018 libbitcoin-consensus developers (see COPYING).\n//\n//        GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY\n//\n///////////////////////////////////////////////////////////////////////////////\n#ifndef UC_CONSENSUS_VERSION_HPP\n#define UC_CONSENSUS_VERSION_HPP\n\n/**\n * The semantic version of this repository as: [major].[minor].[patch]\n * For interpretation of the versioning scheme see: http://semver.org\n */\n\n#define UC_CONSENSUS_VERSION \"0.0.6\"\n#define UC_CONSENSUS_MAJOR_VERSION 0\n#define UC_CONSENSUS_MINOR_VERSION 0\n#define UC_CONSENSUS_PATCH_VERSION 6\n\n#endif\n"
  },
  {
    "path": "include/UChainService/consensus.hpp",
    "content": "///////////////////////////////////////////////////////////////////////////////\n// Copyright (c) 2014-2018 libbitcoin-consensus developers (see COPYING).\n//\n//        GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY\n//\n///////////////////////////////////////////////////////////////////////////////\n#ifndef UC_CONSENSUS_HPP\n#define UC_CONSENSUS_HPP\n\n/**\n * API Users: Include only this header. Direct use of other headers is fragile\n * and unsupported as header organization is subject to change.\n *\n * Maintainers: Do not include this header internal to this library.\n */\n\n#include <UChainService/consensus/define.hpp>\n#include <UChainService/consensus/export.hpp>\n#include <UChainService/consensus/version.hpp>\n\n#endif\n"
  },
  {
    "path": "include/UChainService/data/databases/address_token_db.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_ADDRESS_TOKEN_DATABASE_HPP\n#define UC_DATABASE_ADDRESS_TOKEN_DATABASE_HPP\n\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory_map.hpp>\n#include <UChain/database/primitives/record_multimap.hpp>\n#include <UChainService/txs/token/token_transfer.hpp>\n#include <UChainService/txs/asset_data.hpp>\n\nusing namespace libbitcoin::chain;\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nstruct BCD_API address_token_statinfo\n{\n    /// Number of buckets used in the hashtable.\n    /// load factor = addrs / buckets\n    const size_t buckets;\n\n    /// Total number of unique addresses in the database.\n    const size_t addrs;\n\n    /// Total number of rows across all addresses.\n    const size_t rows;\n};\n\n/// This is a multimap where the key is the Bitcoin address hash,\n/// which returns several rows giving the address_token for that address.\nclass BCD_API address_token_database\n{\n  public:\n    /// Construct the database.\n    address_token_database(const boost::filesystem::path &lookup_filename,\n                           const boost::filesystem::path &rows_filename,\n                           std::shared_ptr<shared_mutex> mutex = nullptr);\n\n    /// Close the database (all threads must first be stopped).\n    ~address_token_database();\n\n    /// Initialize a new address_token database.\n    bool create();\n\n    /// Call before using the database.\n    bool start();\n\n    /// Call to signal a stop of current operations.\n    bool stop();\n\n    /// Call to unload the memory map.\n    bool close();\n\n    template <class BusinessDataType>\n    void store_output(const short_hash &key, const output_point &outpoint,\n                      uint32_t output_height, uint64_t value, uint16_t business_kd,\n                      uint32_t timestamp, BusinessDataType &asset_data)\n    {\n        auto write = [&](memory_ptr data) {\n            auto serial = make_serializer(REMAP_ADDRESS(data));\n            serial.write_byte(static_cast<uint8_t>(point_kind::output)); // 1\n            serial.write_data(outpoint.to_data());                       // 36\n            serial.write_4_bytes_little_endian(output_height);           // 4\n            serial.write_8_bytes_little_endian(value);                   // 8\n            serial.write_2_bytes_little_endian(business_kd);             // 2\n            serial.write_4_bytes_little_endian(timestamp);               // 4\n            serial.write_data(asset_data.to_data());\n        };\n        rows_multimap_.add_row(key, write);\n    }\n\n    void store_input(const short_hash &key,\n                     const output_point &inpoint, uint32_t input_height,\n                     const input_point &previous, uint32_t timestamp);\n\n    business_record::list get(const short_hash &key, size_t from_height, size_t limit) const;\n    std::shared_ptr<business_record::list> get(const std::string &address, size_t start, size_t end) const;\n    std::shared_ptr<business_record::list> get(const std::string &address, const std::string &symbol,\n                                               size_t start_height, size_t end_height, uint64_t limit, uint64_t page_number) const;\n    std::shared_ptr<business_record::list> get(size_t idx) const;\n    business_record get_record(size_t idx) const;\n\n    business_history::list get_business_history(const short_hash &key, size_t from_height) const;\n    business_history::list get_business_history(const std::string &address,\n                                                size_t from_height, business_kind kind, uint8_t status) const;\n    business_history::list get_business_history(const std::string &address,\n                                                size_t from_height, business_kind kind, uint32_t time_begin, uint32_t time_end) const;\n    std::shared_ptr<std::vector<business_history>> get_address_business_history(const std::string &address,\n                                                                                size_t from_height) const;\n\n    business_address_token::list get_tokens(const std::string &address,\n                                            size_t from_height, business_kind kind) const;\n    business_address_token::list get_tokens(const std::string &address,\n                                            size_t from_height) const;\n    business_address_message::list get_messages(const std::string &address,\n                                                size_t from_height) const;\n    business_address_token_cert::list get_token_certs(const std::string &address,\n                                                      const std::string &symbol, token_cert_type cert_type,\n                                                      size_t from_height) const;\n\n    business_history::list get_token_certs_history(const std::string &address,\n                                                   const std::string &symbol, token_cert_type cert_type,\n                                                   size_t from_height) const;\n\n    /// Delete the last row that was added to key.\n    void delete_last_row(const short_hash &key);\n\n    /// Synchonise with disk.\n    void sync();\n\n    /// Return statistical info about the database.\n    address_token_statinfo statinfo() const;\n\n  private:\n    typedef record_hash_table<short_hash> record_map;\n    typedef record_multimap<short_hash> record_multiple_map;\n\n    /// Hash table used for start index lookup for linked list by address hash.\n    memory_map lookup_file_;\n    record_hash_table_header lookup_header_;\n    record_manager lookup_manager_;\n    record_map lookup_map_;\n\n    /// List of address_token rows.\n    memory_map rows_file_;\n    record_manager rows_manager_;\n    record_list rows_list_;\n    record_multiple_map rows_multimap_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainService/data/databases/address_uid_db.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_ADDRESS_UID_DATABASE_HPP\n#define UC_DATABASE_ADDRESS_UID_DATABASE_HPP\n\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory_map.hpp>\n#include <UChain/database/primitives/record_multimap.hpp>\n#include <UChainService/txs/asset_data.hpp>\n\nusing namespace libbitcoin::chain;\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nstruct BCD_API address_uid_statinfo\n{\n    /// Number of buckets used in the hashtable.\n    /// load factor = addrs / buckets\n    const size_t buckets;\n\n    /// Total number of unique addresses in the database.\n    const size_t addrs;\n\n    /// Total number of rows across all addresses.\n    const size_t rows;\n};\n\n/// This is a multimap where the key is the Bitcoin address hash,\n/// which returns several rows giving the address_uid for that address.\nclass BCD_API address_uid_database\n{\n  public:\n    /// Construct the database.\n    address_uid_database(const boost::filesystem::path &lookup_filename,\n                         const boost::filesystem::path &rows_filename,\n                         std::shared_ptr<shared_mutex> mutex = nullptr);\n\n    /// Close the database (all threads must first be stopped).\n    ~address_uid_database();\n\n    /// Initialize a new address_uid database.\n    bool create();\n\n    /// Call before using the database.\n    bool start();\n\n    /// Call to signal a stop of current operations.\n    bool stop();\n\n    /// Call to unload the memory map.\n    bool close();\n\n    template <class BusinessDataType>\n    void store_output(const short_hash &key, const output_point &outpoint,\n                      uint32_t output_height, uint64_t value, uint16_t business_kd, uint32_t timestamp, BusinessDataType &asset_data)\n    {\n        //delete_last_row(key);\n        auto write = [&](memory_ptr data) {\n            auto serial = make_serializer(REMAP_ADDRESS(data));\n            serial.write_byte(static_cast<uint8_t>(point_kind::output)); // 1\n            serial.write_data(outpoint.to_data());                       // 36\n            serial.write_4_bytes_little_endian(output_height);           // 4\n            serial.write_8_bytes_little_endian(value);                   // 8\n            serial.write_2_bytes_little_endian(business_kd);             // 2\n            serial.write_4_bytes_little_endian(timestamp);               // 4\n            serial.write_data(asset_data.to_data());\n        };\n        rows_multimap_.add_row(key, write);\n    }\n\n    void store_input(const short_hash &key,\n                     const output_point &inpoint, uint32_t input_height,\n                     const input_point &previous, uint32_t timestamp);\n\n    business_record::list get(const short_hash &key, size_t from_height, size_t limit) const;\n    std::shared_ptr<std::vector<business_record>> get(const std::string &address, size_t start, size_t end) const;\n    std::shared_ptr<std::vector<business_record>> get(const std::string &address, const std::string &symbol,\n                                                      size_t start_height, size_t end_height, uint64_t limit, uint64_t page_number) const;\n    std::shared_ptr<std::vector<business_record>> get(size_t idx) const;\n    business_record get_record(size_t idx) const;\n    business_history::list get_business_history(const short_hash &key,\n                                                size_t from_height) const;\n    business_history::list get_business_history(const std::string &address,\n                                                size_t from_height, business_kind kind, uint8_t status) const;\n    business_history::list get_business_history(const std::string &address,\n                                                size_t from_height, business_kind kind, uint32_t time_begin, uint32_t time_end) const;\n    std::shared_ptr<std::vector<business_history>> get_address_business_history(const std::string &address,\n                                                                                size_t from_height) const;\n    business_address_uid::list get_uids(const std::string &address,\n                                        size_t from_height, business_kind kind) const;\n    business_address_uid::list get_uids(const std::string &address,\n                                        size_t from_height, size_t to_height = max_uint64) const;\n    business_address_message::list get_messages(const std::string &address,\n                                                size_t from_height) const;\n\n    //unbind the old uid with address\n    void delete_old_uid(const short_hash &key);\n\n    /// Delete the last row that was added to key.\n    void delete_last_row(const short_hash &key);\n\n    /// Synchonise with disk.\n    void sync();\n\n    /// Return statistical info about the database.\n    address_uid_statinfo statinfo() const;\n\n  private:\n    typedef record_hash_table<short_hash> record_map;\n    typedef record_multimap<short_hash> record_multiple_map;\n\n    /// Hash table used for start index lookup for linked list by address hash.\n    memory_map lookup_file_;\n    record_hash_table_header lookup_header_;\n    record_manager lookup_manager_;\n    record_map lookup_map_;\n\n    /// List of address_uid rows.\n    memory_map rows_file_;\n    record_manager rows_manager_;\n    record_list rows_list_;\n    record_multiple_map rows_multimap_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainService/data/databases/blockchain_candidate_db.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#pragma once\n\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory_map.hpp>\n#include <UChain/database/primitives/slab_hash_table.hpp>\n#include <UChain/database/primitives/slab_manager.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nclass BCD_API blockchain_candidate_database\n{\n  public:\n    /// Construct the database.\n    blockchain_candidate_database(const boost::filesystem::path &map_filename,\n                                  std::shared_ptr<shared_mutex> mutex = nullptr);\n\n    /// Close the database (all threads must first be stopped).\n    ~blockchain_candidate_database();\n\n    /// Initialize a new transaction database.\n    bool create();\n\n    /// Call before using the database.\n    bool start();\n\n    /// Call to signal a stop of current operations.\n    bool stop();\n\n    /// Call to unload the memory map.\n    bool close();\n\n    std::shared_ptr<candidate_info> get(const hash_digest &hash) const;\n\n    /// Get all token certs\n    std::shared_ptr<candidate_info::list> get_blockchain_candidates() const;\n\n    ///\n    std::shared_ptr<candidate_info> get_register_history(const std::string &candidate_symbol) const;\n    ///\n    uint64_t get_register_height(const std::string &candidate_symbol) const;\n\n    void store(candidate_info &candidate_info);\n\n    /// Delete a transaction from database.\n    void remove(const hash_digest &hash);\n\n    /// Synchronise storage with disk so things are consistent.\n    /// Should be done at the end of every block write.\n    void sync();\n\n  private:\n    typedef slab_hash_table<hash_digest> slab_map;\n\n    // Hash table used for looking up txs by hash.\n    memory_map lookup_file_;\n    slab_hash_table_header lookup_header_;\n    slab_manager lookup_manager_;\n    slab_map lookup_map_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/data/databases/blockchain_token_cert_db.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#pragma once\n\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory_map.hpp>\n#include <UChain/database/result/tx_result.hpp>\n#include <UChain/database/primitives/slab_hash_table.hpp>\n#include <UChain/database/primitives/slab_manager.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n/// This enables lookups of transactions by hash.\n/// An alternative and faster method is lookup from a unique index\n/// that is assigned upon storage.\n/// This is so we can quickly reconstruct blocks given a list of tx indexes\n/// belonging to that block. These are stored with the block.\nclass BCD_API blockchain_token_cert_database\n{\n  public:\n    /// Construct the database.\n    blockchain_token_cert_database(const boost::filesystem::path &map_filename,\n                                   std::shared_ptr<shared_mutex> mutex = nullptr);\n\n    /// Close the database (all threads must first be stopped).\n    ~blockchain_token_cert_database();\n\n    /// Initialize a new transaction database.\n    bool create();\n\n    /// Call before using the database.\n    bool start();\n\n    /// Call to signal a stop of current operations.\n    bool stop();\n\n    /// Call to unload the memory map.\n    bool close();\n\n    std::shared_ptr<token_cert> get(const hash_digest &hash) const;\n\n    /// Get all token certs\n    std::shared_ptr<std::vector<token_cert>> get_blockchain_token_certs() const;\n\n    void store(const token_cert &sp_cert);\n\n    /// Delete a transaction from database.\n    void remove(const hash_digest &hash);\n\n    /// Synchronise storage with disk so things are consistent.\n    /// Should be done at the end of every block write.\n    void sync();\n\n  private:\n    typedef slab_hash_table<hash_digest> slab_map;\n\n    // Hash table used for looking up txs by hash.\n    memory_map lookup_file_;\n    slab_hash_table_header lookup_header_;\n    slab_manager lookup_manager_;\n    slab_map lookup_map_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/data/databases/blockchain_token_db.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#pragma once\n\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory_map.hpp>\n#include <UChain/database/result/tx_result.hpp>\n#include <UChain/database/primitives/slab_hash_table.hpp>\n#include <UChain/database/primitives/slab_manager.hpp>\n#include <UChainService/txs/token/blockchain_token.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n/// This enables lookups of transactions by hash.\n/// An alternative and faster method is lookup from a unique index\n/// that is assigned upon storage.\n/// This is so we can quickly reconstruct blocks given a list of tx indexes\n/// belonging to that block. These are stored with the block.\nclass BCD_API blockchain_token_database\n{\n  public:\n    /// Construct the database.\n    blockchain_token_database(const boost::filesystem::path &map_filename,\n                              std::shared_ptr<shared_mutex> mutex = nullptr);\n\n    /// Close the database (all threads must first be stopped).\n    ~blockchain_token_database();\n\n    /// Initialize a new transaction database.\n    bool create();\n\n    /// Call before using the database.\n    bool start();\n\n    /// Call to signal a stop of current operations.\n    bool stop();\n\n    /// Call to unload the memory map.\n    bool close();\n\n    std::shared_ptr<blockchain_token> get(const hash_digest &hash) const;\n\n    ///\n    std::shared_ptr<std::vector<blockchain_token>> get_blockchain_tokens(const std::string &token_symbol = \"\") const;\n\n    uint64_t get_token_volume(const std::string &name) const;\n\n    ///\n    std::shared_ptr<blockchain_token> get_register_history(const std::string &token_symbol) const;\n    ///\n    uint64_t get_register_height(const std::string &token_symbol) const;\n    std::shared_ptr<blockchain_token::list> get_token_history(const std::string &token_symbol) const;\n\n    void store(const hash_digest &hash, const blockchain_token &sp_detail);\n\n    /// Delete a transaction from database.\n    void remove(const hash_digest &hash);\n\n    /// Synchronise storage with disk so things are consistent.\n    /// Should be done at the end of every block write.\n    void sync();\n\n  private:\n    typedef slab_hash_table<hash_digest> slab_map;\n\n    // Hash table used for looking up txs by hash.\n    memory_map lookup_file_;\n    slab_hash_table_header lookup_header_;\n    slab_manager lookup_manager_;\n    slab_map lookup_map_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/data/databases/blockchain_uid_db.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#pragma once\n\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory_map.hpp>\n#include <UChain/database/result/tx_result.hpp>\n#include <UChain/database/primitives/slab_hash_table.hpp>\n#include <UChain/database/primitives/slab_manager.hpp>\n#include <UChainService/txs/uid/blockchain_uid.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n/// This enables lookups of transactions by hash.\n/// An alternative and faster method is lookup from a unique index\n/// that is assigned upon storage.\n/// This is so we can quickly reconstruct blocks given a list of tx indexes\n/// belonging to that block. These are stored with the block.\nclass BCD_API blockchain_uid_database\n{\npublic:\n  /// Construct the database.\n  blockchain_uid_database(const boost::filesystem::path &map_filename,\n                          std::shared_ptr<shared_mutex> mutex = nullptr);\n\n  /// Close the database (all threads must first be stopped).\n  ~blockchain_uid_database();\n\n  /// Initialize a new transaction database.\n  bool create();\n\n  /// Call before using the database.\n  bool start();\n\n  /// Call to signal a stop of current operations.\n  bool stop();\n\n  /// Call to unload the memory map.\n  bool close();\n\n  std::shared_ptr<blockchain_uid> get(const hash_digest &hash) const;\n\n  ///\n  std::shared_ptr<std::vector<blockchain_uid>> get_history_uids(const hash_digest &hash) const;\n  ///\n  std::shared_ptr<std::vector<blockchain_uid>> get_blockchain_uids() const;\n\n  ///\n  std::shared_ptr<blockchain_uid> get_register_history(const std::string &uid_symbol) const;\n  ///\n  uint64_t get_register_height(const std::string &uid_symbol) const;\n\n  std::shared_ptr<std::vector<blockchain_uid>> getuids_from_address_history(\n      const std::string &address, const uint64_t &fromheight = 0, const uint64_t &toheight = max_uint64) const;\n\n  void store(const hash_digest &hash, const blockchain_uid &sp_detail);\n\n  /// Delete a transaction from database.\n  void remove(const hash_digest &hash);\n\n  /// Synchronise storage with disk so things are consistent.\n  /// Should be done at the end of every block write.\n  void sync();\n\n  //pop back uid_detail\n  std::shared_ptr<blockchain_uid> pop_uid_transfer(const hash_digest &hash);\n\nprotected:\n  /// update address status(current or old), default old\n  std::shared_ptr<blockchain_uid> update_address_status(const hash_digest &hash, uint32_t status = blockchain_uid::address_history);\n\nprivate:\n  typedef slab_hash_table<hash_digest> slab_map;\n\n  // Hash table used for looking up txs by hash.\n  memory_map lookup_file_;\n  slab_hash_table_header lookup_header_;\n  slab_manager lookup_manager_;\n  slab_map lookup_map_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/data/databases/candidate_history_db.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_CANDIDATE_HISTORY_DATABASE_HPP\n#define UC_DATABASE_CANDIDATE_HISTORY_DATABASE_HPP\n\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory_map.hpp>\n#include <UChain/database/primitives/record_multimap.hpp>\n#include <UChainService/txs/asset_data.hpp>\n\nusing namespace libbitcoin::chain;\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nstruct BCD_API candidate_history_statinfo\n{\n  /// Number of buckets used in the hashtable.\n  /// load factor = addrs / buckets\n  const size_t buckets;\n\n  /// Total number of unique addresses in the database.\n  const size_t addrs;\n\n  /// Total number of rows across all addresses.\n  const size_t rows;\n};\n\n/// This is a multimap where the key is the Bitcoin address hash,\n/// which returns several rows giving the candidate_history for that address.\nclass BCD_API candidate_history_database\n{\npublic:\n  /// Construct the database.\n  candidate_history_database(const boost::filesystem::path &lookup_filename,\n                             const boost::filesystem::path &rows_filename,\n                             std::shared_ptr<shared_mutex> mutex = nullptr);\n\n  /// Close the database (all threads must first be stopped).\n  ~candidate_history_database();\n\n  /// Initialize a new candidate_history database.\n  bool create();\n\n  /// Call before using the database.\n  bool start();\n\n  /// Call to signal a stop of current operations.\n  bool stop();\n\n  /// Call to unload the memory map.\n  bool close();\n\n  /// Delete the last row that was added to key.\n  void delete_last_row(const short_hash &key);\n\n  /// Synchonise with disk.\n  void sync();\n\n  /// Return statistical info about the database.\n  candidate_history_statinfo statinfo() const;\n\n  void store(const candidate_info &candidate_info);\n\n  std::shared_ptr<candidate_info> get(const short_hash &key) const;\n\n  std::shared_ptr<candidate_info::list> get_history_candidates_by_height(const short_hash &key,\n                                                                         uint32_t start_height = 0, uint32_t end_height = 0,\n                                                                         uint64_t limit = 0, uint64_t page_number = 0) const;\n\n  std::shared_ptr<candidate_info::list> get_history_candidates_by_time(const short_hash &key,\n                                                                       uint32_t time_begin, uint32_t time_end,\n                                                                       uint64_t limit = 0, uint64_t page_number = 0) const;\n\n  bool update_address_status(const candidate_info &candidate_info, uint8_t status);\n\nprivate:\n  typedef record_hash_table<short_hash> record_map;\n  typedef record_multimap<short_hash> record_multiple_map;\n\n  /// Hash table used for start index lookup for linked list by address hash.\n  memory_map lookup_file_;\n  record_hash_table_header lookup_header_;\n  record_manager lookup_manager_;\n  record_map lookup_map_;\n\n  /// List of candidate_history rows.\n  memory_map rows_file_;\n  record_manager rows_manager_;\n  record_list rows_list_;\n  record_multiple_map rows_multimap_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainService/data/databases/token_db.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS) \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_TOKEN_DATABASE_HPP\n#define UC_DATABASE_TOKEN_DATABASE_HPP\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory_map.hpp>\n#include <UChain/database/result/token_result.hpp>\n#include <UChain/database/primitives/slab_hash_table.hpp>\n#include <UChain/database/primitives/slab_manager.hpp>\n#include <UChain/database/databases/base_db.hpp>\n#include <UChainService/txs/token/token_detail.hpp>\n\nusing namespace libbitcoin::chain;\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n/// This enables lookups of tokens by hash.\n/// An alternative and faster method is lookup from a unique index\n/// that is assigned upon storage.\n/// This database is used to store token issued from blockchain(not store local unissued tokens)\nclass BCD_API token_database : public base_database\n{\npublic:\n  /// Construct the database.\n  token_database(const boost::filesystem::path &map_filename,\n                 std::shared_ptr<shared_mutex> mutex = nullptr);\n\n  /// Close the database (all threads must first be stopped).\n  ~token_database();\n\n  /// get token info by symbol hash\n  token_result get_token_result(const hash_digest &hash) const;\n  /// get all tokens in the blockchain\n  std::shared_ptr<std::vector<token_detail>> get_token_details() const;\n  /// Store a token in the database. Returns a unique index\n  /// which can be used to reference the token.\n  void store(const hash_digest &hash, const token_detail &sp_detail);\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainService/data/databases/wallet_address_db.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_WALLET_ADDRESS_DATABASE_HPP\n#define UC_DATABASE_WALLET_ADDRESS_DATABASE_HPP\n\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory_map.hpp>\n#include <UChain/database/primitives/record_multimap.hpp>\n#include <UChainService/txs/wallet/wallet_address.hpp>\n//#include <UChain/database/result/wallet_address_result.hpp>  // todo -- remove later\nusing namespace libbitcoin::chain;\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nstruct BCD_API wallet_address_statinfo\n{\n    /// Number of buckets used in the hashtable.\n    /// load factor = addrs / buckets\n    const size_t buckets;\n\n    /// Total number of unique addresses in the database.\n    const size_t addrs;\n\n    /// Total number of rows across all addresses.\n    const size_t rows;\n};\n\n/// This is a multimap where the key is the Bitcoin address hash,\n/// which returns several rows giving the wallet_address for that address.\nclass BCD_API wallet_address_database\n{\n  public:\n    /// Construct the database.\n    wallet_address_database(const boost::filesystem::path &lookup_filename,\n                            const boost::filesystem::path &rows_filename,\n                            std::shared_ptr<shared_mutex> mutex = nullptr);\n\n    /// Close the database (all threads must first be stopped).\n    ~wallet_address_database();\n\n    /// Initialize a new wallet_address database.\n    bool create();\n\n    /// Call before using the database.\n    bool start();\n\n    /// Call to signal a stop of current operations.\n    bool stop();\n\n    /// Call to unload the memory map.\n    bool close();\n\n    /// store wallet address into database\n    void store(const short_hash &key, const wallet_address &wallet_address);\n\n    /// get wallet address vector by key\n    wallet_address::list get(const short_hash &key) const;\n\n    /// get wallet address according by key and address\n    std::shared_ptr<wallet_address> get(const short_hash &key, const std::string &address) const;\n\n    /// Delete the last row that was added to key.\n    void delete_last_row(const short_hash &key);\n\n    void safe_store(const short_hash &key, const wallet_address &address);\n\n    /// Synchonise with disk.\n    void sync();\n\n    /// Return statistical info about the database.\n    wallet_address_statinfo statinfo() const;\n\n  private:\n    typedef record_hash_table<short_hash> record_map;\n    typedef record_multimap<short_hash> record_multiple_map;\n\n    /// Hash table used for start index lookup for linked list by address hash.\n    memory_map lookup_file_;\n    record_hash_table_header lookup_header_;\n    record_manager lookup_manager_;\n    record_map lookup_map_;\n\n    /// List of wallet_address rows.\n    memory_map rows_file_;\n    record_manager rows_manager_;\n    record_list rows_list_;\n    record_multiple_map rows_multimap_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainService/data/databases/wallet_db.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS) \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_WALLET_DATABASE_HPP\n#define UC_DATABASE_WALLET_DATABASE_HPP\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory_map.hpp>\n#include <UChain/database/result/wallet_result.hpp>\n#include <UChain/database/primitives/slab_hash_table.hpp>\n#include <UChain/database/primitives/slab_manager.hpp>\n#include <UChain/database/databases/base_db.hpp>\n\nusing namespace libbitcoin::chain;\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n/// This enables lookups of wallets by hash.\n/// An alternative and faster method is lookup from a unique index\n/// that is assigned upon storage.\n/// This is so we can quickly reconstruct blocks given a list of tx indexes\n/// belonging to that block. These are stored with the block.\nclass BCD_API wallet_database : public base_database\n{\n  public:\n    /// Construct the database.\n    wallet_database(const boost::filesystem::path &map_filename,\n                    std::shared_ptr<shared_mutex> mutex = nullptr);\n\n    /// Close the database (all threads must first be stopped).\n    ~wallet_database();\n\n    void set_admin(const std::string &name, const std::string &passwd);\n    /// get wallet info by symbol hash\n    wallet_result get_wallet_result(const hash_digest &hash) const;\n    std::shared_ptr<std::vector<libbitcoin::chain::wallet>> get_wallets() const;\n\n    /// Store a wallet in the database. Returns a unique index\n    /// which can be used to reference the wallet.\n    void store(const libbitcoin::chain::wallet &wallet);\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainService/data/databases/wallet_token_db.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS) \n *\n * This file is part of ucd.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_DATABASE_WALLET_TOKEN_DATABASE_HPP\n#define UC_DATABASE_WALLET_TOKEN_DATABASE_HPP\n\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n#include <UChain/database/memory/memory_map.hpp>\n#include <UChain/database/primitives/record_multimap.hpp>\n#include <UChainService/txs/token/token_detail.hpp>\n#include <UChainService/txs/asset_data.hpp>\n\nusing namespace libbitcoin::chain;\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nstruct BCD_API wallet_token_statinfo\n{\n    /// Number of buckets used in the hashtable.\n    /// load factor = addrs / buckets\n    const size_t buckets;\n\n    /// Total number of unique addresses in the database.\n    const size_t addrs;\n\n    /// Total number of rows across all addresses.\n    const size_t rows;\n};\n\n/// This is a multimap where the key is the Bitcoin address hash,\n/// which returns several rows giving the wallet_token for that address.\nclass BCD_API wallet_token_database\n{\n  public:\n    /// Construct the database.\n    wallet_token_database(const boost::filesystem::path &lookup_filename,\n                          const boost::filesystem::path &rows_filename,\n                          std::shared_ptr<shared_mutex> mutex = nullptr);\n\n    /// Close the database (all threads must first be stopped).\n    ~wallet_token_database();\n\n    /// Initialize a new wallet_token database.\n    bool create();\n\n    /// Call before using the database.\n    bool start();\n\n    /// Call to signal a stop of current operations.\n    bool stop();\n\n    /// Call to unload the memory map.\n    bool close();\n\n    void store(const short_hash &key, const token_detail &wallet_token);\n\n    void delete_last_row(const short_hash &key);\n\n    token_detail::list get(const short_hash &key) const;\n\n    std::shared_ptr<token_detail> get(const short_hash &key, const std::string &address) const;\n\n    /// get tokens whose status is not issued and stored in local database (not in blockchain)\n    std::shared_ptr<business_address_token::list> get_unissued_tokens(const short_hash &key) const;\n\n    /// Synchonise with disk.\n    void sync();\n\n    /// Return statistical info about the database.\n    wallet_token_statinfo statinfo() const;\n\n  private:\n    typedef record_hash_table<short_hash> record_map;\n    typedef record_multimap<short_hash> record_multiple_map;\n\n    /// Hash table used for start index lookup for linked list by address hash.\n    memory_map lookup_file_;\n    record_hash_table_header lookup_header_;\n    record_manager lookup_manager_;\n    record_map lookup_map_;\n\n    /// List of wallet_token rows.\n    memory_map rows_file_;\n    record_manager rows_manager_;\n    record_list rows_list_;\n    record_multiple_map rows_multimap_;\n};\n\n} // namespace database\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainService/txs/asset.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of UChainService.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_ASSET_HPP\n#define UC_CHAIN_ASSET_HPP\n\n#include <cstdint>\n#include <istream>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n#include <boost/variant.hpp>\n#include <UChainService/txs/token/token.hpp>\n#include <UChainService/txs/token/token_cert.hpp>\n#include <UChainService/txs/token/candidate.hpp>\n#include <UChainService/txs/token/attenuation_model.hpp>\n#include <UChainService/txs/uid/uid.hpp>\n#include <UChainService/txs/ucn/ucn.hpp>\n#include <UChainService/txs/ucn/ucn_award.hpp>\n#include <UChainService/txs/message/msg.hpp>\n\nusing namespace libbitcoin::chain;\n#define TYPE2UINT32(kd) (static_cast<typename std::underlying_type<asset::asset_type>::type>(kd))\n\n#define UCN_TYPE TYPE2UINT32(asset::asset_type::asset_ucn)\n#define UCN_AWARD_TYPE TYPE2UINT32(asset::asset_type::asset_ucn_award)\n#define UC_TOKEN_TYPE TYPE2UINT32(asset::asset_type::asset_token)\n#define MESSAGE_TYPE TYPE2UINT32(asset::asset_type::asset_message)\n#define UID_TYPE TYPE2UINT32(asset::asset_type::asset_uid)\n#define TOKEN_CERT_TYPE TYPE2UINT32(asset::asset_type::asset_token_cert)\n#define TOKEN_CANDIDATE_TYPE TYPE2UINT32(asset::asset_type::asset_candidate)\n\n#define UID_ASSET_VERIFY_VERSION TYPE2UINT32(7)\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nclass BC_API asset\n{\n  public:\n    enum class asset_type : uint32_t\n    {\n        asset_ucn, // ucn\n        asset_ucn_award,\n        asset_token,\n        asset_message,\n        asset_uid,\n        asset_token_cert,\n        asset_candidate\n    };\n\n    typedef boost::variant<\n        ucn,\n        ucn_award,\n        token,\n        blockchain_message,\n        uid,\n        token_cert,\n        candidate>\n        asset_data_type;\n\n    asset();\n\n    asset(const std::string &from_uid, const std::string &to_uid);\n\n    template <class Type>\n    asset(uint32_t type, uint32_t version, const Type &attach_data)\n        : type(type), version(version), attach(attach_data)\n    {\n    }\n\n    static asset factory_from_data(const data_chunk &data);\n    static asset factory_from_data(std::istream &stream);\n    static asset factory_from_data(reader &source);\n    static uint64_t satoshi_fixed_size();\n\n    bool from_data(const data_chunk &data);\n    bool from_data(std::istream &stream);\n    bool from_data(reader &source);\n    data_chunk to_data() const;\n    void to_data(std::ostream &stream) const;\n    void to_data(writer &sink) const;\n    std::string to_string() const;\n    bool is_valid() const;\n    bool is_valid_type() const;\n    void reset();\n    uint64_t serialized_size() const;\n\n    uint32_t get_version() const;\n    void set_version(uint32_t version);\n    uint32_t get_type() const;\n    void set_type(uint32_t type);\n\n    std::string get_to_uid() const;\n    void set_to_uid(const std::string &uid);\n\n    std::string get_from_uid() const;\n    void set_from_uid(const std::string &uid);\n\n    template <class Type>\n    void set_attach(const Type &attach)\n    {\n        this->attach = attach;\n    };\n    asset_data_type &get_attach();\n    const asset_data_type &get_attach() const;\n\n  private:\n    uint32_t version;\n    uint32_t type;\n    std::string touid;\n    std::string fromuid;\n    asset_data_type attach;\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainService/txs/asset_data.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_BUSINESS_DATA_HPP\n#define UC_CHAIN_BUSINESS_DATA_HPP\n\n#include <cstdint>\n#include <istream>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n#include <boost/variant.hpp>\n#include <UChainService/txs/token/token_detail.hpp>\n#include <UChainService/txs/token/token_transfer.hpp>\n#include <UChainService/txs/token/token_cert.hpp>\n#include <UChainService/txs/token/candidate.hpp>\n#include <UChainService/txs/uid/uid_detail.hpp>\n#include <UChainService/txs/ucn/ucn.hpp>\n#include <UChainService/txs/ucn/ucn_award.hpp>\n#include <UChainService/txs/message/msg.hpp>\n\n#define KIND2UINT16(kd) (static_cast<typename std::underlying_type<business_kind>::type>(kd))\n// 0 -- unspent  1 -- confirmed  2 -- local token not issued\n#define TOKEN_STATUS_UNSPENT 0   // in blockchain\n#define TOKEN_STATUS_CONFIRMED 1 // in blockchain\n#define TOKEN_STATUS_UNISSUED 2  // in local database\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nenum class business_kind : uint16_t\n{\n    ucn = 0,\n    token_issue = 1,\n    token_transfer = 2,\n    message = 3,\n    ucn_award = 4, // store to address_token database\n    uid_register = 5,\n    uid_transfer = 6,\n    token_cert = 7,\n    candidate = 8,\n    unknown = 0xffff\n};\n\n// 0 -- unspent  1 -- confirmed  2 -- local token not issued\nenum business_status : uint8_t\n{\n    unspent = 0,   // in blockchain but unspent\n    confirmed = 1, // in blockchain confirmed\n    unissued = 2,  //  in local database ,special for token related business\n    unknown = 0xff\n};\n\nclass BC_API asset_data\n{\n  public:\n    typedef boost::variant<\n        ucn,\n        ucn_award,\n        token_detail,\n        token_transfer,\n        token_cert,\n        candidate,\n        blockchain_message,\n        uid_detail>\n        asset_data_type;\n\n    static asset_data factory_from_data(const data_chunk &data);\n    static asset_data factory_from_data(std::istream &stream);\n    static asset_data factory_from_data(reader &source);\n    static uint64_t satoshi_fixed_size();\n\n    bool from_data(const data_chunk &data);\n    bool from_data(std::istream &stream);\n    bool from_data(reader &source);\n    data_chunk to_data();\n    void to_data(std::ostream &stream);\n    void to_data(writer &sink);\n#if UC_DEBUG\n    std::string to_string();\n#endif\n    bool is_valid() const;\n    bool is_valid_type() const;\n    void reset();\n    uint64_t serialized_size();\n    business_kind get_kind_value() const;\n    const asset_data_type &get_data() const;\n    uint32_t get_timestamp() const;\n\n  private:\n    business_kind kind; // 2 size\n    uint32_t timestamp; // 4 size\n    asset_data_type data;\n};\n\n/*************************************business assisant class begin******************************************/\nclass BC_API business_record\n{\n  public:\n    typedef std::vector<business_record> list;\n\n    // The type of point (output or spend).\n    point_kind kind;\n\n    /// The point that identifies the record.\n    chain::point point;\n\n    /// The height of the point.\n    uint64_t height;\n\n    union {\n        /// If output, then satoshi value of output.\n        uint64_t value;\n\n        /// If spend, then checksum hash of previous output point\n        /// To match up this row with the output, recompute the\n        /// checksum from the output row with spend_checksum(row.point)\n        uint64_t previous_checksum;\n    } val_chk_sum;\n\n    asset_data data;\n\n#ifdef UC_DEBUG\n    // just used for debug code in block_chain_impl_test.cpp\n    std::string to_string()\n    {\n        std::ostringstream ss;\n\n        ss << \"\\t kind = \" << KIND2UINT16(kind)\n           << \"\\t point = \" << point.to_string() << \"\\n\"\n           << \"\\t height = \" << height\n           << \"\\t data = \" << data.to_string() << \"\\n\";\n\n        return ss.str();\n    }\n#endif\n};\n\nclass BC_API business_history\n{\n  public:\n    typedef std::vector<business_history> list;\n    /// If there is no output this is null_hash:max.\n    output_point output;\n    uint64_t output_height;\n\n    /// The satoshi value of the output.\n    uint64_t value;\n\n    /// If there is no spend this is null_hash:max.\n    input_point spend;\n\n    union {\n        /// The height of the spend or max if no spend.\n        uint64_t spend_height;\n\n        /// During expansion this value temporarily doubles as a checksum.\n        uint64_t temporary_checksum;\n    };\n    uint32_t status; // 0 -- unspend  1 -- confirmed\n    asset_data data; // for output only\n\n#ifdef UC_DEBUG\n    // just used for debug code in block_chain_impl_test.cpp\n    std::string to_string()\n    {\n        std::ostringstream ss;\n\n        ss << \"\\t output = \" << output.to_string()\n           << \"\\t output_height = \" << output_height\n           << \"\\t value = \" << value << \"\\n\"\n           << \"\\t spend = \" << spend.to_string()\n           << \"\\t data = \" << data.to_string() << \"\\n\";\n\n        return ss.str();\n    }\n#endif\n};\nclass BC_API business_address_token\n{\n  public:\n    typedef std::vector<business_address_token> list;\n\n    std::string address;\n    uint8_t status; // 0 -- unspent  1 -- confirmed  2 -- local token not issued\n    uint64_t quantity;\n    token_detail detail;\n\n#ifdef UC_DEBUG\n    // just used for unit test in block_chain_impl_test.cpp\n    std::string to_string()\n    {\n        std::ostringstream ss;\n\n        ss << \"\\t address = \" << address\n           << \"\\t status = \" << status\n           << \"\\t quantity = \" << quantity << \"\\n\"\n           << \"\\t detail = \" << detail.to_string() << \"\\n\";\n\n        return ss.str();\n    }\n#endif\n};\n\nclass BC_API business_address_token_cert\n{\n  public:\n    typedef std::vector<business_address_token_cert> list;\n\n    std::string address;\n    uint8_t status; // 0 -- unspent  1 -- confirmed  2 -- local token not issued\n    token_cert certs;\n\n#ifdef UC_DEBUG\n    // just used for unit test in block_chain_impl_test.cpp\n    std::string to_string()\n    {\n        std::ostringstream ss;\n\n        ss << \"\\t address = \" << address\n           << \"\\t status = \" << status\n           << \"\\t certs = \" << certs.to_string() << \"\\n\";\n\n        return ss.str();\n    }\n#endif\n};\n\nclass BC_API business_address_candidate\n{\n  public:\n    typedef std::vector<business_address_candidate> list;\n\n    std::string address;\n    uint8_t status; // 0 -- unspent  1 -- confirmed  2 -- local token not issued\n    libbitcoin::chain::candidate candidate;\n\n#ifdef UC_DEBUG\n    // just used for unit test in block_chain_impl_test.cpp\n    std::string to_string()\n    {\n        std::ostringstream ss;\n\n        ss << \"\\t address = \" << address\n           << \"\\t status = \" << std::to_string(status)\n           << \"\\t candidate = \" << candidate.to_string() << \"\\n\";\n\n        return ss.str();\n    }\n#endif\n};\n\nclass BC_API business_address_uid\n{\n  public:\n    typedef std::vector<business_address_uid> list;\n\n    std::string address;\n    uint8_t status; // 0 -- unspent  1 -- confirmed  2 -- local token not issued\n    uid_detail detail;\n\n#ifdef UC_DEBUG\n    // just used for unit test in block_chain_impl_test.cpp\n    std::string to_string()\n    {\n        std::ostringstream ss;\n\n        ss << \"\\t address = \" << address\n           << \"\\t status = \" << status\n           << \"\\t detail = \" << detail.to_string() << \"\\n\";\n\n        return ss.str();\n    }\n#endif\n};\n\nclass BC_API business_address_message\n{\n  public:\n    typedef std::vector<business_address_message> list;\n\n    std::string address;\n    uint8_t status;\n    chain::blockchain_message msg;\n#ifdef UC_DEBUG\n    // just used for unit test in block_chain_impl_test.cpp\n    std::string to_string()\n    {\n        std::ostringstream ss;\n\n        ss << \"\\t address = \" << address\n           << \"\\t status = \" << status\n           << \"\\t message = \" << msg.to_string() << \"\\n\";\n\n        return ss.str();\n    }\n#endif\n};\n\n/****************************************business assisant class end*******************************************/\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainService/txs/token/attenuation_model.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChainService.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_ASSET_TOKEN_ATTENUATION_MODEL_HPP\n#define UC_CHAIN_ASSET_TOKEN_ATTENUATION_MODEL_HPP\n\n#include <cstdint>\n#include <UChain/coin/chain/point.hpp>\n#include <UChain/coin/chain/script/script.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/error.hpp>\n\nusing namespace libbitcoin::chain;\n\n// forward declaration\nnamespace libbitcoin\n{\nnamespace blockchain\n{\nclass block_chain_impl;\nclass validate_tx_engine;\n} // namespace blockchain\n} // namespace libbitcoin\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nclass attenuation_model\n{\n  public:\n    enum class model_type : uint8_t\n    {\n        none = 0,\n        fixed_quantity = 1,\n        custom = 2,\n        fixed_inflation = 3,\n        unused1 = 4,\n        unused2 = 5,\n        unused3 = 6,\n        unused4 = 7,\n        invalid = 8\n    };\n\n    attenuation_model(const std::string &param, bool is_init = false);\n\n    static uint8_t get_first_unused_index();\n    static uint8_t to_index(model_type model);\n    static model_type from_index(uint32_t index);\n\n    static bool check_model_index(uint32_t index);\n    static bool validate_model_param(const data_chunk &param, uint64_t total_amount);\n    static code check_model_param(const blockchain::validate_tx_engine &);\n    static bool check_model_param_format(const data_chunk &param);\n    static bool check_model_param(const data_chunk &param, uint64_t total_amount);\n    static bool check_model_param_initial(std::string &param, uint64_t total_amount, bool is_init = false);\n    static bool check_model_param_un(attenuation_model &parser);\n    static bool check_model_param_common(attenuation_model &parser);\n    static bool check_model_param_uc_uq(attenuation_model &parser);\n    static bool check_model_param_inflation(attenuation_model &parser, uint64_t total_amount);\n    static bool check_model_param_initial_fixed_inflation(\n        std::string &param, uint64_t total_amount, attenuation_model &parser, bool is_init = false);\n    static bool check_model_param_immutable(const data_chunk &previous, const data_chunk &current);\n    static uint64_t get_available_token_amount(uint64_t token_amount, uint64_t diff_height,\n                                               const data_chunk &model_param, std::shared_ptr<data_chunk> new_param_ptr = nullptr);\n    static uint64_t get_diff_height(const data_chunk &prev_param, const data_chunk &param);\n\n    const std::string &get_model_param() const;\n    data_chunk get_new_model_param(uint64_t PN, uint64_t LH) const;\n\n    // mutable params of the model\n    uint64_t get_current_period_number() const; // PN  current period number\n    uint64_t get_latest_lock_height() const;    // LH  latest lock height\n\n    // immutable params of the model\n    model_type get_model_type() const;                            // TYPE attenuation model type\n    uint64_t get_locked_quantity() const;                         // LQ  total locked quantity\n    uint64_t get_locked_period() const;                           // LP  total locked period\n    uint64_t get_unlock_number() const;                           // UN  total unlock numbers\n    uint64_t get_inflation_rate() const;                          // IR  inflation rate\n    const std::vector<uint64_t> &get_unlock_cycles() const;       // UCt size()==1 means fixed cycle\n    const std::vector<uint64_t> &get_unlocked_quantities() const; // UQt size()==1 means fixed quantity\n\n    static bool is_multi_value_key(const std::string &key);\n    static std::string get_name_of_key(const std::string &key);\n    static std::string get_key_of_name(const std::string &name);\n\n  private:\n    class impl;\n    std::unique_ptr<impl> pimpl;\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainService/txs/token/blockchain_token.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of UChainService.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#pragma once\n\n#include <cstdint>\n#include <istream>\n#include <vector>\n#include <UChain/coin/chain/point.hpp>\n#include <UChain/coin/chain/script/script.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n#include <UChainService/txs/token/token_detail.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nclass BC_API blockchain_token\n{\n  public:\n    typedef std::vector<blockchain_token> list;\n    blockchain_token();\n    blockchain_token(uint32_t version, const output_point &tx_point,\n                     uint64_t height, const token_detail &token);\n    static blockchain_token factory_from_data(const data_chunk &data);\n    static blockchain_token factory_from_data(std::istream &stream);\n    static blockchain_token factory_from_data(reader &source);\n    static uint64_t satoshi_fixed_size();\n\n    bool from_data(const data_chunk &data);\n    bool from_data(std::istream &stream);\n    bool from_data(reader &source);\n    data_chunk to_data() const;\n    void to_data(std::ostream &stream) const;\n    void to_data(writer &sink) const;\n\n#ifdef UC_DEBUG\n    std::string to_string() const;\n#endif\n\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size() const;\n    const uint32_t &get_version() const;\n    void set_version(const uint32_t &version_);\n    const output_point &get_tx_point() const;\n    void set_tx_point(const output_point &tx_point_);\n    const uint64_t &get_height() const;\n    void set_height(const uint64_t &height_);\n    const token_detail &get_token() const;\n    void set_token(const token_detail &token_);\n\n  private:\n    uint32_t version_;\n    output_point tx_point_;\n    uint64_t height_;\n    token_detail token_;\n};\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/txs/token/candidate.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_ATTACH_TOKEN_CANDIDATE_HPP\n#define UC_CHAIN_ATTACH_TOKEN_CANDIDATE_HPP\n\n#include <cstdint>\n#include <istream>\n#include <set>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/error.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\n#define CANDIDATE_STATUS2UINT32(kd) (static_cast<typename std::underlying_type<candidate::candidate_status>::type>(kd))\n\n#define CANDIDATE_STATUS_NONE CANDIDATE_STATUS2UINT32(candidate::candidate_status::candidate_status_none)\n#define CANDIDATE_STATUS_REGISTER CANDIDATE_STATUS2UINT32(candidate::candidate_status::candidate_status_register)\n#define CANDIDATE_STATUS_TRANSFER CANDIDATE_STATUS2UINT32(candidate::candidate_status::candidate_status_transfer)\n#define CANDIDATE_STATUS_MAX CANDIDATE_STATUS2UINT32(candidate::candidate_status::candidate_status_max)\n#define CANDIDATE_STATUS_HISTORY CANDIDATE_STATUS2UINT32(candidate::candidate_status::candidate_status_history)\n#define CANDIDATE_STATUS_CURRENT CANDIDATE_STATUS2UINT32(candidate::candidate_status::candidate_status_current)\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nBC_CONSTEXPR size_t TOKEN_CANDIDATE_SYMBOL_FIX_SIZE = 64;\nBC_CONSTEXPR size_t TOKEN_CANDIDATE_ADDRESS_FIX_SIZE = 64;\nBC_CONSTEXPR size_t TOKEN_CANDIDATE_CONTENT_FIX_SIZE = 256;\nBC_CONSTEXPR size_t TOKEN_CANDIDATE_STATUS_FIX_SIZE = 1;\n\nBC_CONSTEXPR size_t TOKEN_CANDIDATE_FIX_SIZE = (TOKEN_CANDIDATE_SYMBOL_FIX_SIZE + TOKEN_CANDIDATE_ADDRESS_FIX_SIZE + TOKEN_CANDIDATE_CONTENT_FIX_SIZE + TOKEN_CANDIDATE_STATUS_FIX_SIZE);\n\nBC_CONSTEXPR size_t TOKEN_CANDIDATE_TRANSFER_FIX_SIZE = (TOKEN_CANDIDATE_FIX_SIZE - TOKEN_CANDIDATE_CONTENT_FIX_SIZE);\n\n// output_height; timestamp; to_uid; candidate;\nBC_CONSTEXPR size_t TOKEN_CANDIDATE_INFO_FIX_SIZE = 4 + 4 + 64 + TOKEN_CANDIDATE_TRANSFER_FIX_SIZE;\n\nclass BC_API candidate\n{\n  public:\n    typedef std::vector<candidate> list;\n\n    enum class candidate_status : uint8_t\n    {\n        candidate_status_none = 0,\n        candidate_status_register = 1,\n        candidate_status_transfer = 2,\n        candidate_status_history = 3,\n        candidate_status_current = 4,\n        candidate_status_max = 5\n\n    };\n\n    candidate();\n    candidate(const std::string &symbol, const std::string &address,\n              const std::string &content, uint8_t status = 0);\n\n    void reset();\n    bool is_valid() const;\n    bool operator<(const candidate &other) const;\n\n    static candidate factory_from_data(const data_chunk &data);\n    static candidate factory_from_data(std::istream &stream);\n    static candidate factory_from_data(reader &source);\n\n    bool from_data(const data_chunk &data);\n    bool from_data(std::istream &stream);\n    bool from_data(reader &source);\n    data_chunk to_short_data() const;\n    data_chunk to_data() const;\n    void to_data(std::ostream &stream) const;\n    void to_data(writer &sink) const;\n\n    std::string to_string() const;\n    uint64_t serialized_size() const;\n    uint64_t calc_size() const;\n    uint64_t get_max_serialized_size() const;\n\n    const std::string &get_symbol() const;\n    void set_symbol(const std::string &symbol);\n\n    const std::string &get_address() const;\n    void set_address(const std::string &address);\n\n    void set_content(const std::string &content);\n    const std::string &get_content() const;\n\n    void set_status(uint8_t status);\n    uint8_t get_status() const;\n    std::string get_status_name() const;\n\n    static std::string status_to_string(uint8_t status);\n\n    bool is_register_status() const;\n    bool is_transfer_status() const;\n    bool is_invalid_status() const;\n\n  private:\n    // NOTICE: ref CTokenCandidate in transaction.h\n    // candidate and CTokenCandidate should have the same size and order.\n    uint8_t status_;      // token status\n    std::string symbol_;  // token name/symbol\n    std::string address_; // address that owned token cert\n    std::string content_; // the content of the token, only serialization in register.\n};\n\nstruct BC_API candidate_info\n{\n    typedef std::vector<candidate_info> list;\n    uint32_t output_height;\n    uint32_t timestamp;\n    uint32_t vote;\n    //uint8_t status;\n    std::string to_uid;\n    libbitcoin::chain::candidate candidate;\n\n    uint64_t serialized_size() const;\n    void reset();\n    bool operator<(const candidate_info &other) const;\n\n    static candidate_info factory_from_data(reader &source);\n    bool from_data(reader &source);\n    data_chunk to_data() const;\n    data_chunk to_short_data() const;\n    // const uint8_t& get_status();\n    // void set_status(const uint8_t&  st);\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainService/txs/token/token.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of UChainService.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_ATTACH_TOKEN_HPP\n#define UC_CHAIN_ATTACH_TOKEN_HPP\n\n#include <cstdint>\n#include <istream>\n#include <vector>\n#include <UChain/coin/chain/point.hpp>\n#include <UChain/coin/chain/script/script.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n#include <boost/variant.hpp>\n#include <UChainService/txs/token/token_detail.hpp>\n#include <UChainService/txs/token/token_transfer.hpp>\n\nusing namespace libbitcoin::chain;\n\n#define TOKEN_STATUS2UINT32(kd) (static_cast<typename std::underlying_type<token::token_status>::type>(kd))\n\n#define TOKEN_DETAIL_TYPE TOKEN_STATUS2UINT32(token::token_status::token_locked)\n#define TOKEN_TRANSFERABLE_TYPE TOKEN_STATUS2UINT32(token::token_status::token_transferable)\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nclass BC_API token\n{\n  public:\n    enum class token_status : uint32_t\n    {\n        token_none,\n        token_locked,\n        token_transferable,\n    };\n    typedef boost::variant<token_detail, token_transfer> token_data_type;\n\n    token();\n    token(uint32_t status, const token_detail &detail);\n    token(uint32_t status, const token_transfer &detail);\n    static token factory_from_data(const data_chunk &data);\n    static token factory_from_data(std::istream &stream);\n    static token factory_from_data(reader &source);\n    static uint64_t satoshi_fixed_size();\n\n    bool from_data(const data_chunk &data);\n    bool from_data(std::istream &stream);\n    bool from_data(reader &source);\n    data_chunk to_data() const;\n    void to_data(std::ostream &stream) const;\n    void to_data(writer &sink) const;\n    std::string to_string() const;\n    bool is_valid_type() const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size() const;\n    uint32_t get_status() const;\n    void set_status(uint32_t status);\n    void set_data(const token_detail &detail);\n    void set_data(const token_transfer &detail);\n    token_data_type &get_data();\n    const token_data_type &get_data() const;\n\n  private:\n    uint32_t status;\n    token_data_type data;\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainService/txs/token/token_cert.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_ATTACH_TOKEN_CERT_HPP\n#define UC_CHAIN_ATTACH_TOKEN_CERT_HPP\n\n#include <cstdint>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/error.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\n#define TOKEN_CERT_STATUS2UINT32(kd) (static_cast<typename std::underlying_type<token_cert::token_cert_status>::type>(kd))\n\n#define TOKEN_CERT_NORMAL_TYPE TOKEN_CERT_STATUS2UINT32(token_cert::token_cert_status::token_cert_normal)\n#define TOKEN_CERT_ISSUE_TYPE TOKEN_CERT_STATUS2UINT32(token_cert::token_cert_status::token_cert_issue)\n#define TOKEN_CERT_TRANSFER_TYPE TOKEN_CERT_STATUS2UINT32(token_cert::token_cert_status::token_cert_transfer)\n#define TOKEN_CERT_AUTOISSUE_TYPE TOKEN_CERT_STATUS2UINT32(token_cert::token_cert_status::token_cert_autoissue)\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nBC_CONSTEXPR size_t TOKEN_CERT_SYMBOL_FIX_SIZE = 64;\nBC_CONSTEXPR size_t TOKEN_CERT_OWNER_FIX_SIZE = 64;\nBC_CONSTEXPR size_t TOKEN_CERT_ADDRESS_FIX_SIZE = 64;\nBC_CONSTEXPR size_t TOKEN_CERT_TYPE_FIX_SIZE = 4;\nBC_CONSTEXPR size_t TOKEN_CERT_STATUS_FIX_SIZE = 1;\n\nBC_CONSTEXPR size_t TOKEN_CERT_FIX_SIZE = (TOKEN_CERT_SYMBOL_FIX_SIZE + TOKEN_CERT_OWNER_FIX_SIZE + TOKEN_CERT_ADDRESS_FIX_SIZE + TOKEN_CERT_TYPE_FIX_SIZE + TOKEN_CERT_STATUS_FIX_SIZE);\n\nusing token_cert_type = uint32_t;\nnamespace token_cert_ns\n{\nconstexpr token_cert_type none = 0;\nconstexpr token_cert_type issue = 1;\nconstexpr token_cert_type domain = 2;\nconstexpr token_cert_type naming = 3;\n\nconstexpr token_cert_type custom = 0x80000000;\nconstexpr token_cert_type marriage = custom + 0;\nconstexpr token_cert_type kyc = custom + 1;\n} // namespace token_cert_ns\n\nclass BC_API token_cert\n{\n  public:\n    typedef std::vector<token_cert> list;\n\n    enum class token_cert_status : uint8_t\n    {\n        token_cert_normal = 0,\n        token_cert_issue = 1,\n        token_cert_transfer = 2,\n        token_cert_autoissue = 3,\n    };\n\n    token_cert();\n    token_cert(const std::string &symbol, const std::string &owner,\n               const std::string &address, token_cert_type certs);\n\n    void reset();\n    bool is_valid() const;\n    bool operator<(const token_cert &other) const;\n\n    static token_cert factory_from_data(const data_chunk &data);\n    static token_cert factory_from_data(std::istream &stream);\n    static token_cert factory_from_data(reader &source);\n\n    bool from_data(const data_chunk &data);\n    bool from_data(std::istream &stream);\n    bool from_data(reader &source);\n    data_chunk to_data() const;\n    void to_data(std::ostream &stream) const;\n    void to_data(writer &sink) const;\n\n    std::string to_string() const;\n    uint64_t serialized_size() const;\n    uint64_t calc_size() const;\n\n    const std::string &get_symbol() const;\n    void set_symbol(const std::string &symbol);\n\n    uint8_t get_status() const;\n    void set_status(uint8_t status);\n    bool is_newly_generated() const;\n\n    void set_owner(const std::string &owner);\n    const std::string &get_owner() const;\n\n    void set_address(const std::string &owner);\n    const std::string &get_address() const;\n\n    token_cert_type get_certs() const;\n    void set_certs(token_cert_type certs);\n\n    token_cert_type get_type() const;\n    void set_type(token_cert_type cert_type);\n    std::string get_type_name() const;\n\n    // auxiliary functions\n    std::string get_key() const;\n\n    static const std::map<token_cert_type, std::string> &get_type_name_map();\n    static std::string get_type_name(token_cert_type cert_type);\n    static bool test_certs(const std::vector<token_cert_type> &total, const std::vector<token_cert_type> &parts);\n    static bool test_certs(const std::vector<token_cert_type> &certs, token_cert_type cert_type);\n\n    static std::string get_domain(const std::string &symbol);\n    static bool is_valid_domain(const std::string &domain);\n    static std::string get_key(const std::string &symbol, const token_cert_type &bit);\n\n  private:\n    // NOTICE: ref CTokenCert in transaction.h\n    // token_cert and CTokenCert should have the same size and order.\n    std::string symbol_;        // token name/symbol\n    std::string owner_;         // token cert owner, an digital identity\n    std::string address_;       // address that owned token cert\n    token_cert_type cert_type_; // token certs\n    uint8_t status_;            // token status\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainService/txs/token/token_detail.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of UChainService.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_ASSET_TOKEN_DETAIL_HPP\n#define UC_CHAIN_ASSET_TOKEN_DETAIL_HPP\n\n#include <cstdint>\n#include <istream>\n#include <vector>\n#include <UChain/coin/chain/point.hpp>\n#include <UChain/coin/chain/script/script.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n#include \"token_cert.hpp\"\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nBC_CONSTEXPR size_t TOKEN_DETAIL_SYMBOL_FIX_SIZE = 64;\nBC_CONSTEXPR size_t TOKEN_DETAIL_MAX_SUPPLY_FIX_SIZE = 8;\nBC_CONSTEXPR size_t TOKEN_DETAIL_TOKEN_TYPE_FIX_SIZE = 4;\nBC_CONSTEXPR size_t TOKEN_DETAIL_ISSUER_FIX_SIZE = 64;\nBC_CONSTEXPR size_t TOKEN_DETAIL_ADDRESS_FIX_SIZE = 64;\nBC_CONSTEXPR size_t TOKEN_DETAIL_DESCRIPTION_FIX_SIZE = 64;\n\nBC_CONSTEXPR size_t TOKEN_DETAIL_FIX_SIZE = TOKEN_DETAIL_SYMBOL_FIX_SIZE + TOKEN_DETAIL_MAX_SUPPLY_FIX_SIZE + TOKEN_DETAIL_TOKEN_TYPE_FIX_SIZE + TOKEN_DETAIL_ISSUER_FIX_SIZE + TOKEN_DETAIL_ADDRESS_FIX_SIZE + TOKEN_DETAIL_DESCRIPTION_FIX_SIZE;\n\nclass BC_API token_detail\n{\n  public:\n    typedef std::vector<token_detail> list;\n\n    static BC_CONSTEXPR uint8_t forbidden_secondaryissue_threshold = 0;\n    static BC_CONSTEXPR uint8_t freely_secondaryissue_threshold = 127;\n\n    token_detail();\n    token_detail(\n        const std::string &symbol, uint64_t maximum_supply,\n        uint8_t decimal_number, uint8_t threshold, const std::string &issuer,\n        const std::string &address, const std::string &description);\n\n    static token_detail factory_from_data(const data_chunk &data);\n    static token_detail factory_from_data(std::istream &stream);\n    static token_detail factory_from_data(reader &source);\n    static uint64_t satoshi_fixed_size();\n    bool from_data(const data_chunk &data);\n    bool from_data(std::istream &stream);\n    bool from_data(reader &source);\n    data_chunk to_data() const;\n    void to_data(std::ostream &stream) const;\n    void to_data(writer &sink) const;\n\n    bool operator<(const token_detail &other) const;\n    std::string to_string() const;\n\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size() const;\n    const std::string &get_symbol() const;\n    void set_symbol(const std::string &symbol);\n    uint64_t get_maximum_supply() const;\n    void set_maximum_supply(uint64_t maximum_supply);\n    uint8_t get_decimal_number() const;\n    void set_decimal_number(uint8_t decimal_number);\n    const std::string &get_issuer() const;\n    void set_issuer(const std::string &issuer);\n    const std::string &get_address() const;\n    void set_address(const std::string &address);\n    const std::string &get_description() const;\n    void set_description(const std::string &description);\n    std::vector<token_cert_type> get_token_cert_mask() const;\n\n    bool is_token_secondaryissue() const;\n    void set_token_secondaryissue();\n    uint8_t get_secondaryissue_threshold() const;\n    void set_secondaryissue_threshold(uint8_t share);\n\n    bool is_secondaryissue_threshold_value_ok() const;\n    bool is_secondaryissue_legal() const;\n\n    static bool is_secondaryissue_forbidden(uint8_t threshold);\n    static bool is_secondaryissue_freely(uint8_t threshold);\n    static bool is_secondaryissue_threshold_value_ok(uint8_t threshold);\n    static bool is_secondaryissue_legal(uint8_t threshold);\n    static bool is_secondaryissue_owns_enough(uint64_t own, uint64_t total, uint8_t threshold);\n\n  private:\n    // NOTICE: ref CTokenDetail in transaction.h\n    // token_detail and CTokenDetail should have the same size and order.\n    // uint32_t token_type in CTokenDetail is divided into four uint8_t parts here.\n    std::string symbol;\n    uint64_t maximum_supply;\n    uint8_t decimal_number;\n    uint8_t secondaryissue_threshold;\n    uint8_t unused2;\n    uint8_t unused3;\n    std::string issuer;\n    std::string address;\n    std::string description;\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainService/txs/token/token_transfer.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of UChainService.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_ASSET_TOKEN_TRANSFER_HPP\n#define UC_CHAIN_ASSET_TOKEN_TRANSFER_HPP\n\n#include <cstdint>\n#include <istream>\n#include <vector>\n#include <tuple>\n#include <UChain/coin/chain/point.hpp>\n#include <UChain/coin/chain/script/script.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n#include <UChain/coin/chain/history.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nBC_CONSTEXPR size_t TOKEN_TRANSFER_SYMBOL_FIX_SIZE = 64;\nBC_CONSTEXPR size_t TOKEN_TRANSFER_QUANTITY_FIX_SIZE = 8;\n\nBC_CONSTEXPR size_t TOKEN_TRANSFER_FIX_SIZE = TOKEN_TRANSFER_SYMBOL_FIX_SIZE + TOKEN_TRANSFER_QUANTITY_FIX_SIZE;\n\nstruct token_balances\n{\n    typedef std::vector<token_balances> list;\n    std::string symbol;\n    std::string address;\n    uint64_t unspent_token;\n    uint64_t locked_token;\n\n    // for sort\n    bool operator<(const token_balances &other) const;\n};\n\nstruct token_deposited_balance\n{\n    token_deposited_balance(const std::string &symbol_,\n                            const std::string &address_,\n                            const std::string &tx_hash_,\n                            uint64_t tx_height_)\n        : symbol(symbol_), address(address_), tx_hash(tx_hash_), tx_height(tx_height_), unspent_token(0), locked_token(0)\n    {\n    }\n\n    std::string symbol;\n    std::string address;\n    std::string tx_hash;\n    std::string model_param;\n    uint64_t tx_height;\n    uint64_t unspent_token;\n    uint64_t locked_token;\n\n    // for sort\n    bool operator<(const token_deposited_balance &other) const\n    {\n        typedef std::tuple<std::string, uint64_t> cmp_tuple;\n        return cmp_tuple(symbol, tx_height) < cmp_tuple(other.symbol, other.tx_height);\n    }\n\n    typedef std::vector<token_deposited_balance> list;\n};\n\nclass BC_API token_transfer\n{\n  public:\n    token_transfer();\n    token_transfer(const std::string &symbol, uint64_t quantity);\n    static token_transfer factory_from_data(const data_chunk &data);\n    static token_transfer factory_from_data(std::istream &stream);\n    static token_transfer factory_from_data(reader &source);\n    static uint64_t satoshi_fixed_size();\n\n    bool from_data(const data_chunk &data);\n    bool from_data(std::istream &stream);\n    bool from_data(reader &source);\n    data_chunk to_data() const;\n    void to_data(std::ostream &stream) const;\n    void to_data(writer &sink) const;\n\n    std::string to_string() const;\n\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size() const;\n    const std::string &get_symbol() const;\n    void set_symbol(const std::string &symbol);\n    uint64_t get_quantity() const;\n    void set_quantity(uint64_t quantity);\n\n  private:\n    std::string symbol; // symbol  -- in block\n    uint64_t quantity;  // -- in block\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainService/txs/ucn/ucn.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of UChainService.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_ATTACH_UCN_HPP\n#define UC_CHAIN_ATTACH_UCN_HPP\n\n#include <cstdint>\n#include <istream>\n//#include <UChain/coin/chain/point.hpp>\n//#include <UChain/coin/chain/script/script.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nBC_CONSTEXPR size_t UCN_FIX_SIZE = 8;\n\nclass BC_API ucn\n{\n  public:\n    ucn();\n    ucn(uint64_t value);\n    static ucn factory_from_data(const data_chunk &data);\n    static ucn factory_from_data(std::istream &stream);\n    static ucn factory_from_data(reader &source);\n    static uint64_t satoshi_fixed_size();\n\n    bool from_data(const data_chunk &data);\n    bool from_data(std::istream &stream);\n    bool from_data(reader &source);\n    data_chunk to_data() const;\n    void to_data(std::ostream &stream) const;\n    void to_data(writer &sink) const;\n    std::string to_string() const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size() const;\n    uint64_t get_value() const;\n    void set_value(uint64_t value);\n\n  private:\n    uint64_t value;\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainService/txs/ucn/ucn_award.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of UChainService.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_ATTACH_UCN_AWARD_HPP\n#define UC_CHAIN_ATTACH_UCN_AWARD_HPP\n\n#include <cstdint>\n#include <istream>\n//#include <UChain/coin/chain/point.hpp>\n//#include <UChain/coin/chain/script/script.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nBC_CONSTEXPR size_t UCN_AWARD_FIX_SIZE = 8;\n\nclass BC_API ucn_award\n{\n  public:\n    ucn_award();\n    ucn_award(uint64_t height);\n    static ucn_award factory_from_data(const data_chunk &data);\n    static ucn_award factory_from_data(std::istream &stream);\n    static ucn_award factory_from_data(reader &source);\n    static uint64_t satoshi_fixed_size();\n\n    bool from_data(const data_chunk &data);\n    bool from_data(std::istream &stream);\n    bool from_data(reader &source);\n    data_chunk to_data() const;\n    void to_data(std::ostream &stream) const;\n    void to_data(writer &sink) const;\n    std::string to_string() const;\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size() const;\n    uint64_t get_height() const;\n    void set_height(uint64_t height);\n\n  private:\n    uint64_t height;\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainService/txs/uid/blockchain_uid.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of UChainService.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#pragma once\n\n#include <cstdint>\n#include <istream>\n#include <vector>\n#include <UChain/coin/chain/point.hpp>\n#include <UChain/coin/chain/script/script.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n#include <UChainService/txs/uid/uid_detail.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nclass BC_API blockchain_uid\n{\n  public:\n    enum uid_address_type : uint32_t\n    {\n        address_invalid,\n        address_current,\n        address_history\n    };\n    typedef std::vector<blockchain_uid> list;\n    blockchain_uid();\n    blockchain_uid(uint32_t version, const output_point &tx_point,\n                   uint64_t height, uint32_t status, const uid_detail &uid);\n    static blockchain_uid factory_from_data(const data_chunk &data);\n    static blockchain_uid factory_from_data(std::istream &stream);\n    static blockchain_uid factory_from_data(reader &source);\n    static uint64_t satoshi_fixed_size();\n\n    bool from_data(const data_chunk &data);\n    bool from_data(std::istream &stream);\n    bool from_data(reader &source);\n    data_chunk to_data() const;\n    void to_data(std::ostream &stream) const;\n    void to_data(writer &sink) const;\n\n#ifdef UC_DEBUG\n    std::string to_string() const;\n#endif\n\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size() const;\n    const uint32_t &get_version() const;\n    void set_version(const uint32_t &version_);\n    const output_point &get_tx_point() const;\n    void set_tx_point(const output_point &tx_point_);\n    const uint64_t &get_height() const;\n    void set_height(const uint64_t &height_);\n    const uid_detail &get_uid() const;\n    void set_uid(const uid_detail &uid_);\n    void set_status(const uint32_t &status);\n    const uint32_t &get_status() const;\n    std::string get_status_string() const;\n\n  private:\n    uint32_t version_;\n    output_point tx_point_;\n    uint64_t height_;\n    uint32_t status_;\n    uid_detail uid_;\n};\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "include/UChainService/txs/uid/uid.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of UChainService.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_ATTACH_UID_HPP\n#define UC_CHAIN_ATTACH_UID_HPP\n\n#include <cstdint>\n#include <istream>\n#include <vector>\n#include <UChain/coin/chain/point.hpp>\n#include <UChain/coin/chain/script/script.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n#include <boost/variant.hpp>\n#include <UChainService/txs/uid/uid_detail.hpp>\n\nusing namespace libbitcoin::chain;\n\n#define UID_STATUS2UINT32(kd) (static_cast<typename std::underlying_type<uid::uid_status>::type>(kd))\n\n#define UID_DETAIL_TYPE UID_STATUS2UINT32(uid::uid_status::uid_locked)\n#define UID_TRANSFERABLE_TYPE UID_STATUS2UINT32(uid::uid_status::uid_transferable)\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nclass BC_API uid\n{\npublic:\n  enum class uid_status : uint32_t\n  {\n    uid_none,\n    uid_locked,\n    uid_transferable,\n  };\n\n  uid();\n  uid(uint32_t status, const uid_detail &detail);\n  static uid factory_from_data(const data_chunk &data);\n  static uid factory_from_data(std::istream &stream);\n  static uid factory_from_data(reader &source);\n  static uint64_t satoshi_fixed_size();\n\n  bool from_data(const data_chunk &data);\n  bool from_data(std::istream &stream);\n  bool from_data(reader &source);\n  data_chunk to_data() const;\n  void to_data(std::ostream &stream) const;\n  void to_data(writer &sink) const;\n  std::string to_string() const;\n  bool is_valid_type() const;\n  bool is_valid() const;\n  void reset();\n  uint64_t serialized_size() const;\n  uint32_t get_status() const;\n  void set_status(uint32_t status);\n  void set_data(const uid_detail &detail);\n  const uid_detail &get_data() const;\n\nprivate:\n  uint32_t status;\n  uid_detail data;\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainService/txs/uid/uid_detail.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of UChainService.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_ASSET_UID_DETAIL_HPP\n#define UC_CHAIN_ASSET_UID_DETAIL_HPP\n\n#include <cstdint>\n#include <istream>\n#include <vector>\n#include <UChain/coin/chain/point.hpp>\n#include <UChain/coin/chain/script/script.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nBC_CONSTEXPR size_t UID_DETAIL_SYMBOL_FIX_SIZE = 64;\nBC_CONSTEXPR size_t UID_DETAIL_ADDRESS_FIX_SIZE = 64;\n\nBC_CONSTEXPR size_t UID_DETAIL_FIX_SIZE = UID_DETAIL_SYMBOL_FIX_SIZE + UID_DETAIL_ADDRESS_FIX_SIZE;\n\nclass BC_API uid_detail\n{\npublic:\n  typedef std::vector<uid_detail> list;\n\n  enum uid_detail_type : uint32_t\n  {\n    created,\n    registered_not_in_blockchain,\n    registered_in_blockchain\n  };\n\n  uid_detail();\n  uid_detail(const std::string &symbol, const std::string &address);\n\n  static uid_detail factory_from_data(const data_chunk &data);\n  static uid_detail factory_from_data(std::istream &stream);\n  static uid_detail factory_from_data(reader &source);\n  static uint64_t satoshi_fixed_size();\n  bool from_data(const data_chunk &data);\n  bool from_data(std::istream &stream);\n  bool from_data(reader &source);\n  data_chunk to_data() const;\n  void to_data(std::ostream &stream) const;\n  void to_data(writer &sink) const;\n\n  bool operator<(const uid_detail &other) const;\n  std::string to_string() const;\n  void to_json(std::ostream &out);\n\n  bool is_valid() const;\n  void reset();\n  uint32_t count_size() const;\n  uint64_t serialized_size() const;\n  const std::string &get_symbol() const;\n  void set_symbol(const std::string &symbol);\n  const std::string &get_address() const;\n  void set_address(const std::string &address);\n\nprivate:\n  std::string symbol;\n  std::string address;\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainService/txs/utility/callstack.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef INCLUDE_BITCOIN_BITCOIN_UTILITY_CALLSTACK_HPP_\n#define INCLUDE_BITCOIN_BITCOIN_UTILITY_CALLSTACK_HPP_\n\n#include <iostream>\n#include <string>\n\nnamespace libbitcoin\n{\nvoid call_stack(std::ostream &os);\nvoid do_callstack(const std::string &name);\n} //namespace libbitcoin\n\n#endif /* INCLUDE_BITCOIN_BITCOIN_UTILITY_CALLSTACK_HPP_ */\n"
  },
  {
    "path": "include/UChainService/txs/utility/daemon.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef INCLUDE_BITCOIN_BITCOIN_UTILITY_DAEMON_HPP_\n#define INCLUDE_BITCOIN_BITCOIN_UTILITY_DAEMON_HPP_\n\nnamespace libbitcoin\n{\n\nvoid daemon();\n\n} // namespace libbitcoin\n\n#endif /* INCLUDE_BITCOIN_BITCOIN_UTILITY_DAEMON_HPP_ */\n"
  },
  {
    "path": "include/UChainService/txs/utility/path.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef INCLUDE_BITCOIN_BITCOIN_UTILITY_PATH_HPP_\n#define INCLUDE_BITCOIN_BITCOIN_UTILITY_PATH_HPP_\n\n#include <boost/filesystem.hpp>\n\nnamespace libbitcoin\n{\nconst boost::filesystem::path &default_data_path();\n\nboost::filesystem::path webpage_path();\n} //namespace libbitcoin\n\n#endif /* INCLUDE_BITCOIN_BITCOIN_UTILITY_PATH_HPP_ */\n"
  },
  {
    "path": "include/UChainService/txs/variant.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of UChainService.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_VARIANT_HPP\n#define UC_CHAIN_VARIANT_HPP\n\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n#include <boost/variant.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nclass from_data_visitor : public boost::static_visitor<bool>\n{\npublic:\n  from_data_visitor(reader &src) : source(src)\n  {\n  }\n\n  template <class T>\n  bool operator()(T &t)\n  {\n    return t.from_data(source);\n  }\n\n  reader &source;\n};\n\nclass to_data_visitor : public boost::static_visitor<void>\n{\npublic:\n  to_data_visitor(writer &dst) : sink(dst)\n  {\n  }\n\n  template <class T>\n  void operator()(T &t) const\n  {\n    return t.to_data(sink);\n  }\n\n  writer &sink;\n};\n\nclass serialized_size_visitor : public boost::static_visitor<uint64_t>\n{\npublic:\n  serialized_size_visitor()\n  {\n  }\n\n  template <class T>\n  uint64_t operator()(T &t) const\n  {\n    return t.serialized_size();\n  }\n};\n\nclass to_string_visitor : public boost::static_visitor<std::string>\n{\npublic:\n  to_string_visitor()\n  {\n  }\n\n  template <class T>\n  std::string operator()(T &t) const\n  {\n    return t.to_string();\n  }\n};\n\nclass reset_visitor : public boost::static_visitor<void>\n{\npublic:\n  reset_visitor()\n  {\n  }\n\n  template <class T>\n  void operator()(T &t)\n  {\n    return t.reset();\n  }\n};\n\nclass is_valid_visitor : public boost::static_visitor<bool>\n{\npublic:\n  is_valid_visitor()\n  {\n  }\n\n  template <class T>\n  bool operator()(T &t) const\n  {\n    return t.is_valid();\n  }\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainService/txs/wallet/wallet.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of UChainService.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_ASSET_WALLET_HPP\n#define UC_CHAIN_ASSET_WALLET_HPP\n\n#include <cstdint>\n#include <istream>\n#include <vector>\n#include <UChain/coin/chain/point.hpp>\n#include <UChain/coin/chain/script/script.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n#include <UChain/coin/formats/base_16.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nenum wallet_status : uint8_t\n{\n    //system status\n    locked = 0,\n    imported,\n    normal,\n    //use status\n    login,\n    logout,\n    error,\n};\n\nenum wallet_priority : uint8_t\n{\n    // 0 -- admin user  1 -- common user\n    administrator = 0,\n    common_user = 1,\n};\n\nenum wallet_type : uint8_t\n{\n    common = 0,\n    multisignature,\n};\n\n/// used for store wallet related information\nclass BC_API wallet_multisig\n{\n  public:\n    typedef std::vector<wallet_multisig> list;\n\n    wallet_multisig();\n    wallet_multisig(uint32_t hd_index, uint8_t m, uint8_t n,\n                    std::vector<std::string> &&cosigner_pubkeys, std::string &pubkey);\n\n    void set_hd_index(uint32_t index);\n    uint32_t get_hd_index() const;\n    inline void increase_hd_index() { hd_index_++; };\n\n    void set_index(uint32_t index);\n    uint32_t get_index() const;\n\n    void set_m(uint8_t m);\n    uint8_t get_m() const;\n\n    void set_n(uint8_t n);\n    uint8_t get_n() const;\n\n    const std::vector<std::string> &get_cosigner_pubkeys() const;\n    void set_cosigner_pubkeys(std::vector<std::string> &&cosigner_pubkeys);\n\n    std::string get_pub_key() const;\n    void set_pub_key(std::string &pubkey);\n\n    std::string get_description() const;\n    void set_description(std::string &description);\n\n    std::string get_address() const;\n    void set_address(std::string &address);\n\n    std::string get_multisig_script() const;\n\n    bool from_data(reader &source);\n    void to_data(writer &sink) const;\n\n    uint64_t serialized_size() const;\n\n    bool operator==(const wallet_multisig &other) const;\n    void reset();\n\n#ifdef UC_DEBUG\n    std::string to_string();\n#endif\n\n  private:\n    uint32_t hd_index_;\n    uint32_t index_;\n    uint8_t m_;\n    uint8_t n_;\n    std::string pubkey_;\n    std::vector<std::string> cosigner_pubkeys_;\n    std::string description_;\n    std::string address_;\n};\n\nclass BC_API wallet\n{\n  public:\n    wallet();\n    wallet(const std::string &name, const std::string &mnemonic, const hash_digest &passwd,\n           uint32_t hd_index, uint8_t priority, uint8_t status, uint8_t type);\n\n    static wallet factory_from_data(const data_chunk &data);\n    static wallet factory_from_data(std::istream &stream);\n    static wallet factory_from_data(reader &source);\n    static uint64_t satoshi_fixed_size();\n\n    bool from_data(const data_chunk &data);\n    bool from_data(std::istream &stream);\n    bool from_data(reader &source);\n    data_chunk to_data() const;\n    void to_data(std::ostream &stream) const;\n    void to_data(writer &sink) const;\n\n    bool is_valid() const;\n    void reset();\n\n    uint64_t serialized_size() const;\n\n    operator bool() const;\n\n    bool operator==(const libbitcoin::chain::wallet &other) const;\n\n#ifdef UC_DEBUG\n    std::string to_string();\n#endif\n\n    const std::string &get_name() const;\n    void set_name(const std::string &name);\n\n    const std::string &get_mnemonic(std::string &passphrase, std::string &decry_output) const;\n    const std::string &get_mnemonic() const;\n    void set_mnemonic(const std::string &mnemonic, std::string &passphrase);\n    void set_mnemonic(const std::string &mnemonic);\n\n    const hash_digest &get_passwd() const;\n\n    void set_passwd(const std::string &outside_passwd)\n    {\n        //bc::decode_hash(passwd, outside_passwd);\n        data_chunk data(outside_passwd.begin(), outside_passwd.end());\n        set_passwd(sha256_hash(data));\n    }\n\n    void set_passwd(const hash_digest &passwd_hash)\n    {\n        passwd = passwd_hash;\n    }\n\n    uint32_t get_hd_index() const;\n    void set_hd_index(const uint32_t hd_index);\n\n    void increase_hd_index() { hd_index++; };\n\n    uint8_t get_status() const;\n    void set_status(const uint8_t status);\n\n    uint8_t get_priority() const;\n    void set_priority(const uint8_t priority);\n\n    void set_type(uint8_t type);\n    uint8_t get_type() const;\n\n    const wallet_multisig::list &get_multisig_vec() const;\n    void set_multisig_vec(wallet_multisig::list &&multisig);\n\n    bool is_multisig_exist(const wallet_multisig &multisig);\n    void set_multisig(const wallet_multisig &multisig);\n    void modify_multisig(const wallet_multisig &multisig);\n    void remove_multisig(const wallet_multisig &multisig);\n    std::shared_ptr<wallet_multisig::list> get_multisig(const std::string &addr);\n\n  private:\n    std::string name;\n    std::string mnemonic;\n    hash_digest passwd;\n\n    uint32_t hd_index;\n    //uint16_t status; // old define\n    uint8_t type;\n    uint8_t status;\n    uint8_t priority;\n\n    // multisig fields\n    wallet_multisig::list multisig_vec;\n    //wallet_multisig multisig;\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "include/UChainService/txs/wallet/wallet_address.hpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of UChainService.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_ASSET_WALLET_ADDRESS_HPP\n#define UC_CHAIN_ASSET_WALLET_ADDRESS_HPP\n\n#include <cstdint>\n#include <istream>\n#include <vector>\n#include <UChain/coin/chain/point.hpp>\n#include <UChain/coin/chain/script/script.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/reader.hpp>\n#include <UChain/coin/utility/writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nBC_CONSTEXPR size_t ADDRESS_NAME_FIX_SIZE = 64;\nBC_CONSTEXPR size_t ADDRESS_PRV_KEY_FIX_SIZE = 70;\nBC_CONSTEXPR size_t ADDRESS_PUB_KEY_FIX_SIZE = 70;\nBC_CONSTEXPR size_t ADDRESS_HD_INDEX_FIX_SIZE = 4;\nBC_CONSTEXPR size_t ADDRESS_BALANCE_FIX_SIZE = 8;\nBC_CONSTEXPR size_t ADDRESS_ALIAS_FIX_SIZE = 64;\nBC_CONSTEXPR size_t ADDRESS_ADDRESS_FIX_SIZE = 48;\nBC_CONSTEXPR size_t ADDRESS_STATUS_FIX_SIZE = 1;\n\n/// used for store wallet_address related information\nenum wallet_address_status : uint8_t\n{\n    diabale = 0,\n    enable = 1,        // common address\n    multisig_addr = 2, // multisig address\n    stealth_addr = 3   // stealth address\n};\n\nclass BC_API wallet_address\n{\n  public:\n    typedef std::vector<wallet_address> list;\n    wallet_address();\n    wallet_address(const std::string &name, const std::string &prv_key,\n                   const std::string &pub_key, uint32_t hd_index, uint64_t balance,\n                   const std::string &alias, const std::string &address, uint8_t status);\n    wallet_address(const wallet_address &other);\n    static wallet_address factory_from_data(const data_chunk &data);\n    static wallet_address factory_from_data(std::istream &stream);\n    static wallet_address factory_from_data(reader &source);\n    static uint64_t satoshi_fixed_size();\n\n    bool from_data(const data_chunk &data);\n    bool from_data(std::istream &stream);\n    bool from_data(reader &source);\n    data_chunk to_data() const;\n    void to_data(std::ostream &stream) const;\n    void to_data(writer &sink) const;\n#ifdef UC_DEBUG\n    std::string to_string();\n#endif\n    bool is_valid() const;\n    void reset();\n    uint64_t serialized_size() const;\n    const std::string &get_name() const;\n    void set_name(const std::string &name);\n    const std::string get_prv_key(std::string &passphrase) const;\n    const std::string get_prv_key() const;\n    void set_prv_key(const std::string &prv_key, std::string &passphrase);\n    void set_prv_key(const std::string &prv_key);\n    const std::string &get_pub_key() const;\n    void set_pub_key(const std::string &pub_key);\n    uint32_t get_hd_index() const;\n    void set_hd_index(uint32_t hd_index);\n    uint64_t get_balance() const;\n    void set_balance(uint64_t balance);\n    const std::string &get_alias() const;\n    void set_alias(const std::string &alias);\n    const std::string &get_address() const;\n    void set_address(const std::string &address);\n    uint8_t get_status() const;\n    void set_status(uint8_t status);\n\n  private:\n    std::string name;    // 64 bytes -- wallet name -- todo remove it later\n    std::string prv_key; // 70 bytes\n    std::string pub_key; // 70 bytes\n    uint32_t hd_index;   // 4 bytes -- todo remove it later\n    uint64_t balance;    // 8 bytes\n    std::string alias;   // 64 bytes\n    std::string address; // 48 bytes\n    uint8_t status_;     // 1 bytes -- 0 -- diabale  1 -- enable\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "install_thirdlibrary",
    "content": "#!/bin/bash\n###############################################################################\n#  Copyright (c) 2014-2018 libbitcoin-explorer developers (see COPYING).\n#  Copyright (c) 2018-2020 UC Core Developers\n#\n###############################################################################\n\n# Define constants.\n#==============================================================================\n# The default build directory.\n#------------------------------------------------------------------------------\nBUILD_DIR=\"thirdlibrary\"\n\n# ICU archive.\n#------------------------------------------------------------------------------\nICU_URL=\"http://download.icu-project.org/files/icu4c/55.1/icu4c-55_1-src.tgz\"\nICU_ARCHIVE=\"icu4c-55_1-src.tgz\"\n\n# ZLib archive.\n#------------------------------------------------------------------------------\nZLIB_URL=\"https://github.com/madler/zlib/archive/v1.2.9.tar.gz\"\nZLIB_ARCHIVE=\"v1.2.9.tar.gz\"\n\n# ZeroMQ archive.\n#------------------------------------------------------------------------------\nZMQ_URL=\"https://github.com/zeromq/libzmq/releases/download/v4.2.5/zeromq-4.2.5.tar.gz\"\n# the following URL is not stable, sometimes it is unable to connect.\n#ZMQ_URL=\"https://sources.voidlinux.eu/zeromq-4.2.5/zeromq-4.2.5.tar.gz\"\nZMQ_ARCHIVE=\"zeromq-4.2.5.tar.gz\"\n\n# PNG archive.\n#------------------------------------------------------------------------------\nPNG_URL=\"http://downloads.sourceforge.net/project/libpng/libpng16/older-releases/1.6.29/libpng-1.6.29.tar.xz\"\nPNG_ARCHIVE=\"libpng-1.6.29.tar.xz\"\n\n# QREncode archive.\n#------------------------------------------------------------------------------\nQRENCODE_URL=\"http://fukuchi.org/works/qrencode/qrencode-3.4.4.tar.bz2\"\nQRENCODE_ARCHIVE=\"qrencode-3.4.4.tar.bz2\"\n\n# Boost archive.\n#------------------------------------------------------------------------------\nBOOST_URL=\"\"https://sourceforge.net/projects/boost/files/boost/1.62.0/boost_1_62_0.tar.bz2\n# the following URL is not stable, sometimes it is unable to connect.\n#BOOST_URL=\"http://downloads.sourceforge.net/project/boost/boost/1.58.0/boost_1_58_0.tar.bz2\"\nBOOST_ARCHIVE=\"boost_1_62_0.tar.bz2\"\n\n# miniupnpc archive\n#------------------------------------------------------------------------------\nUPNPC_URL=\"http://miniupnp.tuxfamily.org/files/miniupnpc-2.0.tar.gz\"\nUPNPC_ARCHIVE=\"miniupnpc-2.0.tar.gz\"\n\n\n# Define utility functions.\n#==============================================================================\nconfigure_options()\n{\n    display_message \"configure options:\"\n    for OPTION in \"$@\"; do\n        if [[ $OPTION ]]; then\n            display_message $OPTION\n        fi\n    done\n\n    ./configure \"$@\"\n}\n\nconfigure_links()\n{\n    # Configure dynamic linker run-time bindings when installing to system.\n    if [[ ($OS == Linux) && ($PREFIX == \"/usr/local\") ]]; then\n        sudo ldconfig\n    fi\n}\n\ncreate_directory()\n{\n    local DIRECTORY=\"$1\"\n\n    if [ ! -d $DIRECTORY ];then\n    rm -rf \"$DIRECTORY\"\n    mkdir \"$DIRECTORY\"\n    fi\n}\n\ndisplay_heading_message()\n{\n    local MESSAGE=\"$1\"\n\n    echo\n    echo \"********************** $MESSAGE **********************\"\n    echo\n}\n\ndisplay_message()\n{\n    local MESSAGE=\"$1\"\n    echo \"$MESSAGE\"\n}\n\ndisplay_error()\n{\n    local MESSAGE=\"$1\"\n    >&2 echo \"$MESSAGE\"\n}\n\ninitialize_git()\n{\n    # Initialize git repository at the root of the current directory.\n    git init\n    git config user.name anonymous\n}\n\n# make_current_directory jobs [configure_options]\nmake_current_directory()\n{\n    local JOBS=$1\n    shift 1\n\n    ./autogen.sh\n    configure_options \"$@\"\n    make_jobs $JOBS\n    sudo make install\n    configure_links\n}\n\n# make_jobs jobs [make_options]\nmake_jobs()\n{\n    local JOBS=$1\n    shift 1\n\n    # Avoid setting -j1 (causes problems on Travis).\n    if [[ $JOBS > $SEQUENTIAL ]]; then\n        make -j$JOBS \"$@\"\n    else\n        make \"$@\"\n    fi\n}\n\n# make_tests jobs\nmake_tests()\n{\n    local JOBS=$1\n\n    # Disable exit on error.\n    set +e\n\n    # Build and run unit tests relative to the primary directory.\n    # VERBOSE=1 ensures test runner output sent to console (gcc).\n    make_jobs $JOBS check \"VERBOSE=1\"\n    local RESULT=$?\n\n    # Test runners emit to the test.log file.\n    if [[ -e \"test.log\" ]]; then\n        cat \"test.log\"\n    fi\n\n    if [[ $RESULT -ne 0 ]]; then\n        exit $RESULT\n    fi\n\n    # Reenable exit on error.\n    set -e\n}\n\npop_directory()\n{\n    popd >/dev/null\n}\n\npush_directory()\n{\n    local DIRECTORY=\"$1\"\n\n    pushd \"$DIRECTORY\" >/dev/null\n}\n\n\n# Initialize the build environment.\n#==============================================================================\n# Exit this script on the first build error.\n#------------------------------------------------------------------------------\nset -e\n\n# Configure build parallelism.\n#------------------------------------------------------------------------------\nSEQUENTIAL=1\nOS=`uname -s`\nif [[ $PARALLEL ]]; then\n    display_message \"Using shell-defined PARALLEL value.\"\nelif [[ $OS == Linux ]]; then\n    PARALLEL=`nproc`\nelif [[ ($OS == Darwin) || ($OS == OpenBSD) ]]; then\n    PARALLEL=`sysctl -n hw.ncpu`\nelse\n    display_error \"Unsupported system: $OS\"\n    exit 1\nfi\n\n# Define operating system specific settings.\n#------------------------------------------------------------------------------\nif [[ $OS == Darwin ]]; then\n    export CC=\"clang\"\n    export CXX=\"clang++\"\n    STDLIB=\"c++\"\nelif [[ $OS == OpenBSD ]]; then\n    make() { gmake \"$@\"; }\n    export CC=\"egcc\"\n    export CXX=\"eg++\"\n    STDLIB=\"estdc++\"\nelse # Linux\n    STDLIB=\"stdc++\"\nfi\n\n# Link to appropriate standard library in non-default scnearios.\n#------------------------------------------------------------------------------\nif [[ ($OS == Linux && $CC == \"clang\") || ($OS == OpenBSD) ]]; then\n    export LDLIBS=\"-l$STDLIB $LDLIBS\"\n    export CXXFLAGS=\"-stdlib=lib$STDLIB $CXXFLAGS\"\nfi\n\n# Parse command line options that are handled by this script.\n#------------------------------------------------------------------------------\nfor OPTION in \"$@\"; do\n    case $OPTION in\n        # Custom build options (in the form of --build-<option>).\n        (--build-icu)      BUILD_ICU=\"yes\";;\n        (--build-zlib)     BUILD_ZLIB=\"yes\";;\n        (--build-png)      BUILD_PNG=\"yes\";;\n        (--build-qrencode) BUILD_QRENCODE=\"yes\";;\n        (--build-boost)    BUILD_BOOST=\"yes\";;\n        (--build-upnpc)    BUILD_UPNPC=\"yes\";;\n        (--build-dir=*)    BUILD_DIR=\"${OPTION#*=}\";;\n\n        # Standard build options.\n        (--prefix=*)       PREFIX=\"${OPTION#*=}\";;\n        (--disable-shared) DISABLE_SHARED=\"yes\";;\n        (--disable-static) DISABLE_STATIC=\"yes\";;\n        (--with-icu)       WITH_ICU=\"yes\";;\n        (--with-png)       WITH_PNG=\"yes\";;\n        (--with-qrencode)  WITH_QRENCODE=\"yes\";;\n    esac\ndone\n\n# Normalize of static and shared options.\n#------------------------------------------------------------------------------\nif [[ $DISABLE_SHARED ]]; then\n    CONFIGURE_OPTIONS=(\"$@\" \"--enable-static\")\nelif [[ $DISABLE_STATIC ]]; then\n    CONFIGURE_OPTIONS=(\"$@\" \"--enable-shared\")\nelse\n    CONFIGURE_OPTIONS=(\"$@\" \"--enable-shared\")\n    CONFIGURE_OPTIONS=(\"$@\" \"--enable-static\")\nfi\n\n# Purge custom build options so they don't break configure.\n#------------------------------------------------------------------------------\nCONFIGURE_OPTIONS=(\"${CONFIGURE_OPTIONS[@]/--build-*/}\")\n\n# Always set a prefix (required on OSX and for lib detection).\n#------------------------------------------------------------------------------\nif [[ !($PREFIX) ]]; then\n    PREFIX=\"/usr/local\"\n    CONFIGURE_OPTIONS=( \"${CONFIGURE_OPTIONS[@]}\" \"--prefix=$PREFIX\")\nelse\n    # Incorporate the custom libdir into each object, for runtime resolution.\n    export LD_RUN_PATH=\"$PREFIX/lib\"\nfi\n\n# Incorporate the prefix.\n#------------------------------------------------------------------------------\n# Set the prefix-based package config directory.\nPREFIX_PKG_CONFIG_DIR=\"$PREFIX/lib/pkgconfig\"\n\n# Augment PKG_CONFIG_PATH search path with our prefix.\nexport PKG_CONFIG_PATH=\"$PKG_CONFIG_PATH:$PREFIX_PKG_CONFIG_DIR\"\n\n# Set a package config save path that can be passed via our builds.\nwith_pkgconfigdir=\"--with-pkgconfigdir=$PREFIX_PKG_CONFIG_DIR\"\n\nif [[ $BUILD_BOOST ]]; then\n    # Boost has no pkg-config, m4 searches in the following order:\n    # --with-boost=<path>, /usr, /usr/local, /opt, /opt/local, $BOOST_ROOT.\n    # We use --with-boost to prioritize the --prefix path when we build it.\n    # Otherwise standard paths suffice for Linux, Homebrew and MacPorts.\n    # ax_boost_base.m4 appends /include and adds to BOOST_CPPFLAGS\n    # ax_boost_base.m4 searches for /lib /lib64 and adds to BOOST_LDFLAGS\n    with_boost=\"--with-boost=$PREFIX\"\nfi\n\n# Echo generated values.\n#------------------------------------------------------------------------------\ndisplay_message \"Libbitcoin installer configuration.\"\ndisplay_message \"--------------------------------------------------------------------\"\ndisplay_message \"OS                    : $OS\"\ndisplay_message \"PARALLEL              : $PARALLEL\"\ndisplay_message \"CC                    : $CC\"\ndisplay_message \"CXX                   : $CXX\"\ndisplay_message \"CPPFLAGS              : $CPPFLAGS\"\ndisplay_message \"CFLAGS                : $CFLAGS\"\ndisplay_message \"CXXFLAGS              : $CXXFLAGS\"\ndisplay_message \"LDFLAGS               : $LDFLAGS\"\ndisplay_message \"LDLIBS                : $LDLIBS\"\ndisplay_message \"WITH_ICU              : $WITH_ICU\"\ndisplay_message \"WITH_PNG              : $WITH_PNG\"\ndisplay_message \"WITH_QRENCODE         : $WITH_QRENCODE\"\ndisplay_message \"BUILD_ICU             : $BUILD_ICU\"\ndisplay_message \"BUILD_ZLIB            : $BUILD_ZLIB\"\ndisplay_message \"BUILD_PNG             : $BUILD_PNG\"\ndisplay_message \"BUILD_QRENCODE        : $BUILD_QRENCODE\"\ndisplay_message \"BUILD_BOOST           : $BUILD_BOOST\"\ndisplay_message \"BUILD_UPNPC           : $BUILD_UPNPC\"\ndisplay_message \"PREFIX                : $PREFIX\"\ndisplay_message \"BUILD_DIR             : $BUILD_DIR\"\ndisplay_message \"DISABLE_SHARED        : $DISABLE_SHARED\"\ndisplay_message \"DISABLE_STATIC        : $DISABLE_STATIC\"\ndisplay_message \"with_boost            : ${with_boost}\"\ndisplay_message \"with_pkgconfigdir     : ${with_pkgconfigdir}\"\ndisplay_message \"--------------------------------------------------------------------\"\n\n\n# Define build options.\n#==============================================================================\n# Define icu options.\n#------------------------------------------------------------------------------\nICU_OPTIONS=(\n\"--enable-draft\" \\\n\"--enable-tools\" \\\n\"--disable-extras\" \\\n\"--disable-icuio\" \\\n\"--disable-layout\" \\\n\"--disable-layoutex\" \\\n\"--disable-tests\" \\\n\"--disable-samples\")\n\n# Define boost options.\n#------------------------------------------------------------------------------\nBOOST_OPTIONS=(\n\"--with-chrono\" \\\n\"--with-date_time\" \\\n\"--with-filesystem\" \\\n\"--with-program_options\" \\\n\"--with-regex\" \\\n\"--with-system\" \\\n\"--with-thread\" \\\n\"--with-test\")\n\n#\"--with-log\" \\\n#\"--with-iostreams\" \\\n#\"--with-locale\" \\\n\n# Define secp256k1 options. fix me.\nif [ $IS_TRAVIS_LINUX ] || [ $IS_TRAVIS_OSX ];then\n    with_secp256k1_gmp=\"--with-bignum=no\"\nfi\n#------------------------------------------------------------------------------\nSECP256K1_OPTIONS=(\n\"--disable-tests\" \\\n\"--enable-module-recovery\" \\\n\"${with_secp256k1_gmp}\")\n\n# Define bitcoin options.\n#------------------------------------------------------------------------------\nBITCOIN_OPTIONS=(\n\"--without-tests\" \\\n\"--without-examples\" \\\n\"${with_boost}\" \\\n\"${with_pkgconfigdir}\")\n\n# Define bitcoin-protocol options.\n#------------------------------------------------------------------------------\nBITCOIN_PROTOCOL_OPTIONS=(\n\"--without-tests\" \\\n\"--without-examples\" \\\n\"${with_boost}\" \\\n\"${with_pkgconfigdir}\")\n\n# Define bitcoin-client options.\n#------------------------------------------------------------------------------\nBITCOIN_CLIENT_OPTIONS=(\n\"--without-tests\" \\\n\"--without-examples\" \\\n\"${with_boost}\" \\\n\"${with_pkgconfigdir}\")\n\n# Define bitcoin-network options.\n#------------------------------------------------------------------------------\nBITCOIN_NETWORK_OPTIONS=(\n\"--without-tests\" \\\n\"${with_boost}\" \\\n\"${with_pkgconfigdir}\")\n\n# Define bitcoin-explorer options.\n#------------------------------------------------------------------------------\nBITCOIN_EXPLORER_OPTIONS=(\n\"${with_boost}\" \\\n\"${with_pkgconfigdir}\")\n\n\n# Define build functions.\n#==============================================================================\n\n# Because PKG_CONFIG_PATH doesn't get updated by Homebrew or MacPorts.\ninitialize_icu_packages()\n{\n    if [[ ($OS == Darwin) ]]; then\n        # Update PKG_CONFIG_PATH for ICU package installations on OSX.\n        # OSX provides libicucore.dylib with no pkgconfig and doesn't support\n        # renaming or important features, so we can't use that.\n        local HOMEBREW_ICU_PKG_CONFIG=\"/usr/local/opt/icu4c/lib/pkgconfig\"\n        local MACPORTS_ICU_PKG_CONFIG=\"/opt/local/lib/pkgconfig\"\n\n        if [[ -d \"$HOMEBREW_ICU_PKG_CONFIG\" ]]; then\n            export PKG_CONFIG_PATH=\"$PKG_CONFIG_PATH:$HOMEBREW_ICU_PKG_CONFIG\"\n        elif [[ -d \"$MACPORTS_ICU_PKG_CONFIG\" ]]; then\n            export PKG_CONFIG_PATH=\"$PKG_CONFIG_PATH:$MACPORTS_ICU_PKG_CONFIG\"\n        fi\n    fi\n}\n\n# Because ZLIB doesn't actually parse its --disable-shared option.\n# Because ZLIB doesn't follow GNU recommentation for unknown arguments.\npatch_zlib_configuration()\n{\n    sed -i.tmp \"s/leave 1/shift/\" configure\n    sed -i.tmp \"s/--static/--static | --disable-shared/\" configure\n    sed -i.tmp \"/unknown option/d\" configure\n    sed -i.tmp \"/help for help/d\" configure\n\n    # display_message \"Hack: ZLIB configuration options modified.\"\n}\n\n# Because ZLIB can't build shared only.\nclean_zlib_build()\n{\n    if [[ $DISABLE_STATIC ]]; then\n        rm --force \"$PREFIX/lib/libz.a\"\n    fi\n}\n\n# Standard build from tarball.\nbuild_from_tarball()\n{\n    local URL=$1\n    local ARCHIVE=$2\n    local COMPRESSION=$3\n    local PUSH_DIR=$4\n    local JOBS=$5\n    local BUILD=$6\n    local OPTIONS=$7\n    shift 7\n\n    # For some platforms we need to set ICU pkg-config path.\n    if [[ !($BUILD) ]]; then\n        if [[ $ARCHIVE == $ICU_ARCHIVE ]]; then\n            initialize_icu_packages\n        fi\n        return\n    fi\n\n    # Because libpng doesn't actually use pkg-config to locate zlib.\n    # Because ICU tools don't know how to locate internal dependencies.\n    if [[ ($ARCHIVE == $ICU_ARCHIVE) || ($ARCHIVE == $PNG_ARCHIVE) ]]; then\n        local SAVE_LDFLAGS=$LDFLAGS\n        export LDFLAGS=\"-L$PREFIX/lib $LDFLAGS\"\n    fi\n\n    # Because libpng doesn't actually use pkg-config to locate zlib.h.\n    if [[ ($ARCHIVE == $PNG_ARCHIVE) ]]; then\n        local SAVE_CPPFLAGS=$CPPFLAGS\n        export CPPFLAGS=\"-I$PREFIX/include $CPPFLAGS\"\n    fi\n\n    display_heading_message \"Download $ARCHIVE\"\n\n    # Use the suffixed archive name as the extraction directory.\n    local EXTRACT=\"build-$ARCHIVE\"\n    push_directory \"$BUILD_DIR\"\n    create_directory \"$EXTRACT\"\n    push_directory \"$EXTRACT\"\n\n    # Extract the source locally.\n    wget --output-document $ARCHIVE $URL\n    tar --extract --file $ARCHIVE --$COMPRESSION --strip-components=1\n    push_directory \"$PUSH_DIR\"\n\n    # Enable static only zlib build.\n    if [[ $ARCHIVE == $ZLIB_ARCHIVE ]]; then\n        patch_zlib_configuration\n    fi\n\n    # Join generated and command line options.\n    local CONFIGURATION=(\"${OPTIONS[@]}\" \"$@\")\n\n    if [[ $ARCHIVE == $UPNPC_ARCHIVE ]]; then\n        # miniupnpc has Makefile already, has no configure\n        make_jobs $JOBS --silent\n        sudo INSTALLPREFIX=$PREFIX make install\n        configure_links\n    else\n        configure_options \"${CONFIGURATION[@]}\"\n        make_jobs $JOBS --silent\n        sudo make install\n        configure_links\n    fi\n\n    # Enable shared only zlib build.\n    if [[ $ARCHIVE == $ZLIB_ARCHIVE ]]; then\n        clean_zlib_build\n    fi\n\n    pop_directory\n    pop_directory\n\n    # Restore flags to prevent side effects.\n    export LDFLAGS=$SAVE_LDFLAGS\n    export CPPFLAGS=$SAVE_LCPPFLAGS\n\n    pop_directory\n}\n\n# Because boost ICU detection assumes in incorrect ICU path.\ncircumvent_boost_icu_detection()\n{\n    # Boost expects a directory structure for ICU which is incorrect.\n    # Boost ICU discovery fails when using prefix, can't fix with -sICU_LINK,\n    # so we rewrite the two 'has_icu_test.cpp' files to always return success.\n\n    local SUCCESS=\"int main() { return 0; }\"\n    local REGEX_TEST=\"libs/regex/build/has_icu_test.cpp\"\n    local LOCALE_TEST=\"libs/locale/build/has_icu_test.cpp\"\n\n    echo $SUCCESS > $REGEX_TEST\n    echo $SUCCESS > $LOCALE_TEST\n\n    # display_message \"Hack: ICU detection modified, will always indicate found.\"\n}\n\n# Because boost doesn't support autoconfig and doesn't like empty settings.\ninitialize_boost_configuration()\n{\n    if [[ $DISABLE_STATIC ]]; then\n        BOOST_LINK=\"shared\"\n    elif [[ $DISABLE_SHARED ]]; then\n        BOOST_LINK=\"static\"\n    else\n        BOOST_LINK=\"static,shared\"\n    fi\n\n    if [[ $CC ]]; then\n        BOOST_TOOLSET=\"toolset=$CC\"\n    fi\n\n    if [[ ($OS == Linux && $CC == \"clang\") || ($OS == OpenBSD) ]]; then\n        STDLIB_FLAG=\"-stdlib=lib$STDLIB\"\n        BOOST_CXXFLAGS=\"cxxflags=$STDLIB_FLAG\"\n        BOOST_LINKFLAGS=\"linkflags=$STDLIB_FLAG\"\n    fi\n}\n\n# Because boost doesn't use pkg-config.\ninitialize_boost_icu_configuration()\n{\n    BOOST_ICU_ICONV=\"on\"\n    BOOST_ICU_POSIX=\"on\"\n\n    if [[ $WITH_ICU ]]; then\n        circumvent_boost_icu_detection\n\n        # Restrict other locale options when compiling boost with icu.\n        BOOST_ICU_ICONV=\"off\"\n        BOOST_ICU_POSIX=\"off\"\n\n        # Extract ICU libs from package config variables and augment with -ldl.\n        ICU_LIBS=( `pkg-config icu-i18n --libs` \"-ldl\" )\n\n        # This is a hack for boost m4 scripts that fail with ICU dependency.\n        # See custom edits in ax-boost-locale.m4 and ax_boost_regex.m4.\n        export BOOST_ICU_LIBS=\"${ICU_LIBS[@]}\"\n\n        # Extract ICU prefix directory from package config variable.\n        ICU_PREFIX=`pkg-config icu-i18n --variable=prefix`\n    fi\n}\n\n# Because boost doesn't use autoconfig.\nbuild_from_tarball_boost()\n{\n    local URL=$1\n    local ARCHIVE=$2\n    local COMPRESSION=$3\n    local PUSH_DIR=$4\n    local JOBS=$5\n    local BUILD=$6\n    shift 6\n\n    if [[ !($BUILD) ]]; then\n        return\n    fi\n\n    display_heading_message \"Download $ARCHIVE\"\n\n    # Use the suffixed archive name as the extraction directory.\n    local EXTRACT=\"build-$ARCHIVE\"\n    push_directory \"$BUILD_DIR\"\n    create_directory \"$EXTRACT\"\n    push_directory \"$EXTRACT\"\n\n    # Extract the source locally.\n    wget --output-document $ARCHIVE $URL\n    tar --extract --file $ARCHIVE --$COMPRESSION --strip-components=1\n\n    initialize_boost_configuration\n    initialize_boost_icu_configuration\n\n    display_message \"Libbitcoin boost configuration.\"\n    display_message \"--------------------------------------------------------------------\"\n    display_message \"variant               : release\"\n    display_message \"threading             : multi\"\n    display_message \"toolset               : $CC\"\n    display_message \"cxxflags              : $STDLIB_FLAG\"\n    display_message \"linkflags             : $STDLIB_FLAG\"\n    display_message \"link                  : $BOOST_LINK\"\n    display_message \"boost.locale.iconv    : $BOOST_ICU_ICONV\"\n    display_message \"boost.locale.posix    : $BOOST_ICU_POSIX\"\n    display_message \"-sNO_BZIP2            : 1\"\n    display_message \"-sICU_PATH            : $ICU_PREFIX\"\n    display_message \"-sICU_LINK            : ${ICU_LIBS[@]}\"\n    display_message \"-sZLIB_LIBPATH        : $PREFIX/lib\"\n    display_message \"-sZLIB_INCLUDE        : $PREFIX/include\"\n    display_message \"-j                    : $JOBS\"\n    display_message \"-d0                   : [supress informational messages]\"\n    display_message \"-q                    : [stop at the first error]\"\n    display_message \"--reconfigure         : [ignore cached configuration]\"\n    display_message \"--prefix              : $PREFIX\"\n    display_message \"BOOST_OPTIONS         : $@\"\n    display_message \"--------------------------------------------------------------------\"\n\n    # boost_iostreams\n    # The zlib options prevent boost linkage to system libs in the case where\n    # we have built zlib in a prefix dir. Disabling zlib in boost is broken in\n    # all versions (through 1.60). https://svn.boost.org/trac/boost/ticket/9156\n    # The bzip2 auto-detection is not implemented, but disabling it works.\n\n    ./bootstrap.sh \\\n        \"--prefix=$PREFIX\" \\\n        \"--with-icu=$ICU_PREFIX\"\n\n    sudo ./b2 install \\\n        \"variant=release\" \\\n        \"threading=multi\" \\\n        \"$BOOST_TOOLSET\" \\\n        \"$BOOST_CXXFLAGS\" \\\n        \"$BOOST_LINKFLAGS\" \\\n        \"link=$BOOST_LINK\" \\\n        \"boost.locale.iconv=$BOOST_ICU_ICONV\" \\\n        \"boost.locale.posix=$BOOST_ICU_POSIX\" \\\n        \"-sNO_BZIP2=1\" \\\n        \"-sICU_PATH=$ICU_PREFIX\" \\\n        \"-sICU_LINK=${ICU_LIBS[@]}\" \\\n        \"-sZLIB_LIBPATH=$PREFIX/lib\" \\\n        \"-sZLIB_INCLUDE=$PREFIX/include\" \\\n        \"-j $JOBS\" \\\n        \"-d0\" \\\n        \"-q\" \\\n        \"--reconfigure\" \\\n        \"--prefix=$PREFIX\" \\\n        \"$@\"\n\n    pop_directory\n    pop_directory\n}\n\n# Standard build from github.\nbuild_from_github()\n{\n    push_directory \"$BUILD_DIR\"\n\n    local ACCOUNT=$1\n    local REPO=$2\n    local BRANCH=$3\n    local JOBS=$4\n    local OPTIONS=$5\n    shift 5\n\n    FORK=\"$ACCOUNT/$REPO\"\n    display_heading_message \"Download $FORK/$BRANCH\"\n\n    # Clone the repository locally.\n    git clone --depth 1 --branch $BRANCH --single-branch \"https://github.com/$FORK\"\n\n    # Join generated and command line options.\n    local CONFIGURATION=(\"${OPTIONS[@]}\" \"$@\")\n\n    # Build the local repository clone.\n    push_directory \"$REPO\"\n    make_current_directory $JOBS \"${CONFIGURATION[@]}\"\n    pop_directory\n    pop_directory\n}\n\n# Standard build of current directory.\nbuild_from_local()\n{\n    local MESSAGE=\"$1\"\n    local JOBS=$2\n    local OPTIONS=$3\n    shift 3\n\n    display_heading_message \"$MESSAGE\"\n\n    # Join generated and command line options.\n    local CONFIGURATION=(\"${OPTIONS[@]}\" \"$@\")\n\n    # Build the current directory.\n    make_current_directory $JOBS \"${CONFIGURATION[@]}\"\n}\n\n# Because Travis alread has downloaded the primary repo.\nbuild_from_travis()\n{\n    local ACCOUNT=$1\n    local REPO=$2\n    local BRANCH=$3\n    local JOBS=$4\n    local OPTIONS=$5\n    shift 5\n\n    # The primary build is not downloaded if we are running in Travis.\n    if [[ $TRAVIS == true ]]; then\n        build_from_local \"Local $TRAVIS_REPO_SLUG\" $JOBS \"${OPTIONS[@]}\" \"$@\"\n        make_tests $JOBS\n    else\n        build_from_github $ACCOUNT $REPO $BRANCH $JOBS \"${OPTIONS[@]}\" \"$@\"\n        push_directory \"$BUILD_DIR\"\n        push_directory \"$REPO\"\n        make_tests $JOBS\n        pop_directory\n        pop_directory\n    fi\n}\n\n\n# The master build function.\n#==============================================================================\nbuild_all()\n{\n    build_from_tarball $UPNPC_URL $UPNPC_ARCHIVE gzip . $PARALLEL \"$BUILD_UPNPC\" \"${UPNPC_OPTIONS[@]}\" \"$@\"\n    build_from_tarball $ZMQ_URL $ZMQ_ARCHIVE gzip . $PARALLEL \"yes\" \"${ZMQ_OPTIONS[@]}\" \"$@\"\n    build_from_tarball_boost $BOOST_URL $BOOST_ARCHIVE bzip2 . $PARALLEL \"$BUILD_BOOST\" \"${BOOST_OPTIONS[@]}\"\n    build_from_github UCHAIN-WORLD secp256k1 master $PARALLEL ${SECP256K1_OPTIONS[@]} \"$@\"\n}\n\n\n# Build the primary library and all dependencies.\n#==============================================================================\ncreate_directory \"$BUILD_DIR\"\npush_directory \"$BUILD_DIR\"\ninitialize_git\npop_directory\ntime build_all \"${CONFIGURE_OPTIONS[@]}\"\n\n"
  },
  {
    "path": "src/CMakeLists.txt",
    "content": "ADD_SUBDIRECTORY(UChain/coin)\nADD_SUBDIRECTORY(UChain/network)\nADD_SUBDIRECTORY(UChain/database)\nADD_SUBDIRECTORY(UChain/blockchain)\nADD_SUBDIRECTORY(UChain/node)\nADD_SUBDIRECTORY(UChain/protocol)\nADD_SUBDIRECTORY(UChain/client)\nADD_SUBDIRECTORY(UChain/explorer)\nADD_SUBDIRECTORY(UChainService/consensus)\nADD_SUBDIRECTORY(UChainService/api)\nADD_SUBDIRECTORY(UChainService/txs)\nADD_SUBDIRECTORY(UChainService/data)\nADD_SUBDIRECTORY(UChainApp/ucd)\nADD_SUBDIRECTORY(UChainApp/uc-cli)\n"
  },
  {
    "path": "src/README.md",
    "content": "those primary source code for uc in blockchain layer\n"
  },
  {
    "path": "src/UChain/README.md",
    "content": "those base libs for uc\n"
  },
  {
    "path": "src/UChain/blockchain/CMakeLists.txt",
    "content": "FILE(GLOB_RECURSE blockchain_SOURCES \"*.cpp\")\n\nADD_DEFINITIONS(-DBCB_STATIC=1 -DWITH_CONSENSUS)\nADD_LIBRARY(blockchain_static STATIC ${blockchain_SOURCES})\nSET_TARGET_PROPERTIES(blockchain_static PROPERTIES OUTPUT_NAME uc_blockchain)\nTARGET_LINK_LIBRARIES(blockchain_static ${Boost_LIBRARIES} ${txs_LIBRARY} ${bitcoin_LIBRARY} ${data_LIBRARY} ${database_LIBRARY} ${consensus_LIBRARY})\nINSTALL(TARGETS blockchain_static DESTINATION lib)\n\nIF(ENABLE_SHARED_LIBS)\n    ADD_DEFINITIONS(-DBCB_DLL=1 -DWITH_CONSENSUS)\n  ADD_LIBRARY(blockchain_shared SHARED ${blockchain_SOURCES})\n  SET_TARGET_PROPERTIES(blockchain_shared PROPERTIES OUTPUT_NAME uc_blockchain)\n  TARGET_LINK_LIBRARIES(blockchain_shared ${Boost_LIBRARIES} ${txs_LIBRARY} ${bitcoin_LIBRARY} ${data_LIBRARY} ${database_LIBRARY} ${consensus_LIBRARY})\n  INSTALL(TARGETS blockchain_shared DESTINATION lib)\nENDIF()\n"
  },
  {
    "path": "src/UChain/blockchain/block.cpp",
    "content": "/*\n * Copyright (c) 2011-2018 libbitcoin developers\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/blockchain/block.hpp>\n\n#include <cstdint>\n#include <UChain/coin.hpp>\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\n\nusing namespace chain;\n\nu256 block_work(u256 bits)\n{\n    return bits;\n}\n\nblock::indexes block_locator_indexes(size_t top_height)\n{\n    BITCOIN_ASSERT(top_height <= bc::max_int64);\n    const auto top_height64 = static_cast<int64_t>(top_height);\n\n    block::indexes indexes;\n\n    // Modify the step in the iteration.\n    int64_t step = 1;\n\n    // Start at the top of the chain and work backwards.\n    for (auto index = top_height64; index > 0; index -= step)\n    {\n        // Push top 10 indexes first, then back off exponentially.\n        if (indexes.size() >= 10)\n            step <<= 1;\n\n        indexes.push_back(static_cast<size_t>(index));\n    }\n\n    //  Push the genesis block index.\n    indexes.push_back(0);\n    return indexes;\n}\n\n} // namespace blockchain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/blockchain/block_chain_impl.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/blockchain/block_chain_impl.hpp>\n\n#include <cstddef>\n#include <cstdint>\n#include <memory>\n#include <string>\n#include <algorithm>\n#include <algorithm>\n#include <utility>\n#include <unordered_map>\n#include <boost/filesystem.hpp>\n#include <boost/interprocess/sync/file_lock.hpp>\n#include <UChain/coin.hpp>\n#include <UChainService/txs/token/token_cert.hpp>\n#include <UChain/database.hpp>\n#include <UChain/blockchain/block.hpp>\n#include <UChain/blockchain/block_fetcher.hpp>\n#include <UChain/blockchain/organizer.hpp>\n#include <UChain/blockchain/settings.hpp>\n#include <UChain/blockchain/tx_pool.hpp>\n#include <UChain/blockchain/validate_tx_engine.hpp>\n#include <UChain/blockchain/wallet_security_strategy.hpp>\nnamespace libbitcoin\n{\nnamespace blockchain\n{\n\n////#define NAME \"blockchain\"\n\nusing namespace bc::chain;\nusing namespace bc::database;\nusing namespace boost::interprocess;\nusing namespace std::placeholders;\nusing boost::filesystem::path;\n\nblock_chain_impl::block_chain_impl(threadpool &pool,\n                                   const blockchain::settings &chain_settings,\n                                   const database::settings &database_settings)\n    : stopped_(true),\n      settings_(chain_settings),\n      organizer_(pool, *this, chain_settings),\n      ////read_dispatch_(pool, NAME),\n      ////write_dispatch_(pool, NAME),\n      tx_pool_(pool, *this, chain_settings),\n      database_(database_settings)\n{\n}\n\n// Close does not call stop because there is no way to detect thread join.\nblock_chain_impl::~block_chain_impl()\n{\n    close();\n}\n\n// Utilities.\n// ----------------------------------------------------------------------------\n\nstatic hash_list to_hashes(const block_result &result)\n{\n    const auto count = result.transaction_count();\n    hash_list hashes;\n    hashes.reserve(count);\n\n    for (size_t index = 0; index < count; ++index)\n        hashes.push_back(result.transaction_hash(index));\n\n    return hashes;\n}\n\n// Properties.\n// ----------------------------------------------------------------------------\n\ntx_pool &block_chain_impl::pool()\n{\n    return tx_pool_;\n}\n\nconst settings &block_chain_impl::chain_settings() const\n{\n    return settings_;\n}\n\n// Startup and shutdown.\n// ----------------------------------------------------------------------------\n\n// Start is required and the blockchain is restartable.\nbool block_chain_impl::start()\n{\n    if (!stopped() || !database_.start())\n        return false;\n\n    stopped_ = false;\n    organizer_.start();\n    tx_pool_.start();\n\n    //init the single instance here, to avoid multi-thread init confilict\n    auto *temp = wallet_security_strategy::get_instance();\n\n    return true;\n}\n\n// Stop is not required, speeds work shutdown with multiple threads.\nbool block_chain_impl::stop()\n{\n    stopped_ = true;\n    organizer_.stop();\n    tx_pool_.stop();\n    return database_.stop();\n}\n\n// Database threads must be joined before close is called (or destruct).\nbool block_chain_impl::close()\n{\n    return database_.close();\n}\n\n// private\nbool block_chain_impl::stopped() const\n{\n    // TODO: consider relying on the database stopped state.\n    return stopped_;\n}\n\n// Subscriber\n// ------------------------------------------------------------------------\n\nvoid block_chain_impl::subscribe_reorganize(reorganize_handler handler)\n{\n    // Pass this through to the organizer, which issues the notifications.\n    organizer_.subscribe_reorganize(handler);\n}\n\n// simple_chain (no locks, not thread safe).\n// ----------------------------------------------------------------------------\n\nbool block_chain_impl::get_gap_range(uint64_t &out_first,\n                                     uint64_t &out_last) const\n{\n    size_t first;\n    size_t last;\n\n    if (!database_.blocks.gap_range(first, last))\n        return false;\n\n    out_first = static_cast<uint64_t>(first);\n    out_last = static_cast<uint64_t>(last);\n    return true;\n}\n\nbool block_chain_impl::get_next_gap(uint64_t &out_height,\n                                    uint64_t start_height) const\n{\n    if (stopped())\n        return false;\n\n    BITCOIN_ASSERT(start_height <= bc::max_size_t);\n    const auto start = static_cast<size_t>(start_height);\n    size_t out;\n\n    if (database_.blocks.next_gap(out, start))\n    {\n        out_height = static_cast<uint64_t>(out);\n        return true;\n    }\n\n    return false;\n}\n\nbool block_chain_impl::get_difficulty(u256 &out_difficulty,\n                                      uint64_t height) const\n{\n    size_t top;\n    if (!database_.blocks.top(top))\n        return false;\n\n    out_difficulty = 0;\n    for (uint64_t index = height; index <= top; ++index)\n    {\n        const auto bits = database_.blocks.get(index).header().timestamp;\n        out_difficulty += block_work(bits);\n    }\n\n    return true;\n}\n\nbool block_chain_impl::get_header(header &out_header, uint64_t height) const\n{\n    auto result = database_.blocks.get(height);\n    if (!result)\n        return false;\n\n    out_header = result.header();\n    return true;\n}\n\nbool block_chain_impl::get_height(uint64_t &out_height,\n                                  const hash_digest &block_hash) const\n{\n    auto result = database_.blocks.get(block_hash);\n    if (!result)\n        return false;\n\n    out_height = result.height();\n    return true;\n}\n\nbool block_chain_impl::get_last_height(uint64_t &out_height) const\n{\n    size_t top;\n    if (database_.blocks.top(top))\n    {\n        out_height = static_cast<uint64_t>(top);\n        return true;\n    }\n\n    return false;\n}\n\nbool block_chain_impl::get_outpoint_transaction(hash_digest &out_transaction,\n                                                const output_point &outpoint) const\n{\n    const auto spend = database_.spends.get(outpoint);\n    if (!spend.valid)\n        return false;\n\n    out_transaction = spend.hash;\n    return true;\n}\n\nbool block_chain_impl::get_transaction(transaction &out_transaction,\n                                       uint64_t &out_block_height, const hash_digest &transaction_hash) const\n{\n    const auto result = database_.transactions.get(transaction_hash);\n    if (!result)\n        return false;\n\n    out_transaction = result.transaction();\n    out_block_height = result.height();\n    return true;\n}\n\n// This is safe to call concurrently (but with no other methods).\nbool block_chain_impl::import(block::ptr block, uint64_t height)\n{\n    if (stopped())\n        return false;\n\n    // THIS IS THE DATABASE BLOCK WRITE AND INDEX OPERATION.\n    database_.push(*block, height);\n    return true;\n}\n\nbool block_chain_impl::push(block_info::ptr block)\n{\n    database_.push(*block->actual());\n    return true;\n}\n\nbool block_chain_impl::pop_from(block_info::list &out_blocks,\n                                uint64_t height)\n{\n    size_t top;\n\n    // The chain has no genesis block, fail.\n    if (!database_.blocks.top(top))\n        return false;\n\n    BITCOIN_ASSERT_MSG(top <= max_size_t - 1, \"chain overflow\");\n\n    // The fork is at the top of the chain, nothing to pop.\n    if (height == top + 1)\n        return true;\n\n    // The fork is disconnected from the chain, fail.\n    if (height > top)\n        return false;\n\n    // If the fork is at the top there is one block to pop, and so on.\n    out_blocks.reserve(top - height + 1);\n\n    for (uint64_t index = top; index >= height; --index)\n    {\n        const auto block = std::make_shared<block_info>(database_.pop());\n        out_blocks.push_back(block);\n    }\n\n    return true;\n}\n\n// block_chain (internal locks).\n// ----------------------------------------------------------------------------\n\nvoid block_chain_impl::start_write()\n{\n    DEBUG_ONLY(const auto result =)\n    database_.begin_write();\n    BITCOIN_ASSERT(result);\n}\n\nvoid block_chain_impl::stop_write()\n{\n    DEBUG_ONLY(const auto result =)\n    database_.end_write();\n    BITCOIN_ASSERT(result);\n}\n\n// This call is sequential, but we are preserving the callback model for now.\nvoid block_chain_impl::store(message::block_msg::ptr block,\n                             block_store_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped, 0);\n        return;\n    }\n\n    // We moved write to the network thread using a critical section here.\n    // We do not want to give the thread to any other activity at this point.\n    // A flood of valid orphans from multiple peers could tie up the CPU here,\n    // but resolving that cleanly requires removing the orphan pool.\n\n    ////write_dispatch_.ordered(\n    ////    std::bind(&block_chain_impl::do_store,\n    ////        this, block, handler));\n\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section.\n    unique_lock lock(mutex_);\n\n    do_store(block, handler);\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n// This processes the block through the organizer.\nvoid block_chain_impl::do_store(message::block_msg::ptr block,\n                                block_store_handler handler)\n{\n    start_write();\n\n    // fail fast if the block is already stored...\n    if (database_.blocks.get(block->header.hash()))\n    {\n        stop_write(handler, error::duplicate, 0);\n        return;\n    }\n\n    const auto detail = std::make_shared<block_info>(block);\n\n    // ...or if the block is already orphaned.\n    if (!organizer_.add(detail))\n    {\n        stop_write(handler, error::duplicate, 0);\n        return;\n    }\n\n    // Otherwise organize the chain...\n    organizer_.organize();\n\n    //...and then get the particular block's status.\n    stop_write(handler, detail->error(), detail->height());\n}\n\n///////////////////////////////////////////////////////////////////////////////\n// TODO: This should be ordered on channel distacher (modify channel queries).\n// This allows channels to run concurrently with internal order preservation.\n///////////////////////////////////////////////////////////////////////////////\n// This performs a query in the context of the calling thread.\n// The callback model is preserved currently in order to limit downstream changes.\n// This change allows the caller to manage worker threads.\nvoid block_chain_impl::fetch_serial(perform_read_functor perform_read)\n{\n    // Post IBD writes are ordered on the strand, so never concurrent.\n    // Reads are unordered and concurrent, but effectively blocked by writes.\n    const auto try_read = [this, perform_read]() {\n        const auto handle = database_.begin_read();\n        return (!database_.is_write_locked(handle) && perform_read(handle));\n    };\n\n    const auto do_read = [try_read]() {\n        // Sleep while waiting for write to complete.\n        while (!try_read())\n            std::this_thread::sleep_for(asio::milliseconds(10));\n    };\n\n    // Initiate serial read operation.\n    do_read();\n}\n\n////void block_chain_impl::fetch_parallel(perform_read_functor perform_read)\n////{\n////    // Post IBD writes are ordered on the strand, so never concurrent.\n////    // Reads are unordered and concurrent, but effectively blocked by writes.\n////    const auto try_read = [this, perform_read]()\n////    {\n////        const auto handle = database_.begin_read();\n////        return (!database_.is_write_locked(handle) && perform_read(handle));\n////    };\n////\n////    const auto do_read = [this, try_read]()\n////    {\n////        // Sleep while waiting for write to complete.\n////        while (!try_read())\n////            std::this_thread::sleep_for(std::chrono::milliseconds(10));\n////    };\n////\n////    // Initiate async read operation.\n////    read_dispatch_.concurrent(do_read);\n////}\n\n////// TODO: This should be ordered on the channel's strand, not across channels.\n////void block_chain_impl::fetch_ordered(perform_read_functor perform_read)\n////{\n////    // Writes are ordered on the strand, so never concurrent.\n////    // Reads are unordered and concurrent, but effectively blocked by writes.\n////    const auto try_read = [this, perform_read]() -> bool\n////    {\n////        const auto handle = database_.begin_read();\n////        return (!database_.is_write_locked(handle) && perform_read(handle));\n////    };\n////\n////    const auto do_read = [this, try_read]()\n////    {\n////        // Sleep while waiting for write to complete.\n////        while (!try_read())\n////            std::this_thread::sleep_for(std::chrono::milliseconds(10));\n////    };\n////\n////    // Initiate async read operation.\n////    read_dispatch_.ordered(do_read);\n////}\n\n// block_chain (formerly fetch_ordered)\n// ----------------------------------------------------------------------------\n\n// This may generally execute 29+ queries.\n// TODO: collect asynchronous calls in a function invoked directly by caller.\nvoid block_chain_impl::fetch_block_locator(block_locator_fetch_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped, {});\n        return;\n    }\n\n    const auto do_fetch = [this, handler](size_t slock) {\n        hash_list locator;\n        size_t top_height;\n        if (!database_.blocks.top(top_height))\n            return finish_fetch(slock, handler, error::operation_failed,\n                                locator);\n\n        const auto indexes = block_locator_indexes(top_height);\n        for (const auto index : indexes)\n        {\n            hash_digest hash;\n            auto found = false;\n            {\n                const auto result = database_.blocks.get(index);\n                if (result)\n                {\n                    found = true;\n                    hash = result.header().hash();\n                }\n            }\n            if (!found)\n                return finish_fetch(slock, handler, error::not_found, locator);\n\n            locator.push_back(hash);\n        }\n\n        return finish_fetch(slock, handler, error::success, locator);\n    };\n    fetch_serial(do_fetch);\n}\n\n// Fetch start-base-stop|top+1(max 500)\n// This may generally execute 502 but as many as 531+ queries.\nvoid block_chain_impl::fetch_locator_block_hashes(\n    const message::get_blocks &locator, const hash_digest &threshold,\n    size_t limit, locator_block_hashes_fetch_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped, {});\n        return;\n    }\n\n    // This is based on the idea that looking up by block hash to get heights\n    // will be much faster than hashing each retrieved block to test for stop.\n    const auto do_fetch = [this, locator, threshold, limit, handler](\n                              size_t slock) {\n        // Find the first block height.\n        // If no start block is on our chain we start with block 0.\n        size_t start = 0;\n        for (const auto &hash : locator.start_hashes)\n        {\n            const auto result = database_.blocks.get(hash);\n            if (result)\n            {\n                start = result.height();\n                break;\n            }\n        }\n\n        // Find the stop block height.\n        // The maximum stop block is 501 blocks after start (to return 500).\n        size_t stop = start + limit + 1;\n        if (locator.stop_hash != null_hash)\n        {\n            // If the stop block is not on chain we treat it as a null stop.\n            const auto stop_result = database_.blocks.get(locator.stop_hash);\n            if (stop_result)\n                stop = std::min(stop_result.height() + 1, stop);\n        }\n\n        // Find the threshold block height.\n        // If the threshold is above the start it becomes the new start.\n        if (threshold != null_hash)\n        {\n            const auto start_result = database_.blocks.get(threshold);\n            if (start_result)\n                start = std::max(start_result.height(), start);\n        }\n\n        // TODO: This largest portion can be parallelized.\n        // Build the hash list until we hit last or the blockchain top.\n        hash_list hashes;\n        for (size_t index = start + 1; index < stop; ++index)\n        {\n            const auto result = database_.blocks.get(index);\n            if (result)\n            {\n                hashes.push_back(result.header().hash());\n                //                break;\n            }\n        }\n\n        return finish_fetch(slock, handler, error::success, hashes);\n    };\n    fetch_serial(do_fetch);\n}\n\nvoid block_chain_impl::fetch_locator_block_headers(\n    const message::get_headers &locator, const hash_digest &threshold,\n    size_t limit, locator_block_headers_fetch_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped, {});\n        return;\n    }\n\n    // This is based on the idea that looking up by block hash to get heights\n    // will be much faster than hashing each retrieved block to test for stop.\n    const auto do_fetch = [this, locator, threshold, limit, handler](\n                              size_t slock) {\n        // TODO: consolidate this portion with fetch_locator_block_hashes.\n        //---------------------------------------------------------------------\n        // Find the first block height.\n        // If no start block is on our chain we start with block 0.\n        size_t start = 0;\n        for (const auto &hash : locator.start_hashes)\n        {\n            const auto result = database_.blocks.get(hash);\n            if (result)\n            {\n                start = result.height();\n                break;\n            }\n        }\n\n        // Find the stop block height.\n        // The maximum stop block is 501 blocks after start (to return 500).\n        size_t stop = start + limit + 1;\n        if (locator.stop_hash != null_hash)\n        {\n            // If the stop block is not on chain we treat it as a null stop.\n            const auto stop_result = database_.blocks.get(locator.stop_hash);\n            if (stop_result)\n                stop = std::min(stop_result.height() + 1, stop);\n        }\n\n        // Find the threshold block height.\n        // If the threshold is above the start it becomes the new start.\n        if (threshold != null_hash)\n        {\n            const auto start_result = database_.blocks.get(threshold);\n            if (start_result)\n                start = std::max(start_result.height(), start);\n        }\n        //---------------------------------------------------------------------\n\n        // TODO: This largest portion can be parallelized.\n        // Build the hash list until we hit last or the blockchain top.\n        chain::header::list headers;\n        for (size_t index = start + 1; index < stop; ++index)\n        {\n            const auto result = database_.blocks.get(index);\n            if (result)\n            {\n                headers.push_back(result.header());\n                //                break;\n            }\n        }\n\n        return finish_fetch(slock, handler, error::success, headers);\n    };\n    fetch_serial(do_fetch);\n}\n\n// This may execute up to 500 queries.\nvoid block_chain_impl::filter_blocks(message::get_data::ptr message,\n                                     result_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped);\n        return;\n    }\n\n    const auto do_fetch = [this, message, handler](size_t slock) {\n        auto &inventories = message->inventories;\n\n        for (auto it = inventories.begin(); it != inventories.end();)\n            if (it->is_block_type() && database_.blocks.get(it->hash))\n                it = inventories.erase(it);\n            else\n                ++it;\n\n        return finish_fetch(slock, handler, error::success);\n    };\n    fetch_serial(do_fetch);\n}\n\n// BUGBUG: should only remove unspent transactions, other dups ok (BIP30).\nvoid block_chain_impl::filter_transactions(message::get_data::ptr message,\n                                           result_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped);\n        return;\n    }\n\n    const auto do_fetch = [this, message, handler](size_t slock) {\n        auto &inventories = message->inventories;\n\n        for (auto it = inventories.begin(); it != inventories.end();)\n            if (it->is_transaction_type() &&\n                database_.transactions.get(it->hash))\n                it = inventories.erase(it);\n            else\n                ++it;\n\n        return finish_fetch(slock, handler, error::success);\n    };\n    fetch_serial(do_fetch);\n}\n\n/// filter out block hashes that exist in the orphan pool.\nvoid block_chain_impl::filter_orphans(message::get_data::ptr message,\n                                      result_handler handler)\n{\n    organizer_.filter_orphans(message);\n    handler(error::success);\n}\n\n// block_chain (formerly fetch_parallel)\n// ------------------------------------------------------------------------\n\nvoid block_chain_impl::fetch_block(uint64_t height,\n                                   block_fetch_handler handler)\n{\n    blockchain::fetch_block(*this, height, handler);\n}\n\nvoid block_chain_impl::fetch_latest_transactions(uint32_t index, uint32_t count,\n                                                 transactions_fetch_handler handler)\n{\n    uint64_t height;\n    get_last_height(height);\n    blockchain::fetch_latest_transactions(*this, height, index, count, handler);\n}\n\nvoid block_chain_impl::fetch_block(const hash_digest &hash,\n                                   block_fetch_handler handler)\n{\n    blockchain::fetch_block(*this, hash, handler);\n}\n\nvoid block_chain_impl::fetch_block_header(uint64_t height,\n                                          block_header_fetch_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped, {});\n        return;\n    }\n\n    const auto do_fetch = [this, height, handler](size_t slock) {\n        chain::header header;\n        auto found = false;\n        {\n            const auto result = database_.blocks.get(height);\n            if (result)\n            {\n                header = result.header();\n                header.transaction_count = result.transaction_count();\n                found = true;\n            }\n        }\n        return found ? finish_fetch(slock, handler, error::success, header) : finish_fetch(slock, handler, error::not_found, chain::header());\n    };\n    fetch_serial(do_fetch);\n}\n\nvoid block_chain_impl::fetch_block_headers(uint64_t start,\n                                           uint64_t end, bool order, locator_block_headers_fetch_handler handler, uint32_t count)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped, {});\n        return;\n    }\n\n    const auto do_fetch = [this, &start, &end, order, count, handler](size_t slock) {\n        chain::header header;\n        std::vector<chain::header> headers;\n        uint32_t tx_count = 0;\n        while (start <= end)\n        {\n            if ((count && tx_count >= count) || !(start + 1) || !end)\n                break;\n            const auto result = database_.blocks.get((order ? start++ : end--));\n            if (result)\n            {\n                chain::header header = result.header();\n                header.transaction_count = result.transaction_count();\n                tx_count += result.transaction_count();\n                headers.push_back(header);\n            }\n        }\n\n        return headers.size() ? finish_fetch(slock, handler, error::success, headers) : finish_fetch(slock, handler, error::not_found, vector<chain::header>{});\n    };\n    fetch_serial(do_fetch);\n}\n\nvoid block_chain_impl::fetch_block_header(const hash_digest &hash,\n                                          block_header_fetch_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped, {});\n        return;\n    }\n\n    const auto do_fetch = [this, hash, handler](size_t slock) {\n        chain::header header;\n        auto found = false;\n        {\n            const auto result = database_.blocks.get(hash);\n            if (result)\n            {\n                header = result.header();\n                header.transaction_count = result.transaction_count();\n                found = true;\n            }\n        }\n        return found ? finish_fetch(slock, handler, error::success, header) : finish_fetch(slock, handler, error::not_found, chain::header());\n    };\n    fetch_serial(do_fetch);\n}\n\nvoid block_chain_impl::fetch_merkle_block(uint64_t height,\n                                          merkle_block_fetch_handler handler)\n{\n    // TODO:\n    ////blockchain::fetch_merkle_block(*this, height, handler);\n    handler(error::operation_failed, {});\n}\n\nvoid block_chain_impl::fetch_merkle_block(const hash_digest &hash,\n                                          merkle_block_fetch_handler handler)\n{\n    // TODO:\n    ////blockchain::fetch_merkle_block(*this, hash, handler);\n    handler(error::operation_failed, {});\n}\n\nvoid block_chain_impl::fetch_block_transaction_hashes(uint64_t height,\n                                                      transaction_hashes_fetch_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped, {});\n        return;\n    }\n\n    const auto do_fetch = [this, height, handler](size_t slock) {\n        hash_list hashes;\n        auto found = false;\n        {\n            const auto result = database_.blocks.get(height);\n            if (result)\n            {\n                hashes = to_hashes(result);\n                found = true;\n            }\n        }\n\n        return found ? finish_fetch(slock, handler, error::success, hashes) : finish_fetch(slock, handler, error::not_found, hash_list());\n    };\n    fetch_serial(do_fetch);\n}\n\nvoid block_chain_impl::fetch_block_transaction_hashes(const hash_digest &hash,\n                                                      transaction_hashes_fetch_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped, {});\n        return;\n    }\n\n    const auto do_fetch = [this, hash, handler](size_t slock) {\n        hash_list hashes;\n        auto found = false;\n        {\n            const auto result = database_.blocks.get(hash);\n            if (result)\n            {\n                hashes = to_hashes(result);\n                found = true;\n            }\n        }\n\n        return found ? finish_fetch(slock, handler, error::success, hashes) : finish_fetch(slock, handler, error::not_found, hash_list());\n    };\n    fetch_serial(do_fetch);\n}\n\nvoid block_chain_impl::fetch_block_height(const hash_digest &hash,\n                                          block_height_fetch_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped, {});\n        return;\n    }\n\n    const auto do_fetch = [this, hash, handler](size_t slock) {\n        std::size_t h{0};\n        auto found = false;\n        {\n            const auto result = database_.blocks.get(hash);\n            if (result)\n            {\n                h = result.height();\n                found = true;\n            }\n        }\n\n        return found ? finish_fetch(slock, handler, error::success, h) : finish_fetch(slock, handler, error::not_found, 0);\n    };\n    fetch_serial(do_fetch);\n}\n\nvoid block_chain_impl::fetch_last_height(last_height_fetch_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped, {});\n        return;\n    }\n\n    const auto do_fetch = [this, handler](size_t slock) {\n        size_t last_height;\n        return database_.blocks.top(last_height) ? finish_fetch(slock, handler, error::success, last_height) : finish_fetch(slock, handler, error::not_found, 0);\n    };\n    fetch_serial(do_fetch);\n}\n\nvoid block_chain_impl::fetch_transaction(const hash_digest &hash,\n                                         transaction_fetch_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped, {});\n        return;\n    }\n\n    const auto do_fetch = [this, hash, handler](size_t slock) {\n        const auto result = database_.transactions.get(hash);\n        const auto tx = result ? result.transaction() : chain::transaction();\n        return result ? finish_fetch(slock, handler, error::success, tx) : finish_fetch(slock, handler, error::not_found, tx);\n    };\n    fetch_serial(do_fetch);\n}\n\nvoid block_chain_impl::fetch_transaction_index(const hash_digest &hash,\n                                               transaction_index_fetch_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped, {}, {});\n        return;\n    }\n\n    const auto do_fetch = [this, hash, handler](size_t slock) {\n        const auto result = database_.transactions.get(hash);\n        return result ? finish_fetch(slock, handler, error::success, result.height(),\n                                     result.index())\n                      : finish_fetch(slock, handler, error::not_found, 0, 0);\n    };\n    fetch_serial(do_fetch);\n}\n\nvoid block_chain_impl::fetch_spend(const chain::output_point &outpoint,\n                                   spend_fetch_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped, {});\n        return;\n    }\n\n    const auto do_fetch = [this, outpoint, handler](size_t slock) {\n        const auto spend = database_.spends.get(outpoint);\n        const auto point = spend.valid ? chain::input_point{spend.hash, spend.index} : chain::input_point();\n        return spend.valid ? finish_fetch(slock, handler, error::success, point) : finish_fetch(slock, handler, error::unspent_output, point);\n    };\n    fetch_serial(do_fetch);\n}\n\nvoid block_chain_impl::fetch_history(const bc::wallet::payment_address &address,\n                                     uint64_t limit, uint64_t from_height, history_fetch_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped, {});\n        return;\n    }\n\n    const auto do_fetch = [this, address, handler, limit, from_height](\n                              size_t slock) {\n        const auto history = database_.history.get(address.hash(), limit,\n                                                   from_height);\n        return finish_fetch(slock, handler, error::success, history);\n    };\n    fetch_serial(do_fetch);\n}\n\nbool block_chain_impl::fetch_history(const bc::wallet::payment_address &address,\n                                     uint64_t limit, uint64_t from_height, history_compact::list &history)\n{\n    if (stopped())\n    {\n        return false;\n    }\n\n    boost::mutex mutex;\n\n    mutex.lock();\n    auto f = [&history, &mutex](const code &ec, const history_compact::list &history_) -> void {\n        if ((code)error::success == ec)\n            history = history_;\n        mutex.unlock();\n    };\n\n    // Obtain payment address history from the blockchain.\n    fetch_history(address, limit, from_height, f);\n    boost::unique_lock<boost::mutex> lock(mutex);\n\n    return true;\n}\n\nvoid block_chain_impl::fetch_stealth(const binary &filter, uint64_t from_height,\n                                     stealth_fetch_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped, {});\n        return;\n    }\n\n    const auto do_fetch = [this, filter, handler, from_height](\n                              size_t slock) {\n        const auto stealth = database_.stealth.scan(filter, from_height);\n        return finish_fetch(slock, handler, error::success, stealth);\n    };\n    fetch_serial(do_fetch);\n}\n\ninline hash_digest block_chain_impl::get_hash(const std::string &str)\n{\n    data_chunk data(str.begin(), str.end());\n    return sha256_hash(data);\n}\n\ninline short_hash block_chain_impl::get_short_hash(const std::string &str)\n{\n    data_chunk data(str.begin(), str.end());\n    return ripemd160_hash(data);\n}\n\nstd::shared_ptr<chain::transaction> block_chain_impl::get_spends_output(const input_point &input)\n{\n    const auto spend = database_.spends.get(input);\n    if (spend.valid)\n    {\n\n        const auto result = database_.transactions.get(spend.hash);\n        if (result)\n        {\n            return std::make_shared<chain::transaction>(result.transaction());\n        }\n    }\n\n    return nullptr;\n}\n\nstd::shared_ptr<libbitcoin::chain::wallet> block_chain_impl::is_wallet_passwd_valid(const std::string &name, const std::string &passwd)\n{\n    //added by chengzhiping to protect wallets from brute force password attacks.\n    auto *ass = wallet_security_strategy::get_instance();\n    ass->check_locked(name);\n\n    auto wallet = get_wallet(name);\n    if (wallet && wallet->get_passwd() == get_hash(passwd))\n    { // wallet exist\n        ass->on_auth_passwd(name, true);\n        return wallet;\n    }\n\n    ass->on_auth_passwd(name, false);\n    throw std::logic_error{\"wallet not found or incorrect password\"};\n    return nullptr;\n}\n\nstd::string block_chain_impl::is_wallet_lastwd_valid(const libbitcoin::chain::wallet &acc, std::string &auth, const std::string &lastwd)\n{\n    //added by chengzhiping to protect wallets from brute force password attacks.\n    auto *ass = wallet_security_strategy::get_instance();\n\n    std::string mnemonic;\n    acc.get_mnemonic(auth, mnemonic);\n    auto &&results = bc::split(mnemonic, \" \", true); // with trim\n    if (*results.rbegin() != lastwd)\n    {\n        ass->on_auth_lastwd(acc.get_name(), false);\n        throw std::logic_error{\"last word not matching.\"};\n    }\n\n    ass->on_auth_lastwd(acc.get_name(), true);\n\n    return mnemonic;\n}\n\nvoid block_chain_impl::set_wallet_passwd(const std::string &name, const std::string &passwd)\n{\n    auto wallet = get_wallet(name);\n    if (wallet)\n    {\n        wallet->set_passwd(passwd);\n        store_wallet(wallet);\n    }\n    else\n    {\n        throw std::logic_error{\"wallet not found\"};\n    }\n}\n\nbool block_chain_impl::is_admin_wallet(const std::string &name)\n{\n    auto wallet = get_wallet(name);\n    if (wallet)\n    {\n        return wallet_priority::administrator == wallet->get_priority();\n    }\n    return false;\n}\n\nbool block_chain_impl::is_wallet_exist(const std::string &name)\n{\n    return nullptr != get_wallet(name);\n}\n\noperation_result block_chain_impl::store_wallet(std::shared_ptr<libbitcoin::chain::wallet> acc)\n{\n    if (stopped())\n    {\n        return operation_result::failure;\n    }\n\n    if (!(acc))\n    {\n        throw std::runtime_error{\"nullptr for wallet\"};\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section.\n    unique_lock lock(mutex_);\n\n    database_.wallets.store(*acc);\n    database_.wallets.sync();\n    ///////////////////////////////////////////////////////////////////////////\n    return operation_result::okay;\n}\n\nstd::shared_ptr<libbitcoin::chain::wallet> block_chain_impl::get_wallet(const std::string &name)\n{\n    return database_.wallets.get_wallet_result(get_hash(name)).get_wallet_detail();\n}\n\n/// get all the wallets in wallet database\nstd::shared_ptr<std::vector<libbitcoin::chain::wallet>> block_chain_impl::get_wallets()\n{\n    return database_.wallets.get_wallets();\n}\n\n/// delete wallet according wallet name\noperation_result block_chain_impl::delete_wallet(const std::string &name)\n{\n    if (stopped())\n    {\n        return operation_result::failure;\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section.\n    unique_lock lock(mutex_);\n\n    database_.wallets.remove(get_hash(name));\n    database_.wallets.sync();\n    ///////////////////////////////////////////////////////////////////////////\n    return operation_result::okay;\n}\n\n/// just store data into database \"not do same address check\"  -- todo\noperation_result block_chain_impl::store_wallet_address(std::shared_ptr<wallet_address> address)\n{\n    if (stopped())\n    {\n        return operation_result::failure;\n    }\n\n    if (!address)\n    {\n        throw std::runtime_error{\"nullptr for address\"};\n    }\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section.\n    unique_lock lock(mutex_);\n\n    const auto hash = get_short_hash(address->get_name());\n    database_.wallet_addresses.store(hash, *address);\n    database_.wallet_addresses.sync();\n    ///////////////////////////////////////////////////////////////////////////\n    return operation_result::okay;\n}\n\n/// only delete the last address of wallet\noperation_result block_chain_impl::delete_wallet_address(const std::string &name)\n{\n    if (stopped())\n    {\n        return operation_result::failure;\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section.\n    unique_lock lock(mutex_);\n\n    auto hash = get_short_hash(name);\n    auto addr_vec = database_.wallet_addresses.get(hash);\n    for (auto each : addr_vec)\n        database_.wallet_addresses.delete_last_row(hash);\n    database_.wallet_addresses.sync();\n    ///////////////////////////////////////////////////////////////////////////\n    return operation_result::okay;\n}\n\n/// delete some of the address from the last\noperation_result block_chain_impl::delete_n_wallet_address(const std::string &name, uint64_t count)\n{\n    if (stopped())\n    {\n        return operation_result::failure;\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section.\n    unique_lock lock(mutex_);\n\n    auto hash = get_short_hash(name);\n    auto addr_vec = database_.wallet_addresses.get(hash);\n    if (count >= addr_vec.size())\n        throw std::logic_error{\"Parameter count should less than the count of your address!\"};\n    for (size_t i = 0; i < count; i++)\n        database_.wallet_addresses.delete_last_row(hash);\n    database_.wallet_addresses.sync();\n    ///////////////////////////////////////////////////////////////////////////\n    return operation_result::okay;\n}\n\nstd::shared_ptr<wallet_address> block_chain_impl::get_wallet_address(\n    const std::string &name, const std::string &address)\n{\n    return database_.wallet_addresses.get(get_short_hash(name), address);\n}\n\nstd::shared_ptr<wallet_address::list> block_chain_impl::get_wallet_addresses(\n    const std::string &name)\n{\n    auto sp_addr = std::make_shared<wallet_address::list>();\n    auto result = database_.wallet_addresses.get(get_short_hash(name));\n    if (result.size())\n    {\n        //sp_addr = std::make_shared<wallet_address::list>();\n        const auto action = [&sp_addr](const wallet_address &elem) {\n            sp_addr->emplace_back(std::move(elem));\n        };\n        std::for_each(result.begin(), result.end(), action);\n    }\n    return sp_addr;\n}\n\noperation_result block_chain_impl::store_wallet_token(\n    const token_detail &detail,\n    const string &name)\n{\n    if (stopped())\n    {\n        return operation_result::failure;\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section.\n    unique_lock lock(mutex_);\n\n    const auto hash = get_short_hash(name);\n    database_.wallet_tokens.store(hash, detail);\n    database_.wallet_tokens.sync();\n    ///////////////////////////////////////////////////////////////////////////\n    return operation_result::okay;\n}\n\noperation_result block_chain_impl::store_wallet_token(\n    std::shared_ptr<token_detail> detail,\n    const string &name)\n{\n    if (!(detail))\n    {\n        throw std::runtime_error{\"nullptr for token\"};\n    }\n    return store_wallet_token(*detail, name);\n}\n\n/// delete wallet token by wallet name\noperation_result block_chain_impl::delete_wallet_token(const std::string &name)\n{\n    if (stopped())\n    {\n        return operation_result::failure;\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section.\n    unique_lock lock(mutex_);\n\n    auto hash = get_short_hash(name);\n    auto token_vec = database_.wallet_tokens.get(hash);\n    for (auto each : token_vec) // just use token count\n        database_.wallet_tokens.delete_last_row(hash);\n    database_.wallet_tokens.sync();\n    ///////////////////////////////////////////////////////////////////////////\n    return operation_result::okay;\n}\n\nstd::shared_ptr<business_address_token::list> block_chain_impl::get_wallet_token(\n    const std::string &name, const std::string &token_name, business_kind kind)\n{\n    auto sp_token_vec = get_wallet_tokens(name, kind);\n    auto ret_vector = std::make_shared<business_address_token::list>();\n\n    const auto action = [&](const business_address_token &addr_token) {\n        if (addr_token.detail.get_symbol() == token_name)\n            ret_vector->emplace_back(std::move(addr_token));\n    };\n\n    std::for_each(sp_token_vec->begin(), sp_token_vec->end(), action);\n\n    return ret_vector;\n}\n\nstd::shared_ptr<business_address_token::list> block_chain_impl::get_wallet_token(\n    const std::string &name, const std::string &token_name)\n{\n    auto sp_token_vec = get_wallet_tokens(name);\n    auto ret_vector = std::make_shared<business_address_token::list>();\n\n    const auto action = [&](const business_address_token &addr_token) {\n        if (addr_token.detail.get_symbol() == token_name)\n            ret_vector->emplace_back(std::move(addr_token));\n    };\n\n    std::for_each(sp_token_vec->begin(), sp_token_vec->end(), action);\n\n    return ret_vector;\n}\n\nstatic history::list expand_history(history_compact::list &compact)\n{\n    history::list result;\n    result.reserve(compact.size());\n\n    std::unordered_map<uint64_t, history *> map_output;\n    // Process all outputs.\n    for (auto output = compact.begin(); output != compact.end(); ++output)\n    {\n        if (output->kind == point_kind::output)\n        {\n            history row;\n            row.output = output->point;\n            row.output_height = output->height;\n            row.value = output->value;\n            row.spend = {null_hash, max_uint32};\n            row.temporary_checksum = output->point.checksum();\n            result.emplace_back(row);\n            map_output[row.temporary_checksum] = &result.back();\n        }\n    }\n\n    //process the spends.\n    for (const auto &spend : compact)\n    {\n        if (spend.kind != point_kind::spend)\n            continue;\n\n        auto r = map_output.find(spend.previous_checksum);\n        if (r != map_output.end() && r->second->spend.hash == null_hash)\n        {\n            r->second->spend = spend.point;\n            r->second->spend_height = spend.height;\n            continue;\n        }\n\n        // This will only happen if the history height cutoff comes between\n        // an output and its spend. In this case we return just the spend.\n        {\n            history row;\n            row.output = {null_hash, max_uint32};\n            row.output_height = max_uint64;\n            row.value = max_uint64;\n            row.spend = spend.point;\n            row.spend_height = spend.height;\n            result.emplace_back(row);\n        }\n    }\n\n    compact.clear();\n\n    // Clear all remaining checksums from unspent rows.\n    for (auto &row : result)\n    {\n        if (row.spend.hash == null_hash)\n        {\n            row.spend_height = max_uint64;\n        }\n    }\n\n    // sort by height and index of output(unspend) and spend in order.\n    // 1. unspend before spend\n    // because unspend's spend height is max_uint64,\n    // so sort by spend height decreasely can ensure this.\n    // 2. for spend\n    // spent height first, decreasely\n    // spend index second, decreasely\n    // 3. for unspend\n    // output height first, decreasely\n    // output index second, decreasely\n    std::sort(result.begin(), result.end(),\n              [](const history &elem1, const history &elem2) {\n                  typedef std::tuple<uint64_t, uint64_t, uint64_t, uint64_t> cmp_tuple_t;\n                  cmp_tuple_t tuple1(elem1.spend_height, elem1.spend.index, elem1.output_height, elem1.output.index);\n                  cmp_tuple_t tuple2(elem2.spend_height, elem2.spend.index, elem2.output_height, elem2.output.index);\n                  return tuple1 > tuple2;\n              });\n    return result;\n}\n\nhistory::list block_chain_impl::get_address_history(const bc::wallet::payment_address &addr, bool add_memory_pool, uint64_t from_height)\n{\n    history_compact::list cmp_history;\n    bool result = true;\n    if (add_memory_pool)\n    {\n        result = get_history(addr, 0, from_height, cmp_history);\n    }\n    else\n    {\n        result = fetch_history(addr, 0, from_height, cmp_history);\n    }\n    if (result)\n    {\n        return expand_history(cmp_history);\n    }\n    return history::list();\n}\n\nstd::shared_ptr<token_cert> block_chain_impl::get_wallet_token_cert(\n    const std::string &wallet, const std::string &symbol, token_cert_type cert_type)\n{\n    BITCOIN_ASSERT(!symbol.empty());\n    BITCOIN_ASSERT(cert_type != token_cert_ns::none);\n\n    auto pvaddr = get_wallet_addresses(wallet);\n    if (!pvaddr)\n        return nullptr;\n\n    chain::transaction tx_temp;\n    uint64_t tx_height;\n\n    for (auto &each : *pvaddr)\n    {\n        bc::wallet::payment_address payment_address(each.get_address());\n        auto &&rows = get_address_history(payment_address);\n\n        for (auto &row : rows)\n        {\n            // spend unconfirmed (or no spend attempted)\n            if ((row.spend.hash == null_hash) && get_transaction(row.output.hash, tx_temp, tx_height))\n            {\n                BITCOIN_ASSERT(row.output.index < tx_temp.outputs.size());\n                const auto &output = tx_temp.outputs.at(row.output.index);\n                if (output.is_token_cert())\n                {\n                    auto cert = output.get_token_cert();\n                    if (symbol != cert.get_symbol() || cert_type != cert.get_type())\n                    {\n                        continue;\n                    }\n\n                    return std::make_shared<token_cert>(cert);\n                }\n            }\n        }\n    }\n\n    return nullptr;\n}\n\nstd::shared_ptr<business_address_token_cert::list>\nblock_chain_impl::get_address_token_certs(const std::string &address, const std::string &symbol, token_cert_type cert_type)\n{\n    auto ret_vector = std::make_shared<business_address_token_cert::list>();\n    auto &&business_certs = database_.address_tokens.get_token_certs(address, symbol, cert_type, 0);\n    for (auto &business_cert : business_certs)\n    {\n        ret_vector->emplace_back(std::move(business_cert));\n    }\n    return ret_vector;\n}\n\nstd::shared_ptr<business_address_token_cert::list>\nblock_chain_impl::get_wallet_token_certs(const std::string &wallet, const std::string &symbol, token_cert_type cert_type)\n{\n    auto ret_vector = std::make_shared<business_address_token_cert::list>();\n    auto pvaddr = get_wallet_addresses(wallet);\n    if (pvaddr)\n    {\n        for (const auto &wallet_address : *pvaddr)\n        {\n            auto &&business_certs = database_.address_tokens.get_token_certs(wallet_address.get_address(), symbol, cert_type, 0);\n            for (auto &business_cert : business_certs)\n            {\n                ret_vector->emplace_back(std::move(business_cert));\n            }\n        }\n    }\n    return ret_vector;\n}\n\nstd::shared_ptr<token_cert::list> block_chain_impl::get_issued_token_certs()\n{\n    auto sp_vec = std::make_shared<token_cert::list>();\n    auto sp_token_certs_vec = database_.certs.get_blockchain_token_certs();\n    for (const auto &each : *sp_token_certs_vec)\n        sp_vec->emplace_back(std::move(each));\n    return sp_vec;\n}\n\nbool block_chain_impl::is_token_cert_exist(const std::string &symbol, token_cert_type cert_type)\n{\n    BITCOIN_ASSERT(!symbol.empty());\n\n    auto &&key_str = token_cert::get_key(symbol, cert_type);\n    const auto key = get_hash(key_str);\n    return database_.certs.get(key) != nullptr;\n}\n\nbool block_chain_impl::is_candidate_exist(const std::string &symbol)\n{\n    return get_registered_candidate(symbol) != nullptr;\n}\n\nstd::shared_ptr<candidate_info> block_chain_impl::get_registered_candidate(const std::string &symbol)\n{\n    BITCOIN_ASSERT(!symbol.empty());\n    // return the registered identifiable token, its status must be CANDIDATE_STATUS_REGISTER\n    return database_.candidates.get(get_hash(symbol));\n}\n\nstd::shared_ptr<candidate_info::list> block_chain_impl::get_registered_candidates()\n{\n    // return the registered identifiable tokens, their status must be CANDIDATE_STATUS_REGISTER\n    return database_.candidates.get_blockchain_candidates();\n}\n\nbool block_chain_impl::exist_in_candidates(std::string uid)\n{\n    auto sh_vec = get_registered_candidates();\n    if (nullptr != sh_vec)\n    {\n        auto pred = [uid](libbitcoin::chain::candidate_info &info) {\n            return info.to_uid == uid;\n        };\n        return std::find_if(sh_vec->begin(), sh_vec->end(), pred) != sh_vec->end();\n    }\n    return false;\n}\n\nstd::shared_ptr<candidate_info::list> block_chain_impl::get_candidate_history(\n    const std::string &symbol, uint64_t limit, uint64_t page_number)\n{\n    BITCOIN_ASSERT(!symbol.empty());\n    // return the identifiable tokens of specified symbol, the last item's status must be CANDIDATE_STATUS_REGISTER\n    return database_.candidate_history.get_history_candidates_by_height(get_short_hash(symbol), 0, 0, limit, page_number);\n}\n\nstd::shared_ptr<candidate::list> block_chain_impl::get_wallet_candidates(\n    const std::string &wallet, const std::string &symbol)\n{\n    auto sp_vec = std::make_shared<candidate::list>();\n\n    auto pvaddr = get_wallet_addresses(wallet);\n    if (!pvaddr)\n        return sp_vec;\n\n    chain::transaction tx_temp;\n    uint64_t tx_height;\n\n    for (auto &each : *pvaddr)\n    {\n        bc::wallet::payment_address payment_address(each.get_address());\n        auto &&rows = get_address_history(payment_address);\n\n        for (auto &row : rows)\n        {\n            // spend unconfirmed (or no spend attempted)\n            if ((row.spend.hash == null_hash) && get_transaction(row.output.hash, tx_temp, tx_height))\n            {\n                BITCOIN_ASSERT(row.output.index < tx_temp.outputs.size());\n                const auto &output = tx_temp.outputs.at(row.output.index);\n                if (output.is_candidate())\n                {\n                    auto &&token = output.get_candidate();\n                    if (symbol.empty())\n                    {\n                        sp_vec->emplace_back(std::move(token));\n                    }\n                    else if (symbol == token.get_symbol())\n                    {\n                        sp_vec->emplace_back(std::move(token));\n                        return sp_vec;\n                    }\n                }\n            }\n        }\n    }\n\n    return sp_vec;\n}\n\nuint64_t block_chain_impl::get_address_token_volume(const std::string &addr, const std::string &token)\n{\n    uint64_t token_volume = 0;\n    auto address = payment_address(addr);\n    auto &&rows = get_address_history(address);\n\n    chain::transaction tx_temp;\n    uint64_t tx_height;\n\n    for (auto &row : rows)\n    {\n        // spend unconfirmed (or no spend attempted)\n        if ((row.spend.hash == null_hash) && get_transaction(tx_temp, tx_height, row.output.hash))\n        {\n            auto output = tx_temp.outputs.at(row.output.index);\n            if ((output.is_token_transfer() || output.is_token_issue() || output.is_token_secondaryissue()))\n            {\n                if (output.get_token_symbol() == token)\n                {\n                    token_volume += output.get_token_amount();\n                }\n            }\n        }\n    }\n\n    return token_volume;\n}\n\nuint64_t block_chain_impl::get_wallet_token_volume(const std::string &wallet, const std::string &token)\n{\n    uint64_t volume = 0;\n    auto pvaddr = get_wallet_addresses(wallet);\n    if (pvaddr)\n    {\n        for (auto &each : *pvaddr)\n        {\n            volume += get_address_token_volume(each.get_address(), token);\n        }\n    }\n\n    return volume;\n}\n\nuint64_t block_chain_impl::get_token_volume(const std::string &token)\n{\n    return database_.tokens.get_token_volume(token);\n}\n\nstd::string block_chain_impl::get_token_symbol_from_asset_data(const asset_data &data)\n{\n    std::string token_symbol(\"\");\n    if (data.get_kind_value() == business_kind::token_issue)\n    {\n        auto detail = boost::get<token_detail>(data.get_data());\n        token_symbol = detail.get_symbol();\n    }\n    else if (data.get_kind_value() == business_kind::token_transfer)\n    {\n        auto transfer = boost::get<token_transfer>(data.get_data());\n        token_symbol = transfer.get_symbol();\n    }\n    else if (data.get_kind_value() == business_kind::token_cert)\n    {\n        auto cert = boost::get<token_cert>(data.get_data());\n        token_symbol = cert.get_symbol();\n    }\n    return token_symbol;\n}\n\n// get special tokens of the wallet/name, just used for token_detail/token_transfer\nstd::shared_ptr<business_history::list> block_chain_impl::get_address_business_history(const std::string &addr,\n                                                                                       const std::string &symbol, business_kind kind, uint8_t confirmed)\n{\n    auto ret_vector = std::make_shared<business_history::list>();\n    auto sh_vec = database_.address_tokens.get_address_business_history(addr, 0);\n\n    for (auto iter = sh_vec->begin(); iter != sh_vec->end(); ++iter)\n    {\n        if ((iter->data.get_kind_value() != kind) || (iter->status != confirmed))\n            continue;\n\n        // ucn business process\n        if (kind == business_kind::ucn)\n        {\n            ret_vector->emplace_back(std::move(*iter));\n            continue;\n        }\n\n        // ucn award business process\n        if (kind == business_kind::ucn_award)\n        {\n            ret_vector->emplace_back(std::move(*iter));\n            continue;\n        }\n\n        // token business process\n        std::string &&token_symbol = get_token_symbol_from_asset_data(iter->data);\n        if (symbol == token_symbol)\n        {\n            ret_vector->emplace_back(std::move(*iter));\n        }\n    }\n\n    return ret_vector;\n}\n\n// get special tokens of the wallet/name, just used for token_detail/token_transfer\nstd::shared_ptr<business_record::list> block_chain_impl::get_address_business_record(const std::string &addr,\n                                                                                     uint64_t start, uint64_t end, const std::string &symbol)\n{\n    auto ret_vector = std::make_shared<business_record::list>();\n    auto sh_vec = database_.address_tokens.get(addr, start, end);\n\n    if (symbol.empty())\n    { // all utxo\n        for (auto iter = sh_vec->begin(); iter != sh_vec->end(); ++iter)\n        {\n            ret_vector->emplace_back(std::move(*iter));\n        }\n    }\n    else\n    { // token symbol utxo\n        for (auto iter = sh_vec->begin(); iter != sh_vec->end(); ++iter)\n        {\n            // token business process\n            std::string &&token_symbol = get_token_symbol_from_asset_data(iter->data);\n            if (symbol == token_symbol)\n            {\n                ret_vector->emplace_back(std::move(*iter));\n            }\n        }\n    }\n\n    return ret_vector;\n}\n\n// get special tokens of the wallet/name, just used for token_detail/token_transfer\nstd::shared_ptr<business_record::list> block_chain_impl::get_address_business_record(const std::string &address,\n                                                                                     const std::string &symbol, size_t start_height, size_t end_height, uint64_t limit, uint64_t page_number) const\n{\n    return database_.address_tokens.get(address, symbol, start_height, end_height, limit, page_number);\n}\n\n// get special tokens of the wallet/name, just used for token_detail/token_transfer\nstd::shared_ptr<business_history::list> block_chain_impl::get_address_business_history(const std::string &addr,\n                                                                                       business_kind kind, uint8_t confirmed)\n{\n    auto sp_token_vec = std::make_shared<business_history::list>();\n\n    business_history::list token_vec = database_.address_tokens.get_business_history(addr, 0, kind, confirmed);\n    const auto add_token = [&](const business_history &addr_token) {\n        sp_token_vec->emplace_back(std::move(addr_token));\n    };\n    std::for_each(token_vec.begin(), token_vec.end(), add_token);\n\n    return sp_token_vec;\n}\n\n// get wallet owned business history between begin and end\nstd::shared_ptr<business_history::list> block_chain_impl::get_wallet_business_history(const std::string &name,\n                                                                                      business_kind kind, uint32_t time_begin, uint32_t time_end)\n{\n    auto wallet_addr_vec = get_wallet_addresses(name);\n    auto sp_token_vec = std::make_shared<business_history::list>();\n\n    // copy each token_vec element to sp_token\n    const auto add_token = [&](const business_history &addr_token) {\n        sp_token_vec->emplace_back(std::move(addr_token));\n    };\n\n    // search all tokens belongs to this address which is owned by wallet\n    const auto action = [&](const wallet_address &elem) {\n        auto token_vec = database_.address_tokens.get_business_history(elem.get_address(), 0, kind, time_begin, time_end);\n        std::for_each(token_vec.begin(), token_vec.end(), add_token);\n    };\n    std::for_each(wallet_addr_vec->begin(), wallet_addr_vec->end(), action);\n\n    return sp_token_vec;\n}\n\nstd::shared_ptr<business_history::list> block_chain_impl::get_address_business_history(const std::string &addr,\n                                                                                       business_kind kind, uint32_t time_begin, uint32_t time_end)\n{\n    auto sp_token_vec = std::make_shared<business_history::list>();\n\n    business_history::list token_vec = database_.address_tokens.get_business_history(addr, 0, kind, time_begin, time_end);\n    const auto add_token = [&](const business_history &addr_token) {\n        sp_token_vec->emplace_back(std::move(addr_token));\n    };\n    std::for_each(token_vec.begin(), token_vec.end(), add_token);\n\n    return sp_token_vec;\n}\n\nstd::shared_ptr<business_history::list> block_chain_impl::get_address_business_history(const std::string &addr)\n{\n    auto sp_token_vec = std::make_shared<business_history::list>();\n    auto key = get_short_hash(addr);\n    business_history::list token_vec = database_.address_tokens.get_business_history(key, 0);\n    const auto add_token = [&](const business_history &addr_token) {\n        sp_token_vec->emplace_back(std::move(addr_token));\n    };\n    std::for_each(token_vec.begin(), token_vec.end(), add_token);\n\n    return sp_token_vec;\n}\n\n/// get business record according address\nstd::shared_ptr<business_record::list> block_chain_impl::get_address_business_record(const std::string &addr,\n                                                                                     size_t from_height, size_t limit)\n{\n    auto sp_token_vec = std::make_shared<business_record::list>();\n    auto key = get_short_hash(addr);\n    business_record::list token_vec = database_.address_tokens.get(key, from_height, limit);\n    const auto add_token = [&](const business_record &addr_token) {\n        sp_token_vec->emplace_back(std::move(addr_token));\n    };\n    std::for_each(token_vec.begin(), token_vec.end(), add_token);\n\n    return sp_token_vec;\n}\n\n// get all tokens belongs to the wallet/name\nstd::shared_ptr<business_address_token::list> block_chain_impl::get_wallet_tokens(\n    const std::string &name)\n{\n    return get_wallet_tokens(name, business_kind::unknown);\n}\n\n// get special tokens of the wallet/name, just used for token_detail/token_transfer\nstd::shared_ptr<business_address_token::list> block_chain_impl::get_wallet_tokens(\n    const std::string &name, business_kind kind)\n{\n    auto wallet_addr_vec = get_wallet_addresses(name);\n    auto sp_token_vec = std::make_shared<business_address_token::list>();\n\n    // copy each token_vec element to sp_token\n    const auto add_token = [&](const business_address_token &addr_token) {\n        sp_token_vec->emplace_back(std::move(addr_token));\n    };\n\n    // search all tokens belongs to this address which is owned by wallet\n    const auto action = [&](const wallet_address &elem) {\n        business_address_token::list token_vec = database_.address_tokens.get_tokens(elem.get_address(), 0, kind);\n        std::for_each(token_vec.begin(), token_vec.end(), add_token);\n    };\n    std::for_each(wallet_addr_vec->begin(), wallet_addr_vec->end(), action);\n\n    return sp_token_vec;\n}\n\n// get all unissued tokens which stored in local database\nstd::shared_ptr<business_address_token::list> block_chain_impl::get_wallet_tokens()\n{\n    auto sh_acc_vec = get_wallets();\n    auto ret_vector = std::make_shared<business_address_token::list>();\n\n    for (auto &acc : *sh_acc_vec)\n    {\n        auto sh_vec = get_wallet_tokens(acc.get_name());\n        const auto action = [&](const business_address_token &addr_token) {\n            ret_vector->emplace_back(std::move(addr_token));\n        };\n        std::for_each(sh_vec->begin(), sh_vec->end(), action);\n    }\n\n    return ret_vector;\n}\n\nstd::shared_ptr<token_detail> block_chain_impl::get_wallet_unissued_token(const std::string &name,\n                                                                          const std::string &symbol)\n{\n    std::shared_ptr<token_detail> sp_token(nullptr);\n\n    // get wallet token which is not issued (not in blockchain)\n    auto no_issued_tokens = database_.wallet_tokens.get_unissued_tokens(get_short_hash(name));\n    const auto match = [&](const business_address_token &addr_token) {\n        return addr_token.detail.get_symbol() == symbol;\n    };\n    auto iter = std::find_if(no_issued_tokens->begin(), no_issued_tokens->end(), match);\n    if (iter != no_issued_tokens->end())\n    {\n        sp_token = std::make_shared<token_detail>((*iter).detail);\n    }\n\n    return sp_token;\n}\n\n// get all local unissued tokens belongs to the wallet/name\nstd::shared_ptr<business_address_token::list> block_chain_impl::get_wallet_unissued_tokens(const std::string &name)\n{\n    auto sp_token_vec = std::make_shared<business_address_token::list>();\n    auto sp_issues_token_vec = get_issued_tokens();\n    // copy each token_vec element which is unissued to sp_token\n    const auto add_token = [&sp_token_vec, &sp_issues_token_vec](const business_address_token &addr_token) {\n        auto &symbol = addr_token.detail.get_symbol();\n        auto pos = std::find_if(sp_issues_token_vec->begin(), sp_issues_token_vec->end(),\n                                [&symbol](const token_detail &elem) {\n                                    return symbol == elem.get_symbol();\n                                });\n        if (pos == sp_issues_token_vec->end())\n        { // token is unissued in blockchain\n            sp_token_vec->emplace_back(std::move(addr_token));\n        }\n    };\n\n    // get wallet token which is not issued (not in blockchain)\n    auto no_issued_tokens = database_.wallet_tokens.get_unissued_tokens(get_short_hash(name));\n    std::for_each(no_issued_tokens->begin(), no_issued_tokens->end(), add_token);\n\n    return sp_token_vec;\n}\n\n/// get all the token in blockchain\nstd::shared_ptr<token_detail::list> block_chain_impl::get_issued_tokens(const std::string &symbol)\n{\n    auto sp_vec = std::make_shared<token_detail::list>();\n    const auto is_symbol_empty = symbol.empty();\n    if (!is_symbol_empty && bc::wallet::symbol::is_forbidden(symbol))\n    {\n        return sp_vec;\n    }\n    auto sp_blockchain_vec = database_.tokens.get_blockchain_tokens(symbol);\n    for (auto &each : *sp_blockchain_vec)\n    {\n        auto &token = each.get_token();\n        if (is_symbol_empty && bc::wallet::symbol::is_forbidden(token.get_symbol()))\n        {\n            // swallow forbidden symbol\n            continue;\n        }\n\n        sp_vec->push_back(token);\n    }\n    return sp_vec;\n}\n\nstd::shared_ptr<blockchain_token::list> block_chain_impl::get_token_register_output(const std::string &symbol)\n{\n    return database_.tokens.get_token_history(symbol);\n}\n\n/* check uid symbol exist or not\n*/\nbool block_chain_impl::is_uid_exist(const std::string &uid_name)\n{\n    // find from blockchain database\n    return get_registered_uid(uid_name) != nullptr;\n}\n\n/* check uid address exist or not\n*/\nbool block_chain_impl::is_address_registered_uid(const std::string &uid_address, uint64_t fork_index)\n{\n    return !get_uid_from_address(uid_address, fork_index).empty();\n}\n\nbool block_chain_impl::is_wallet_owned_uid(const std::string &wallet, const std::string &symbol)\n{\n    auto uid_detail = get_registered_uid(symbol);\n    if (!uid_detail)\n    {\n        return false;\n    }\n\n    auto pvaddr = get_wallet_addresses(wallet);\n    if (pvaddr)\n    {\n        const auto match = [&uid_detail](const wallet_address &item) {\n            return item.get_address() == uid_detail->get_address();\n        };\n        auto iter = std::find_if(pvaddr->begin(), pvaddr->end(), match);\n        return iter != pvaddr->end();\n    }\n\n    return false;\n}\n\nstd::shared_ptr<uid_detail::list> block_chain_impl::get_wallet_uids(const std::string &wallet)\n{\n    auto sh_vec = std::make_shared<uid_detail::list>();\n    auto pvaddr = get_wallet_addresses(wallet);\n    if (pvaddr)\n    {\n        for (const auto &wallet_address : *pvaddr)\n        {\n            auto uid_address = wallet_address.get_address();\n            auto uid_symbol = get_uid_from_address(uid_address);\n            if (!uid_symbol.empty())\n            {\n                sh_vec->emplace_back(uid_detail(uid_symbol, uid_address));\n            }\n        }\n    }\n\n    return sh_vec;\n}\n/* find uid by address\n*/\nstd::string block_chain_impl::get_uid_from_address(const std::string &uid_address, uint64_t fork_index)\n{\n    //search from address_uid_database first\n    business_address_uid::list uid_vec = database_.address_uids.get_uids(uid_address, 0, fork_index);\n\n    std::string uid_symbol = \"\";\n    if (!uid_vec.empty())\n        uid_symbol = uid_vec[0].detail.get_symbol();\n\n    if (uid_symbol != \"\")\n    {\n        //double check\n        std::shared_ptr<blockchain_uid::list> blockchain_uidlist = get_uid_history_addresses(uid_symbol);\n        auto iter = std::find_if(blockchain_uidlist->begin(), blockchain_uidlist->end(),\n                                 [fork_index](const blockchain_uid &item) {\n                                     return is_blackhole_address(item.get_uid().get_address()) || item.get_height() <= fork_index;\n                                 });\n\n        if (iter == blockchain_uidlist->end() || iter->get_uid().get_address() != uid_address)\n            return \"\";\n    }\n    else if (uid_symbol == \"\" && fork_index != max_uint64)\n    {\n        // search from uids database\n        auto sp_uid_vec = database_.uids.getuids_from_address_history(uid_address, 0, fork_index);\n        if (sp_uid_vec && !sp_uid_vec->empty())\n        {\n            uid_symbol = sp_uid_vec->back().get_uid().get_symbol();\n        }\n    }\n\n    return uid_symbol;\n}\n\n/* find history addresses by the uid symbol\n*/\nstd::shared_ptr<blockchain_uid::list> block_chain_impl::get_uid_history_addresses(const std::string &symbol)\n{\n    const auto hash = get_hash(symbol);\n    return database_.uids.get_history_uids(hash);\n}\n\nstd::shared_ptr<uid_detail> block_chain_impl::get_registered_uid(const std::string &symbol)\n{\n    std::shared_ptr<uid_detail> sp_uid(nullptr);\n    const auto hash = get_hash(symbol);\n    auto sh_block_uid = database_.uids.get(hash);\n    if (sh_block_uid)\n    {\n        sp_uid = std::make_shared<uid_detail>(sh_block_uid->get_uid());\n    }\n    return sp_uid;\n}\n\n/// get all the uid in blockchain\nstd::shared_ptr<uid_detail::list> block_chain_impl::get_registered_uids()\n{\n    auto sp_vec = std::make_shared<uid_detail::list>();\n    if (!sp_vec)\n        return nullptr;\n\n    auto sp_blockchain_vec = database_.uids.get_blockchain_uids();\n    for (const auto &each : *sp_blockchain_vec)\n    {\n        if (each.get_status() == blockchain_uid::address_current)\n        {\n            sp_vec->emplace_back(each.get_uid());\n        }\n    }\n\n    return sp_vec;\n}\n\nstd::shared_ptr<token_detail> block_chain_impl::get_issued_token(const std::string &symbol)\n{\n    std::shared_ptr<token_detail> sp_token(nullptr);\n    const auto hash = get_hash(symbol);\n    auto sh_block_token = database_.tokens.get(hash);\n    if (sh_block_token)\n    {\n        sp_token = std::make_shared<token_detail>(sh_block_token->get_token());\n    }\n    return sp_token;\n}\n\n// get all addresses\nstd::shared_ptr<wallet_address::list> block_chain_impl::get_addresses()\n{\n    auto sh_acc_vec = get_wallets();\n    auto ret_vector = std::make_shared<wallet_address::list>();\n    const auto action = [&](const wallet_address &addr) {\n        ret_vector->emplace_back(std::move(addr));\n    };\n\n    for (auto &acc : *sh_acc_vec)\n    {\n        auto sh_vec = get_wallet_addresses(acc.get_name());\n        std::for_each(sh_vec->begin(), sh_vec->end(), action);\n    }\n\n    return ret_vector;\n}\n\nstd::shared_ptr<business_address_message::list> block_chain_impl::get_wallet_messages(const std::string &name)\n{\n    auto wallet_addr_vec = get_wallet_addresses(name);\n    auto sp_token_vec = std::make_shared<business_address_message::list>();\n\n    // copy each token_vec element to sp_token\n    const auto add_token = [&](const business_address_message &addr_token) {\n        sp_token_vec->emplace_back(std::move(addr_token));\n    };\n\n    // search all tokens belongs to this address which is owned by wallet\n    const auto action = [&](const wallet_address &elem) {\n        business_address_message::list token_vec = database_.address_tokens.get_messages(elem.get_address(), 0);\n        std::for_each(token_vec.begin(), token_vec.end(), add_token);\n    };\n    std::for_each(wallet_addr_vec->begin(), wallet_addr_vec->end(), action);\n\n    return sp_token_vec;\n}\n\nvoid block_chain_impl::fired()\n{\n    organizer_.fired();\n}\n\n/* find token symbol exist or not\n*  find steps:\n*  1. find from blockchain\n*  2. find from local database(includes wallet created token) if check_local_db = true\n*/\nbool block_chain_impl::is_token_exist(const std::string &token_name, bool check_local_db)\n{\n    // 1. find from blockchain database\n    if (get_issued_token(token_name))\n        return true;\n\n    // 2. find from local database token\n    if (check_local_db)\n    {\n        auto sh_acc_vec = get_local_tokens();\n        // scan all wallet token\n        for (auto &acc : *sh_acc_vec)\n        {\n            if (token_name == acc.get_symbol())\n                return true;\n        }\n    }\n\n    return false;\n}\n\nuint64_t block_chain_impl::get_token_height(const std::string &token_name) const\n{\n    return database_.tokens.get_register_height(token_name);\n}\n\nuint64_t block_chain_impl::get_uid_height(const std::string &uid_name) const\n{\n    return database_.uids.get_register_height(uid_name);\n}\n\nuint64_t block_chain_impl::get_token_cert_height(const std::string &cert_symbol, const token_cert_type &cert_type)\n{\n    auto &&key_str = token_cert::get_key(cert_symbol, cert_type);\n    const auto key = get_hash(key_str);\n    auto cert = database_.certs.get(key);\n    if (cert)\n    {\n        business_history::list history_cert = database_.address_tokens.get_token_certs_history(cert->get_address(), cert_symbol, cert_type, 0);\n        if (history_cert.size() > 0)\n        {\n            return history_cert.back().output_height;\n        }\n    }\n    return max_uint64;\n}\n\nuint64_t block_chain_impl::get_candidate_height(const std::string &candidate_symbol) const\n{\n    return database_.candidates.get_register_height(candidate_symbol);\n}\n\n/// get token from local database including all wallet's tokens\nstd::shared_ptr<token_detail::list> block_chain_impl::get_local_tokens()\n{\n    auto ret_vec = std::make_shared<token_detail::list>();\n    auto sh_acc_vec = get_wallets();\n    // scan all wallet token -- maybe the token has been issued\n    for (auto &acc : *sh_acc_vec)\n    {\n        auto no_issued_tokens = database_.wallet_tokens.get(get_short_hash(acc.get_name()));\n        for (auto &detail : no_issued_tokens)\n        {\n            ret_vec->emplace_back(std::move(detail));\n        }\n    }\n\n    return ret_vec;\n}\n\nvoid block_chain_impl::uppercase_symbol(std::string &symbol)\n{\n    // uppercase symbol\n    for (auto &i : symbol)\n    {\n        if (!(std::isalnum(i) || i == '.'))\n            throw std::logic_error{\"symbol must be alpha or number or dot\"};\n        i = std::toupper(i);\n    }\n}\n\nbool block_chain_impl::is_valid_address(const std::string &address)\n{\n    return is_payment_address(address) ||\n           is_script_address(address) ||\n           is_stealth_address(address) ||\n           is_blackhole_address(address);\n}\n\nbool block_chain_impl::is_blackhole_address(const std::string &address)\n{\n    return (address == bc::wallet::payment_address::blackhole_address);\n}\n\nbool block_chain_impl::is_stealth_address(const std::string &address)\n{\n    bc::wallet::stealth_address addr{address};\n    return (addr && (addr.version() == bc::wallet::stealth_address::mainnet_p2kh));\n}\n\nbool block_chain_impl::is_payment_address(const std::string &address)\n{\n    bc::wallet::payment_address addr{address};\n    return (addr && (addr.version() == bc::wallet::payment_address::mainnet_p2kh));\n}\n\n// stupid name for this function. should be is_p2sh_address.\nbool block_chain_impl::is_script_address(const std::string &address)\n{\n    bc::wallet::payment_address addr{address};\n    return (addr && (addr.version() == bc::wallet::payment_address::mainnet_p2sh));\n}\n\norganizer &block_chain_impl::get_organizer()\n{\n    return organizer_;\n}\n\nbool block_chain_impl::get_transaction(const hash_digest &hash,\n                                       chain::transaction &tx, uint64_t &tx_height)\n{\n\n    bool ret = false;\n    if (stopped())\n    {\n        //handler(error::service_stopped, {});\n        return ret;\n    }\n\n    const auto result = database_.transactions.get(hash);\n    if (result)\n    {\n        tx = result.transaction();\n        tx_height = result.height();\n        ret = true;\n    }\n    else\n    {\n        boost::mutex mutex;\n        tx_message::ptr tx_ptr = nullptr;\n\n        mutex.lock();\n        auto f = [&tx_ptr, &mutex](const code &ec, tx_message::ptr tx_) -> void {\n            if ((code)error::success == ec)\n                tx_ptr = tx_;\n            mutex.unlock();\n        };\n\n        pool().fetch(hash, f);\n        boost::unique_lock<boost::mutex> lock(mutex);\n        if (tx_ptr)\n        {\n            tx = *(static_cast<std::shared_ptr<chain::transaction>>(tx_ptr));\n            tx_height = 0;\n            ret = true;\n        }\n    }\n#ifdef UC_DEBUG\n    log::debug(\"get_transaction=\") << tx.to_string(1);\n#endif\n\n    return ret;\n}\n\nbool block_chain_impl::get_transaction_callback(const hash_digest &hash,\n                                                std::function<void(const code &, const chain::transaction &)> handler)\n{\n\n    bool ret = false;\n    if (stopped())\n    {\n        //handler(error::service_stopped, {});\n        return ret;\n    }\n\n    const auto result = database_.transactions.get(hash);\n    if (result)\n    {\n        handler(error::success, result.transaction());\n        ret = true;\n    }\n    else\n    {\n        tx_message::ptr tx_ptr = nullptr;\n\n        auto f = [&tx_ptr, handler](const code &ec, tx_message::ptr tx_) -> void {\n            if ((code)error::success == ec)\n            {\n                tx_ptr = tx_;\n                if (tx_ptr)\n                    handler(ec, *(static_cast<std::shared_ptr<chain::transaction>>(tx_ptr)));\n            }\n        };\n\n        pool().fetch(hash, f);\n        if (tx_ptr)\n        {\n            ret = true;\n        }\n    }\n\n    return ret;\n}\n\nbool block_chain_impl::get_history_callback(const payment_address &address,\n                                            size_t limit, size_t from_height,\n                                            std::function<void(const code &, chain::history::list &)> handler)\n{\n\n    bool ret = false;\n    if (stopped())\n    {\n        //handler(error::service_stopped, {});\n        return ret;\n    }\n\n    auto f = [&ret, handler](const code &ec, chain::history_compact::list compact) -> void {\n        if ((code)error::success == ec)\n        {\n            history::list result;\n\n            // Process and remove all outputs.\n            for (auto output = compact.begin(); output != compact.end();)\n            {\n                if (output->kind == point_kind::output)\n                {\n                    history row;\n                    row.output = output->point;\n                    row.output_height = output->height;\n                    row.value = output->value;\n                    row.spend = {null_hash, max_uint32};\n                    row.temporary_checksum = output->point.checksum();\n                    result.emplace_back(row);\n                    output = compact.erase(output);\n                    continue;\n                }\n\n                ++output;\n            }\n\n            // All outputs have been removed, process the spends.\n            for (const auto &spend : compact)\n            {\n                auto found = false;\n\n                // Update outputs with the corresponding spends.\n                for (auto &row : result)\n                {\n                    if (row.temporary_checksum == spend.previous_checksum &&\n                        row.spend.hash == null_hash)\n                    {\n                        row.spend = spend.point;\n                        row.spend_height = spend.height;\n                        found = true;\n                        break;\n                    }\n                }\n\n                // This will only happen if the history height cutoff comes between\n                // an output and its spend. In this case we return just the spend.\n                if (!found)\n                {\n                    history row;\n                    row.output = {null_hash, max_uint32};\n                    row.output_height = max_uint64;\n                    row.value = max_uint64;\n                    row.spend = spend.point;\n                    row.spend_height = spend.height;\n                    result.emplace_back(row);\n                }\n            }\n\n            compact.clear();\n\n            // Clear all remaining checksums from unspent rows.\n            for (auto &row : result)\n                if (row.spend.hash == null_hash)\n                    row.spend_height = max_uint64;\n\n            // TODO: sort by height and index of output, spend or both in order.\n            handler(ec, result);\n            ret = true;\n        }\n    };\n\n    // Obtain payment address history from the transaction pool and blockchain.\n    pool().fetch_history(address, limit, from_height, f);\n\n    return ret;\n}\n\ncode block_chain_impl::validate_tx_engine(const chain::transaction &tx)\n{\n    code ret = error::success;\n    if (stopped())\n    {\n        //handler(error::service_stopped, {});\n        log::debug(\"validate_tx_engine\") << \"ec=error::service_stopped\";\n        ret = error::service_stopped;\n        return ret;\n    }\n\n    //std::shared_ptr<tx_message>\n    auto tx_ptr = std::make_shared<tx_message>(tx);\n    boost::mutex mutex;\n\n    mutex.lock();\n    auto f = [&ret, &mutex](const code &ec, tx_message::ptr tx_, chain::point::indexes idx_vec) -> void {\n        log::debug(\"validate_tx_engine\") << \"ec=\" << ec << \" idx_vec=\" << idx_vec.size();\n        log::debug(\"validate_tx_engine\") << \"ec.message=\" << ec.message();\n        //if((error::success == ec) && idx_vec.empty())\n        ret = ec;\n        mutex.unlock();\n    };\n\n    pool().validate(tx_ptr, f);\n    boost::unique_lock<boost::mutex> lock(mutex);\n\n    return ret;\n}\n\ncode block_chain_impl::broadcast_transaction(const chain::transaction &tx)\n{\n    code ret = error::success;\n    if (stopped())\n    {\n        //handler(error::service_stopped, {});\n        log::debug(\"broadcast_transaction\") << \"ec=error::service_stopped\";\n        ret = error::service_stopped;\n        return ret;\n    }\n\n    //std::shared_ptr<tx_message>\n    using transaction_ptr = std::shared_ptr<tx_message>;\n    auto tx_ptr = std::make_shared<tx_message>(tx);\n    boost::mutex valid_mutex;\n\n    valid_mutex.lock();\n    //send_mutex.lock();\n\n    pool().store(tx_ptr, [tx_ptr](const code &ec, transaction_ptr) {\n        //send_mutex.unlock();\n        //ret = true;\n        log::trace(\"broadcast_transaction\") << encode_hash(tx_ptr->hash()) << \" confirmed\"; }, [&valid_mutex, &ret, tx_ptr](const code &ec, std::shared_ptr<tx_message>, chain::point::indexes idx_vec) {\n        log::debug(\"broadcast_transaction\") << \"ec=\" << ec << \" idx_vec=\" << idx_vec.size();\n        log::debug(\"broadcast_transaction\") << \"ec.message=\" << ec.message();\n        ret = ec;\n        if(error::success == ec){\n            log::trace(\"broadcast_transaction\") << encode_hash(tx_ptr->hash()) << \" validated\";\n        } else {\n            //send_mutex.unlock(); // incase dead lock\n            log::trace(\"broadcast_transaction\") << encode_hash(tx_ptr->hash()) << \" invalidated\";\n        }\n        valid_mutex.unlock(); });\n    boost::unique_lock<boost::mutex> lock(valid_mutex);\n    //boost::unique_lock<boost::mutex> send_lock(send_mutex);\n\n    return ret;\n}\n\nbool block_chain_impl::get_history(const bc::wallet::payment_address &address,\n                                   uint64_t limit, uint64_t from_height, history_compact::list &history)\n{\n    if (stopped())\n    {\n        //handler(error::service_stopped, {});\n        return false;\n    }\n\n    boost::mutex mutex;\n\n    mutex.lock();\n    auto f = [&history, &mutex](const code &ec, const history_compact::list &history_) -> void {\n        if ((code)error::success == ec)\n            history = history_;\n        mutex.unlock();\n    };\n\n    // Obtain payment address history from the transaction pool and blockchain.\n    pool().fetch_history(address, limit, from_height, f);\n    boost::unique_lock<boost::mutex> lock(mutex);\n\n#ifdef UC_DEBUG\n    log::debug(\"get_history=\") << history.size();\n#endif\n\n    return true;\n}\n\nbool block_chain_impl::get_tx_inputs_ucn_value(chain::transaction &tx, uint64_t &ucn_val)\n{\n    chain::transaction tx_temp;\n    uint64_t tx_height;\n    ucn_val = 0;\n\n    for (auto &each : tx.inputs)\n    {\n\n        if (get_transaction(each.previous_output.hash, tx_temp, tx_height))\n        {\n            auto output = tx_temp.outputs.at(each.previous_output.index);\n            ucn_val += output.value;\n        }\n        else\n        {\n            log::debug(\"get_tx_inputs_ucn_value=\") << each.to_string(true);\n            return false;\n        }\n    }\n\n    return true;\n}\n\nvoid block_chain_impl::safe_store_wallet(libbitcoin::chain::wallet &acc, const std::vector<std::shared_ptr<wallet_address>> &addresses)\n{\n    if (stopped())\n        return;\n\n    for (auto &address : addresses)\n    {\n        const auto hash = get_short_hash(address->get_name());\n        database_.wallet_addresses.safe_store(hash, *address);\n    }\n    database_.wallet_addresses.sync();\n\n    database_.wallets.store(acc);\n    database_.wallets.sync();\n}\n\n} // namespace blockchain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/blockchain/block_fetcher.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/blockchain/block_fetcher.hpp>\n\n#include <atomic>\n#include <cstdint>\n#include <memory>\n#include <system_error>\n#include <UChain/blockchain/block_chain.hpp>\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\n\nusing namespace chain;\nusing namespace std::placeholders;\n\n// TODO: split into header.\n// This class is used only locally.\nclass block_fetcher\n    : public std::enable_shared_from_this<block_fetcher>\n{\n  public:\n    block_fetcher(block_chain &chain)\n        : blockchain_(chain)\n    {\n    }\n\n    template <typename BlockIndex>\n    void start(const BlockIndex &index,\n               block_chain::block_fetch_handler handler)\n    {\n        // Create the block.\n        const auto block = std::make_shared<chain::block>();\n\n        blockchain_.fetch_block_header(index,\n                                       std::bind(&block_fetcher::handle_fetch_header,\n                                                 shared_from_this(), _1, _2, block, handler));\n    }\n\n    void start(uint64_t height, const uint32_t &index, uint32_t limit,\n               block_chain::transactions_fetch_handler handler)\n    {\n        blockchain_.fetch_block_headers(0, height, false,\n                                        std::bind(&block_fetcher::handle_fetch_headers,\n                                                  shared_from_this(), std::placeholders::_1, std::placeholders::_2, index, limit, handler),\n                                        index * limit);\n    }\n\n  private:\n    void handle_fetch_header(const code &ec, const header &header,\n                             block::ptr block, block_chain::block_fetch_handler handler)\n    {\n        if (ec)\n        {\n            handler(ec, nullptr);\n            return;\n        }\n\n        // Set the block header.\n        block->header = header;\n        const auto hash = header.hash();\n\n        blockchain_.fetch_block_transaction_hashes(hash,\n                                                   std::bind(&block_fetcher::fetch_transactions,\n                                                             shared_from_this(), _1, _2, block, handler));\n    }\n\n    void handle_fetch_headers(const code &ec, const chain::header::list &headers, uint32_t index,\n                              uint32_t count_per_page, block_chain::transactions_fetch_handler handler)\n    {\n        if (ec)\n        {\n            handler(ec, {});\n            return;\n        }\n        auto txs = std::make_shared<chain::transaction::list>();\n        uint32_t startIndex = (index - 1) * count_per_page;\n        uint32_t total_count = 0;\n        // Set the block header.\n        for (size_t i = 0; i < headers.size(); i++)\n        {\n            const auto hash = headers[i].hash();\n\n            blockchain_.fetch_block_transaction_hashes(hash,\n                                                       std::bind(&block_fetcher::fetch_top_transactions,\n                                                                 shared_from_this(), _1, _2, txs, &startIndex, &count_per_page, &total_count, handler));\n        }\n        handler(ec, txs);\n    }\n\n    void fetch_transactions(const code &ec, const hash_list &hashes,\n                            block::ptr block, block_chain::block_fetch_handler handler)\n    {\n        if (ec)\n        {\n            handler(ec, nullptr);\n            return;\n        }\n\n        // Set the block transaction size.\n        const auto count = hashes.size();\n        block->header.transaction_count = count;\n        block->transactions.resize(count);\n\n        // This will be called exactly once by the synchronizer.\n        const auto completion_handler =\n            std::bind(&block_fetcher::handle_complete,\n                      shared_from_this(), _1, _2, handler);\n\n        // Synchronize transaction fetch calls to one completion call.\n        const auto complete = synchronize(completion_handler, count,\n                                          \"block_fetcher\");\n\n        // blockchain::fetch_transaction is thread safe.\n        size_t index = 0;\n        for (const auto &hash : hashes)\n            blockchain_.fetch_transaction(hash,\n                                          std::bind(&block_fetcher::handle_fetch_transaction,\n                                                    shared_from_this(), _1, _2, index++, block, complete));\n    }\n\n    void fetch_top_transactions(const code &ec, const hash_list &hashes,\n                                std::shared_ptr<chain::transaction::list> txs, uint32_t *startIndex, uint32_t *counts, uint32_t *total_count, block_chain::transactions_fetch_handler handler)\n    {\n        if (ec)\n        {\n            handler(ec, nullptr);\n            return;\n        }\n\n        // Set the block transaction size.\n        const auto count = hashes.size();\n\n        // blockchain::fetch_transaction is thread safe.\n        for (const auto &hash : hashes)\n            blockchain_.fetch_transaction(hash,\n                                          std::bind(&block_fetcher::handle_fetch_top_transaction,\n                                                    shared_from_this(), _1, _2, txs, startIndex, counts, total_count, handler));\n    }\n\n    void handle_fetch_transaction(const code &ec,\n                                  const transaction &transaction, size_t index, block::ptr block,\n                                  block_chain::block_fetch_handler handler)\n    {\n        if (ec)\n        {\n            handler(ec, nullptr);\n            return;\n        }\n\n        // Critical Section\n        ///////////////////////////////////////////////////////////////////////\n        mutex_.lock();\n\n        // TRANSACTION COPY\n        block->transactions[index] = transaction;\n\n        mutex_.unlock();\n        ///////////////////////////////////////////////////////////////////////\n\n        handler(error::success, block);\n    }\n\n    void handle_fetch_top_transaction(const code &ec,\n                                      const transaction &transaction,\n                                      std::shared_ptr<chain::transaction::list> txs, uint32_t *startIndex, uint32_t *counts, uint32_t *total_count, block_chain::transactions_fetch_handler handler)\n    {\n        if (ec)\n        {\n            handler(ec, nullptr);\n            return;\n        }\n\n        if ((*total_count)++ >= *startIndex && *total_count - *startIndex <= *counts && *total_count <= 10000)\n        {\n            // Critical Section\n            ///////////////////////////////////////////////////////////////////////\n            mutex_.lock();\n\n            // TRANSACTION COPY\n            //block->transactions[index] = transaction;\n            txs->push_back(transaction);\n            mutex_.unlock();\n            ///////////////////////////////////////////////////////////////////////\n        }\n    }\n\n    // If ec success then there is no possibility that block is being written.\n    void handle_complete(const code &ec, block::ptr block,\n                         block_chain::block_fetch_handler handler)\n    {\n        if (ec)\n            handler(ec, nullptr);\n        else\n            handler(error::success, block);\n    }\n\n    block_chain &blockchain_;\n    mutable shared_mutex mutex_;\n};\n\nvoid fetch_block(block_chain &chain, uint64_t height,\n                 block_chain::block_fetch_handler handle_fetch)\n{\n    const auto fetcher = std::make_shared<block_fetcher>(chain);\n    fetcher->start(height, handle_fetch);\n}\n\nvoid fetch_latest_transactions(block_chain &chain, uint64_t height,\n                               uint32_t index, uint32_t count, block_chain::transactions_fetch_handler handle_fetch)\n{\n    const auto fetcher = std::make_shared<block_fetcher>(chain);\n    fetcher->start(height, index, count, handle_fetch);\n}\n\nvoid fetch_block(block_chain &chain, const hash_digest &hash,\n                 block_chain::block_fetch_handler handle_fetch)\n{\n    const auto fetcher = std::make_shared<block_fetcher>(chain);\n    fetcher->start(hash, handle_fetch);\n}\n\n} // namespace blockchain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/blockchain/block_info.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/blockchain/block_info.hpp>\n\n#include <cstdint>\n#include <memory>\n#include <utility>\n#include <UChain/coin.hpp>\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\n\nusing namespace message;\n\n// Use zero as orphan sentinel since this is precluded by the orphan pool.\nstatic constexpr auto orphan_height = 0u;\n\nblock_info::block_info(block_ptr actual_block)\n    : code_(error::success),\n      processed_(false),\n      height_(orphan_height),\n      actual_block_(actual_block),\n      is_checked_work_proof_(false)\n{\n}\n\n// Hand off ownership of a block to this wrapper.\nblock_info::block_info(chain::block &&actual_block)\n    : block_info(std::make_shared<block_msg>(actual_block))\n{\n}\n\nblock_info::block_ptr block_info::actual() const\n{\n    return actual_block_;\n}\n\nvoid block_info::set_processed()\n{\n    processed_.store(true);\n}\n\nbool block_info::processed() const\n{\n    return processed_.load();\n}\n\nvoid block_info::set_height(uint64_t height)\n{\n    BITCOIN_ASSERT(height != orphan_height);\n    height_.store(height);\n}\n\nuint64_t block_info::height() const\n{\n    return height_.load();\n}\n\nvoid block_info::set_is_checked_work_proof(bool is_checked)\n{\n    is_checked_work_proof_.store(is_checked);\n}\n\nbool block_info::get_is_checked_work_proof() const\n{\n    return is_checked_work_proof_.load();\n}\n\nvoid block_info::set_error(const code &code)\n{\n    code_.store(code);\n}\n\ncode block_info::error() const\n{\n    return code_.load();\n}\n\nconst hash_digest block_info::hash() const\n{\n    // This relies on the hash caching optimization.\n    return actual_block_->header.hash();\n}\n\n} // namespace blockchain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/blockchain/organizer.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/blockchain/organizer.hpp>\n#include <UChain/blockchain/block.hpp>\n\n#include <boost/thread.hpp>\n#include <algorithm>\n#include <cstdint>\n#include <memory>\n#include <numeric>\n#include <UChain/coin.hpp>\n#include <UChain/blockchain/block_info.hpp>\n#include <UChain/blockchain/orphan_pool.hpp>\n#include <UChain/blockchain/organizer.hpp>\n#include <UChain/blockchain/settings.hpp>\n#include <UChain/blockchain/simple_chain.hpp>\n#include <UChain/blockchain/validate_block_impl.hpp>\n#include <UChain/coin/chain/header.hpp>\n#include <UChain/node/protocols/protocol_block_out.hpp>\n#include <UChain/coin/wallet/payment_address.hpp>\n#include <UChain/coin/formats/base_16.hpp>\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\n\nusing namespace bc::chain;\nusing namespace bc::config;\n\n#define NAME \"organizer\"\n\norganizer::organizer(threadpool &pool, simple_chain &chain,\n                     const settings &settings)\n    : stopped_(true),\n      use_testnet_rules_(settings.use_testnet_rules),\n      checkpoints_(checkpoint::sort(settings.checkpoints)),\n      chain_(chain),\n      orphan_pool_(settings.block_pool_capacity),\n      subscriber_(std::make_shared<reorganize_subscriber>(pool, NAME))\n{\n}\n\nvoid organizer::start()\n{\n    stopped_ = false;\n    subscriber_->start();\n}\n\nvoid organizer::stop()\n{\n    stopped_ = true;\n    subscriber_->stop();\n    subscriber_->invoke(error::service_stopped, 0, {}, {});\n}\n\nbool organizer::stopped()\n{\n    return stopped_;\n}\n\nuint64_t organizer::count_inputs(const chain::block &block)\n{\n    const auto value = [](uint64_t total, const transaction &tx) {\n        return total + tx.inputs.size();\n    };\n\n    const auto &txs = block.transactions;\n    return std::accumulate(txs.begin(), txs.end(), uint64_t(0), value);\n}\n\nbool organizer::strict(uint64_t fork_point) const\n{\n    return checkpoints_.empty() || fork_point >= checkpoints_.back().height();\n}\n\n// This verifies the block at orphan_chain[orphan_index]->actual()\ncode organizer::verify(uint64_t fork_point,\n                       const block_info::list &orphan_chain, uint64_t orphan_index)\n{\n    if (stopped())\n        return error::service_stopped;\n\n    BITCOIN_ASSERT(orphan_index < orphan_chain.size());\n    const auto &current_block = orphan_chain[orphan_index]->actual();\n    const auto height = fork_point + orphan_index + 1;\n    BITCOIN_ASSERT(height != 0);\n\n    const auto callback = [this]() {\n        return stopped();\n    };\n\n    // Validates current_block\n    validate_block_impl validate(chain_, fork_point, orphan_chain, orphan_index, height,\n                                 *current_block, use_testnet_rules_, checkpoints_, callback);\n\n    // Checks that are independent of the chain.\n    auto ec = validate.check_block(static_cast<blockchain::block_chain_impl &>(this->chain_));\n    if (error::success != ec)\n    {\n        log::debug(LOG_BLOCKCHAIN) << \"organizer: check_block failed! error:\"\n                                   << std::to_string(ec.value()) << \", fork_point: \"\n                                   << std::to_string(fork_point) << \", orphan_index: \" << std::to_string(orphan_index);\n        return ec;\n    }\n\n    validate.initialize_context();\n\n    // Checks that are dependent on height and preceding blocks.\n    ec = validate.accept_block();\n    if (error::success != ec)\n    {\n        log::debug(LOG_BLOCKCHAIN) << \"organizer: accept_block failed! error:\"\n                                   << std::to_string(ec.value()) << \", fork_point: \"\n                                   << std::to_string(fork_point) << \", orphan_index: \" << std::to_string(orphan_index);\n        return ec;\n    }\n\n    // Start strict validation if past last checkpoint.\n    if (!strict(fork_point))\n    {\n        return ec;\n    }\n\n    const auto total_inputs = count_inputs(*current_block);\n    const auto total_transactions = current_block->transactions.size();\n\n    log::info(LOG_BLOCKCHAIN)\n        << \"Block [\" << height << \"] verify (\" << total_transactions\n        << \") txs and (\" << total_inputs << \") inputs\";\n\n    // Time this for logging.\n    const auto timed = [this, &ec, &validate]() {\n        hash_digest err_tx;\n        // Checks that include input->output traversal.\n        ec = validate.connect_block(err_tx, static_cast<blockchain::block_chain_impl &>(this->chain_));\n        if (ec && err_tx != null_hash)\n        {\n            dynamic_cast<block_chain_impl &>(chain_).pool().delete_tx(err_tx);\n        }\n    };\n\n    // Execute the timed validation.\n    const auto elapsed = timer<std::chrono::milliseconds>::duration(timed);\n    const auto ms_per_block = static_cast<float>(elapsed.count());\n    const auto ms_per_input = ms_per_block / total_inputs;\n    const auto seconds_per_block = ms_per_block / 1000;\n    const auto verified = ec ? \"unverified\" : \"verified\";\n\n    log::info(LOG_BLOCKCHAIN)\n        << \"Block [\" << height << \"] \" << verified << \" in (\"\n        << seconds_per_block << \") secs or (\" << ms_per_input << \") ms/input\";\n\n    return ec;\n}\n\n// This is called on every block_chain_impl::do_store() call.\nvoid organizer::organize()\n{\n    process_queue_ = orphan_pool_.unprocessed();\n\n    while (!process_queue_.empty() && !stopped())\n    {\n        const auto process_block = process_queue_.back();\n        process_queue_.pop_back();\n        process(process_block);\n    }\n}\n\nbool organizer::add(block_info::ptr block)\n{\n    return orphan_pool_.add(block);\n}\n\nvoid organizer::filter_orphans(message::get_data::ptr message)\n{\n    orphan_pool_.filter(message);\n}\n\nvoid organizer::process(block_info::ptr process_block)\n{\n    BITCOIN_ASSERT(process_block);\n\n    std::vector<block_info::ptr> blocks;\n    blocks.push_back(process_block);\n\n    while (blocks.empty() == false)\n    {\n        process_block = blocks.back();\n        blocks.pop_back();\n        // Trace the chain in the orphan pool\n        auto orphan_chain = orphan_pool_.trace(process_block);\n        BITCOIN_ASSERT(orphan_chain.size() >= 1);\n\n        uint64_t fork_index;\n        const auto &hash = orphan_chain.front()->actual()->header.previous_block_hash;\n\n        // Verify the blocks in the orphan chain.\n        if (chain_.get_height(fork_index, hash))\n        {\n            replace_chain(fork_index, orphan_chain);\n            if (orphan_chain.empty() == false)\n            {\n                const auto hash = orphan_chain.back()->actual()->header.hash();\n                block_info::ptr block;\n                while ((block = orphan_pool_.delete_pending_block(hash)))\n                {\n                    blocks.push_back(block);\n                    log::warning(LOG_BLOCKCHAIN) << \"pop pendingblock hash:\" << encode_hash(hash) << \" process_block hash:\" << encode_hash(block->actual()->header.hash());\n                }\n            }\n        }\n        else\n        {\n            orphan_pool_.add_pending_block(hash, orphan_chain.back());\n            log::warning(LOG_BLOCKCHAIN) << \"push pendingblock hash:\" << encode_hash(hash) << \" process_block hash:\" << encode_hash(orphan_chain.back()->actual()->header.hash());\n        }\n\n        // Don't mark all orphan_chain as processed here because there might be\n        // a winning fork from an earlier block.\n        process_block->set_processed();\n    }\n}\n\nvoid organizer::replace_chain(uint64_t fork_index,\n                              block_info::list &orphan_chain)\n{\n    u256 orphan_work = 0;\n\n    for (uint64_t orphan = 0; orphan < orphan_chain.size(); ++orphan)\n    {\n        // This verifies the block at orphan_chain[orphan]->actual()\n        if (!orphan_chain[orphan]->get_is_checked_work_proof())\n        {\n            const auto ec = verify(fork_index, orphan_chain, orphan);\n            if (ec)\n            {\n                // If invalid block info is also set for the block.\n                if (ec != (code)error::service_stopped)\n                {\n                    const auto &header = orphan_chain[orphan]->actual()->header;\n                    const auto block_hash = encode_hash(header.hash());\n\n                    log::warning(LOG_BLOCKCHAIN)\n                        << \"Invalid block [\" << block_hash << \"] \" << ec.message();\n                }\n\n                // Block is invalid, clip the orphans.\n                clip_orphans(orphan_chain, orphan, ec);\n                if (orphan_chain.empty())\n                {\n                    log::warning(LOG_BLOCKCHAIN) << \"orphan_chain.empty()\";\n                    return;\n                }\n\n                // Stop summing work once we discover an invalid block\n                break;\n            }\n            else\n            {\n                orphan_chain[orphan]->set_is_checked_work_proof(true);\n            }\n        }\n\n        const auto &orphan_block = orphan_chain[orphan]->actual();\n        orphan_work += block_work(orphan_block->header.timestamp);\n    }\n\n    // All remaining blocks in orphan_chain should all be valid now\n    // Compare the difficulty of the 2 forks (original and orphan)\n    const auto begin_index = fork_index + 1;\n\n    u256 main_work;\n    DEBUG_ONLY(auto result =)\n    chain_.get_difficulty(main_work, begin_index);\n    BITCOIN_ASSERT(result);\n\n    delete_fork_chain_hash(orphan_chain[orphan_chain.size() - 1]->actual()->header.previous_block_hash);\n    if (orphan_work <= main_work)\n    {\n        if (orphan_chain.size() % node::locator_cap == 0)\n            orphan_chain.back()->set_error(error::fetch_more_block);\n        add_fork_chain_hash(orphan_chain.back()->actual()->header.hash());\n\n        log::debug(LOG_BLOCKCHAIN)\n            << \"Insufficient work to reorganize at [\" << begin_index << \"]\"\n            << \"orphan_work:\" << orphan_work << \" main_work:\" << main_work;\n        return;\n    }\n\n    // Replace! Switch!\n    block_info::list released_blocks;\n    auto success = chain_.pop_from(released_blocks, begin_index);\n\n    if (!released_blocks.empty())\n        log::warning(LOG_BLOCKCHAIN)\n            << \" blockchain fork at height:\" << released_blocks.front()->actual()->header.number\n            << \" begin_index:\" << encode_hash(released_blocks.front()->actual()->header.hash())\n            << \" size:\" << released_blocks.size();\n\n    // if pop blocks failed, stop replace\n    if (!success)\n    {\n        log::warning(LOG_BLOCKCHAIN) << \" pop_from begin_height:\" << begin_index << \"failed\";\n        return;\n    }\n\n    // We add the arriving blocks first to the main chain because if\n    // we add the blocks being replaced back to the pool first then\n    // the we can push the arrival blocks off the bottom of the\n    // circular buffer.\n    // Then when we try to remove the block from the orphans pool,\n    // if will fail to find it. I would rather not add an exception\n    // there so that problems will show earlier.\n    // All arrival_blocks should be blocks from the pool.\n    auto arrival_index = fork_index;\n\n    for (const auto arrival_block : orphan_chain)\n    {\n        orphan_pool_.remove(arrival_block);\n\n        // Indicates the block is not an orphan.\n        arrival_block->set_height(++arrival_index);\n\n        // THIS IS THE DATABASE BLOCK WRITE AND INDEX OPERATION.\n        if (chain_.push(arrival_block) == false)\n        {\n            log::warning(LOG_BLOCKCHAIN)\n                << \" push block height:\" << arrival_block->actual()->header.number\n                << \" hash:\" << encode_hash(arrival_block->actual()->header.hash())\n                << \"failed\";\n            // if push block failed, stop replace\n            return;\n        }\n        else\n        {\n            log::debug(LOG_BLOCKCHAIN)\n                << \" push block height:\" << arrival_block->actual()->header.number\n                << \" hash:\" << encode_hash(arrival_block->actual()->header.hash());\n        }\n    }\n\n    // Add the old blocks back to the pool (as processed with orphan height).\n    for (const auto replaced_block : released_blocks)\n    {\n        replaced_block->set_processed();\n        orphan_pool_.add(replaced_block);\n\n        log::warning(LOG_BLOCKCHAIN)\n            << \" blockchain fork old block number:\" << replaced_block->actual()->header.number\n            << \" hash_index:\" << encode_hash(replaced_block->actual()->header.hash())\n            << \" miner address:\" << bc::wallet::payment_address::extract(replaced_block->actual()->transactions[0].outputs[0].script);\n        for (auto &tx : replaced_block->actual()->transactions)\n        {\n            log::warning(LOG_BLOCKCHAIN) << \" forked transaction hash:\" << encode_hash(tx.hash()) << \" data:\" << tx.to_string(0);\n        }\n    }\n\n    notify_reorganize(fork_index, orphan_chain, released_blocks);\n}\n\nvoid organizer::remove_processed(block_info::ptr remove_block)\n{\n    const auto it = std::find(process_queue_.begin(), process_queue_.end(),\n                              remove_block);\n\n    if (it != process_queue_.end())\n        process_queue_.erase(it);\n}\n\nvoid organizer::clip_orphans(block_info::list &orphan_chain,\n                             uint64_t orphan_index, const code &invalid_reason)\n{\n    // Remove from orphans pool and process queue.\n    auto orphan_start = orphan_chain.begin() + orphan_index;\n\n    for (auto it = orphan_start; it != orphan_chain.end(); ++it)\n    {\n        if (it == orphan_start)\n            (*it)->set_error(invalid_reason);\n        else\n            (*it)->set_error(error::previous_block_invalid);\n\n        (*it)->set_processed();\n        remove_processed(*it);\n        orphan_pool_.remove(*it);\n    }\n\n    orphan_chain.erase(orphan_start, orphan_chain.end());\n}\n\nvoid organizer::subscribe_reorganize(reorganize_handler handler)\n{\n    subscriber_->subscribe(handler, error::service_stopped, 0, {}, {});\n}\n\nvoid organizer::notify_reorganize(uint64_t fork_point,\n                                  const block_info::list &orphan_chain,\n                                  const block_info::list &replaced_chain)\n{\n    const auto to_block_ptr = [](const block_info::ptr &detail) {\n        return detail->actual();\n    };\n\n    message::block_msg::ptr_list arrivals(orphan_chain.size());\n    std::transform(orphan_chain.begin(), orphan_chain.end(), arrivals.begin(),\n                   to_block_ptr);\n\n    message::block_msg::ptr_list replacements(replaced_chain.size());\n    std::transform(replaced_chain.begin(), replaced_chain.end(),\n                   replacements.begin(), to_block_ptr);\n\n    subscriber_->relay(error::success, fork_point, arrivals, replacements);\n}\n\nvoid organizer::fired()\n{\n    subscriber_->relay(error::mock, 0, {}, {}); //event to check whether service is stopped\n}\n\nstd::unordered_map<hash_digest, uint64_t> organizer::get_fork_chain_last_block_hashes()\n{\n    unordered_map<hash_digest, uint64_t> hashes;\n    boost::unique_lock<boost::mutex> lock(mutex_fork_chain_last_block_hashes_);\n    hashes = fork_chain_last_block_hashes_;\n    return hashes;\n}\n\nvoid organizer::add_fork_chain_hash(const hash_digest &hash)\n{\n    boost::unique_lock<boost::mutex> lock(mutex_fork_chain_last_block_hashes_);\n    fork_chain_last_block_hashes_.insert(make_pair(hash, 0));\n}\n\nvoid organizer::delete_fork_chain_hash(const hash_digest &hash)\n{\n    boost::unique_lock<boost::mutex> lock(mutex_fork_chain_last_block_hashes_);\n    fork_chain_last_block_hashes_.erase(hash);\n}\n\n} // namespace blockchain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/blockchain/orphan_pool.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/blockchain/orphan_pool.hpp>\n\n#include <algorithm>\n#include <cstddef>\n#include <UChain/blockchain/block_info.hpp>\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\n\norphan_pool::orphan_pool(size_t capacity)\n{\n    buffer_.reserve(capacity == 0 ? 1 : capacity);\n}\n\n// There is no validation whatsoever of the block up to this pont.\nbool orphan_pool::add(block_info::ptr block)\n{\n    const auto &header = block->actual()->header;\n\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    mutex_.lock_upgrade();\n\n    // No duplicates allowed.\n    if (exists(header))\n    {\n        mutex_.unlock_upgrade();\n        //-----------------------------------------------------------------\n        return false;\n    }\n\n    const auto old_size = buffer_.size();\n    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n    mutex_.unlock_upgrade_and_lock();\n    buffer_.push_back(block);\n    mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n\n    log::debug(LOG_BLOCKCHAIN)\n        << \"Orphan pool added block [\" << encode_hash(block->hash())\n        << \"] previous [\" << encode_hash(header.previous_block_hash)\n        << \"] old size (\" << old_size << \").\";\n\n    return true;\n}\n\nvoid orphan_pool::remove(block_info::ptr block)\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    mutex_.lock_upgrade();\n\n    const auto it = std::find(buffer_.begin(), buffer_.end(), block);\n\n    if (it == buffer_.end())\n    {\n        mutex_.unlock_upgrade();\n        //-----------------------------------------------------------------\n        return;\n    }\n\n    const auto old_size = buffer_.size();\n    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n    mutex_.unlock_upgrade_and_lock();\n    buffer_.erase(it);\n    mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n\n    log::debug(LOG_BLOCKCHAIN)\n        << \"Orphan pool removed block [\" << encode_hash(block->hash())\n        << \"] old size (\" << old_size << \"). with status: \" << block->error().message();\n}\n\n// TODO: use hash table pool to eliminate this O(n^2) search.\nvoid orphan_pool::filter(message::get_data::ptr message) const\n{\n    auto &inventories = message->inventories;\n\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    shared_lock lock(mutex_);\n\n    for (auto it = inventories.begin(); it != inventories.end();)\n        if (it->is_block_type() && exists(it->hash))\n            it = inventories.erase(it);\n        else\n            ++it;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nblock_info::list orphan_pool::trace(block_info::ptr end) const\n{\n    block_info::list trace;\n    trace.reserve(buffer_.size());\n    trace.push_back(end);\n    auto hash = end->actual()->header.previous_block_hash;\n\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    mutex_.lock_shared();\n\n    for (auto it = rfind(buffer_.rbegin(), hash); it != buffer_.rend(); it = rfind(it, hash))\n    {\n        trace.push_back(*it);\n        hash = (*it)->actual()->header.previous_block_hash;\n    }\n\n    mutex_.unlock_shared();\n    ///////////////////////////////////////////////////////////////////////////\n\n    BITCOIN_ASSERT(!trace.empty());\n    std::reverse(trace.begin(), trace.end());\n    trace.shrink_to_fit();\n    return trace;\n}\n\nblock_info::list orphan_pool::unprocessed() const\n{\n    block_info::list unprocessed;\n    unprocessed.reserve(buffer_.size());\n\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    mutex_.lock_shared();\n\n    // Earlier blocks enter pool first, so reversal helps avoid fragmentation.\n    for (auto it = buffer_.rbegin(); it != buffer_.rend(); ++it)\n        if (!(*it)->processed())\n            unprocessed.push_back(*it);\n\n    mutex_.unlock_shared();\n    ///////////////////////////////////////////////////////////////////////////\n\n    unprocessed.shrink_to_fit();\n    return unprocessed;\n}\n\nbool orphan_pool::add_pending_block(const hash_digest &needed_block, const block_info::ptr &pending_block)\n{\n    auto hash = pending_block->actual()->header.hash();\n    if (pending_blocks_hash_.find(hash) != pending_blocks_hash_.end())\n    {\n        return false;\n    }\n\n    pending_blocks_.insert(make_pair(needed_block, pending_block));\n    pending_blocks_hash_.insert(hash);\n    return true;\n}\n\nblock_info::ptr orphan_pool::delete_pending_block(const hash_digest &needed_block)\n{\n    block_info::ptr ret;\n    auto it = pending_blocks_.find(needed_block);\n    if (it != pending_blocks_.end())\n    {\n        ret = it->second;\n        pending_blocks_hash_.erase(it->second->actual()->header.hash());\n        pending_blocks_.erase(it);\n    }\n\n    return ret;\n}\n\n// private\n//-----------------------------------------------------------------------------\n\nbool orphan_pool::exists(const hash_digest &hash) const\n{\n    const auto match = [&hash](const block_info::ptr &entry) {\n        return hash == entry->hash();\n    };\n\n    return std::any_of(buffer_.begin(), buffer_.end(), match);\n}\n\nbool orphan_pool::exists(const chain::header &header) const\n{\n    const auto match = [&header](const block_info::ptr &entry) {\n        return header == entry->actual()->header;\n    };\n\n    return std::any_of(buffer_.begin(), buffer_.end(), match);\n}\n\n/*\norphan_pool::const_iterator orphan_pool::find(buffer::const_iterator begin, const hash_digest& hash) const\n{\n    const auto match = [&hash](const block_info::ptr& entry)\n    {\n        return hash == entry->hash();\n    };\n\n    return std::find_if(begin, buffer_.end(), match);\n}\n*/\n\norphan_pool::const_reverse_iterator orphan_pool::rfind(buffer::const_reverse_iterator begin, const hash_digest &hash) const\n{\n    const auto match = [&hash](const block_info::ptr &entry) {\n        return hash == entry->hash();\n    };\n\n    return std::find_if(begin, buffer_.rend(), match);\n}\n\n} // namespace blockchain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/blockchain/settings.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/blockchain/settings.hpp>\n\n#include <boost/filesystem.hpp>\n#include <UChainService/consensus/miner.hpp>\n#include <UChain/coin/constants.hpp>\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\n\nusing namespace boost::filesystem;\n\nsettings::settings()\n    : block_pool_capacity(5000),\n      tx_pool_capacity(4096),\n      tx_pool_consistency(false),\n      use_testnet_rules(false)\n{\n}\n\n// Use push_back due to initializer_list bug:\n// stackoverflow.com/a/20168627/1172329\nsettings::settings(bc::settings context)\n    : settings()\n{\n    switch (context)\n    {\n    case bc::settings::mainnet:\n    {\n        checkpoints.reserve(1);\n        checkpoints.push_back({\"09e8c9f2ddeaf3c1df74fa3262ddc238a360c9778ca6a3140f563d48dea4bbf4\", 0});\n        // fixme. header sync first has some problem.\n        //checkpoints.push_back({ \"250a083ddd62ea1d0907e29ff8d64e42c451f93560196f3f693fdc1bc6b84d61\", 10000 });\n        //checkpoints.push_back({ \"e989e4b2d60ae2f8fbaa1cdb69d05afa63e7f1f99cf715589a93e4877c92fa8b\", 100000 });\n        //checkpoints.push_back({ \"58986f8f9848d32aa1a210f3890e82312326657b6b84d2aa4bf00b41403dc191\", 200000 });\n        //checkpoints.push_back({ \"b9ec93b181e5ca3825df23c8100188a503b98d6e7240c7b21cedc980304967ea\", 300000 });\n        //checkpoints.push_back({ \"843411e1194c11cc958abd923498e1a7488ba9b0bccf1a3a5960f3bc213645ce\", 400000 });\n        //checkpoints.push_back({ \"2be656ee2c84684faaefd4e9f21f157d1dcb6ad9d25bf18d037cea37d23437ca\", 500000 });\n        //checkpoints.push_back({ \"265e051b24034d3bb51e99099a98d1d103c703cdac22a0d52e816aeb9cb807b9\", 600000 });\n        //checkpoints.push_back({ \"bd512ef95e5c6c99bf03112be7ac7fc0a6ef1113678dd583a18778ca683908f9\", 700000 });\n        //checkpoints.push_back({ \"9a0efd7b41cfc1cbeb1bfbd2ab3cb7989314611608cc4236b80a540444fbfb36\", 800000 });\n\n        bc::wallet::ec_private::mainnet_p2kh = 0x44;\n        bc::wallet::ec_public::mainnet_p2kh = 0x44;\n        bc::wallet::payment_address::mainnet_p2kh = 0x44;\n        break;\n    }\n\n    case bc::settings::testnet:\n    {\n        use_testnet_rules = true;\n\n        checkpoints.reserve(1);\n        checkpoints.push_back({\"b1076144f919c8efaf55e5ec267daa6d5dc0a12609c9c6fddf8157270ae6e7ca\", 0});\n\n        bc::wallet::ec_private::mainnet_p2kh = 0x7f;\n        bc::wallet::ec_public::mainnet_p2kh = 0x7f;\n        bc::wallet::payment_address::mainnet_p2kh = 0x7f;\n\n        //libbitcoin::consensus::bucket_size = 50000;\n        libbitcoin::consensus::lock_heights = {10, 20, 30, 40, 50};\n        libbitcoin::coinbase_maturity = 1;\n        break;\n    }\n\n    default:\n    case bc::settings::none:\n    {\n    }\n    }\n}\n\n} // namespace blockchain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/blockchain/tx_pool.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/blockchain/tx_pool.hpp>\n\n#include <algorithm>\n#include <cstddef>\n#include <memory>\n#include <system_error>\n#include <UChain/coin.hpp>\n#include <UChain/blockchain/block_chain.hpp>\n#include <UChain/blockchain/settings.hpp>\n#include <UChain/blockchain/validate_tx_engine.hpp>\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\n\n#define NAME \"mempool\"\n\nusing namespace chain;\nusing namespace wallet;\nusing namespace std::placeholders;\n\ntx_pool::tx_pool(threadpool &pool, block_chain &chain,\n                                   const settings &settings)\n    : stopped_(true),\n      maintain_consistency_(settings.tx_pool_consistency),\n      buffer_(settings.tx_pool_capacity),\n      dispatch_(pool, NAME),\n      blockchain_(chain),\n      index_(pool, chain),\n      subscriber_(std::make_shared<transaction_subscriber>(pool, NAME))\n{\n}\n\ntx_pool::~tx_pool()\n{\n    clear(error::service_stopped);\n}\n\nvoid tx_pool::start()\n{\n    stopped_ = false;\n    index_.start();\n    subscriber_->start();\n\n    // Subscribe to blockchain (organizer) reorg notifications.\n    blockchain_.subscribe_reorganize(\n        std::bind(&tx_pool::handle_reorganized,\n                  this, _1, _2, _3, _4));\n}\n\n// The subscriber is not restartable.\nvoid tx_pool::stop()\n{\n    stopped_ = true;\n    index_.stop();\n    subscriber_->stop();\n    subscriber_->invoke(error::service_stopped, {}, {});\n}\n\nvoid tx_pool::fired()\n{\n    subscriber_->relay(error::mock, {}, {});\n}\n\nbool tx_pool::stopped()\n{\n    return stopped_;\n}\n\nvoid tx_pool::inventory(message::inventory::ptr inventory)\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // TODO: populate the inventory vector from the full memory pool.\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid tx_pool::validate(transaction_ptr tx, validate_handler handler)\n{\n    dispatch_.ordered(&tx_pool::do_validate,\n                      this, tx, handler);\n}\n\nvoid tx_pool::do_validate(transaction_ptr tx,\n                                   validate_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped, tx, {});\n        return;\n    }\n\n    const auto validate = std::make_shared<validate_tx_engine>(\n        blockchain_, *tx, *this, dispatch_);\n\n    validate->start(\n        dispatch_.ordered_delegate(&tx_pool::handle_validated,\n                                   this, _1, _2, _3, handler));\n}\n\nvoid tx_pool::handle_validated(const code &ec, transaction_ptr tx,\n                                        const indexes &unconfirmed, validate_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped, tx, {});\n        return;\n    }\n\n    if (ec == (code)error::input_not_found || ec == (code)error::validate_inputs_failed)\n    {\n        BITCOIN_ASSERT(unconfirmed.size() == 1);\n        handler(ec, tx, unconfirmed);\n        return;\n    }\n\n    if (ec)\n    {\n        BITCOIN_ASSERT(unconfirmed.empty());\n        handler(ec, tx, {});\n        return;\n    }\n\n    // Recheck the memory pool, as a duplicate may have been added.\n    if (is_in_pool(tx->hash()))\n    {\n        handler(error::duplicate, tx, {});\n        return;\n    }\n\n    code error = check_symbol_repeat(tx);\n    if (error != error::success)\n    {\n        handler(error, tx, {});\n        return;\n    }\n\n    handler(error::success, tx, unconfirmed);\n}\n\ncode tx_pool::check_symbol_repeat(transaction_ptr tx)\n{\n    std::set<string> tokens;\n    std::set<string> token_certs;\n    std::set<string> candidates;\n    std::set<string> uids;\n    std::set<string> uidaddreses;\n    std::set<string> uidattaches;\n\n    auto check_outputs = [&](transaction_ptr txs) -> code {\n        for (auto &output : txs->outputs)\n        {\n            //add asset check;avoid send with uid while transfer\n            if (output.attach_data.get_version() == UID_ASSET_VERIFY_VERSION)\n            {\n                auto check_uid = [&uids, &uidattaches](string attach_uid) {\n                    if (!attach_uid.empty() && uids.find(attach_uid) != uids.end())\n                    {\n                        log::debug(LOG_BLOCKCHAIN)\n                            << \"check_symbol_repeat asset uid: \" + attach_uid\n                            << \" already exists in txpool!\";\n                        return false;\n                    }\n\n                    uidattaches.insert(attach_uid);\n                    return true;\n                };\n\n                if (!check_uid(output.attach_data.get_from_uid()) || !check_uid(output.attach_data.get_to_uid()))\n                {\n                    log::debug(LOG_BLOCKCHAIN)\n                        << \"check_symbol_repeat from_uid \" + output.attach_data.get_from_uid()\n                        << \" to_uid \" + output.attach_data.get_to_uid()\n                        << \" check failed!\"\n                        << \" \" << tx->to_string(1);\n                    return error::uid_exist;\n                }\n            }\n\n            if (output.is_token_issue())\n            {\n                auto r = tokens.insert(output.get_token_symbol());\n                if (r.second == false)\n                {\n                    log::debug(LOG_BLOCKCHAIN)\n                        << \"check_symbol_repeat token \" + output.get_token_symbol()\n                        << \" already exists in txpool!\"\n                        << \" \" << tx->to_string(1);\n                    return error::token_exist;\n                }\n            }\n            else if (output.is_token_cert())\n            {\n                auto &&key = output.get_token_cert().get_key();\n                auto r = token_certs.insert(key);\n                if (r.second == false)\n                {\n                    log::debug(LOG_BLOCKCHAIN)\n                        << \"check_symbol_repeat cert \" + output.get_token_cert_symbol()\n                        << \" with type \" << output.get_token_cert_type()\n                        << \" already exists in txpool!\"\n                        << \" \" << tx->to_string(1);\n                    return error::token_cert_exist;\n                }\n            }\n            else if (output.is_candidate())\n            {\n                auto r = candidates.insert(output.get_token_symbol());\n                if (r.second == false)\n                {\n                    log::debug(LOG_BLOCKCHAIN)\n                        << \"check_symbol_repeat candidate \" + output.get_token_symbol()\n                        << \" already exists in txpool!\"\n                        << \" \" << tx->to_string(1);\n                    return error::candidate_exist;\n                }\n            }\n            else if (output.is_uid())\n            {\n                auto uidsymbol = output.get_uid_symbol();\n                auto uidexist = uids.insert(uidsymbol);\n                if (uidexist.second == false)\n                {\n                    log::debug(LOG_BLOCKCHAIN)\n                        << \"check_symbol_repeat uid \" + uidsymbol\n                        << \" already exists in txpool!\"\n                        << \" \" << tx->to_string(1);\n                    return error::uid_exist;\n                }\n\n                auto uidaddress = uidaddreses.insert(output.get_uid_address());\n                if (uidaddress.second == false)\n                {\n                    log::debug(LOG_BLOCKCHAIN)\n                        << \"check_symbol_repeat uid address \" + output.get_uid_address()\n                        << \" already has uid on it in txpool!\"\n                        << \" \" << tx->to_string(1);\n                    return error::address_registered_uid;\n                }\n\n                if (uidattaches.find(uidsymbol) != uidattaches.end())\n                {\n                    log::debug(LOG_BLOCKCHAIN)\n                        << \"check_symbol_repeat asset uid: \" + uidsymbol\n                        << \" already transfer in txpool!\"\n                        << \" \" << tx->to_string(1);\n                    return error::uid_exist;\n                }\n            }\n        }\n        return error::success;\n    };\n\n    code ec;\n    for (auto &item : buffer_)\n    {\n        if (!item.tx)\n            continue;\n\n        if ((ec = check_outputs(item.tx)) != error::success)\n            break;\n    }\n\n    return ec != error::success ? ec : check_outputs(tx);\n}\n\n// handle_confirm will never fire if handle_validate returns a failure code.\nvoid tx_pool::store(transaction_ptr tx,\n                             confirm_handler handle_confirm, validate_handler handle_validate)\n{\n    if (stopped())\n    {\n        handle_validate(error::service_stopped, tx, {});\n        return;\n    }\n\n    validate(tx,\n             std::bind(&tx_pool::do_store,\n                       this, _1, _2, _3, handle_confirm, handle_validate));\n}\n\n// This is overly complex due to the transaction pool and index split.\nvoid tx_pool::do_store(const code &ec, transaction_ptr tx,\n                                const indexes &unconfirmed, confirm_handler handle_confirm,\n                                validate_handler handle_validate)\n{\n    if (ec)\n    {\n        handle_validate(ec, tx, {});\n        return;\n    }\n\n    // Set up deindexing to run after transaction pool removal.\n    const auto do_deindex = [this, handle_confirm](const code ec,\n                                                   transaction_ptr tx) {\n        const auto do_confirm = [handle_confirm, tx, ec](const code) {\n            handle_confirm(ec, tx);\n        };\n\n        // This always sets success but we have captured the confirmation code.\n        index_.remove(*tx, do_confirm);\n    };\n\n    // Add to pool, save confirmation handler.\n    add(tx, do_deindex);\n\n    const auto handle_indexed = [this, handle_validate, tx, unconfirmed](\n                                    const code ec) {\n        // Notify subscribers that the tx has been validated and indexed.\n        notify_transaction(unconfirmed, tx);\n\n        log::debug(LOG_BLOCKCHAIN)\n            << \"Transaction saved to mempool (\" << buffer_.size() << \")\";\n\n        // Notify caller that the tx has been validated and indexed.\n        handle_validate(ec, tx, unconfirmed);\n    };\n\n    // Add to index and invoke handler to indicate validation and indexing.\n    index_.add(*tx, handle_indexed);\n}\n\nvoid tx_pool::fetch(fetch_all_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped, {});\n        return;\n    }\n\n    const auto tx_fetcher = [this, handler]() {\n        std::vector<transaction_ptr> transactions;\n        for (auto item : buffer_)\n        {\n            if (item.tx)\n                transactions.push_back(item.tx);\n        }\n        handler(error::success, transactions);\n    };\n\n    dispatch_.ordered(tx_fetcher);\n}\n\nvoid tx_pool::delete_tx(const hash_digest &tx_hash)\n{\n    if (stopped())\n    {\n        return;\n    }\n\n    log::debug(LOG_BLOCKCHAIN) << \" delete_tx hash:\" << libbitcoin::encode_hash(tx_hash);\n    const auto tx_delete = [this, tx_hash]() {\n        for (auto item = buffer_.begin(); item != buffer_.end(); ++item)\n        {\n            if (item->tx->hash() == tx_hash)\n            {\n                log::debug(LOG_BLOCKCHAIN) << \" delete_tx hash:\" << libbitcoin::encode_hash(tx_hash) << \" success\";\n                buffer_.erase(item);\n                break;\n            }\n        }\n    };\n\n    dispatch_.ordered(tx_delete);\n}\n\nvoid tx_pool::fetch(const hash_digest &transaction_hash,\n                             fetch_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped, {});\n        return;\n    }\n\n    const auto tx_fetcher = [this, transaction_hash, handler]() {\n        const auto it = find(transaction_hash);\n\n        if (it == buffer_.end())\n            handler(error::not_found, {});\n        else\n            handler(error::success, it->tx);\n    };\n\n    dispatch_.ordered(tx_fetcher);\n}\n\nvoid tx_pool::fetch_history(const payment_address &address,\n                                     size_t limit, size_t from_height,\n                                     block_chain::history_fetch_handler handler)\n{\n    // This passes through to blockchain to build combined history.\n    index_.fetch_all_history(address, limit, from_height, handler);\n}\n\n// TODO: use hash table pool to eliminate this O(n^2) search.\nvoid tx_pool::filter(get_data_ptr message, result_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped);\n        return;\n    }\n\n    const auto filter_transactions = [this, message, handler]() {\n        auto &inventories = message->inventories;\n\n        for (auto it = inventories.begin(); it != inventories.end();)\n            if (it->is_transaction_type() && is_in_pool(it->hash))\n                it = inventories.erase(it);\n            else\n                ++it;\n\n        handler(error::success);\n    };\n\n    dispatch_.ordered(filter_transactions);\n}\n\nvoid tx_pool::exists(const hash_digest &tx_hash,\n                              result_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped);\n        return;\n    }\n\n    const auto get_existence = [this, tx_hash, handler]() {\n        handler(is_in_pool(tx_hash) ? error::success : error::not_found);\n    };\n\n    dispatch_.ordered(get_existence);\n}\n\n// new blocks come in - remove txs in new\n// old blocks taken out - resubmit txs in old\nbool tx_pool::handle_reorganized(const code &ec, size_t fork_point,\n                                          const block_list &new_blocks, const block_list &replaced_blocks)\n{\n    if (ec == (code)error::service_stopped)\n    {\n        log::debug(LOG_BLOCKCHAIN)\n            << \"Stopping transaction pool: \" << ec.message();\n        return false;\n    }\n\n    if (ec == error::mock)\n        return true;\n\n    if (ec)\n    {\n        log::debug(LOG_BLOCKCHAIN)\n            << \"Failure in tx pool reorganize handler: \" << ec.message();\n        return false;\n    }\n\n    log::debug(LOG_BLOCKCHAIN)\n        << \"Reorganize: tx pool size (\" << buffer_.size()\n        << \") forked at (\" << fork_point\n        << \") new blocks (\" << new_blocks.size()\n        << \") replace blocks (\" << replaced_blocks.size() << \")\";\n\n    if (replaced_blocks.empty())\n    {\n        // Remove memory pool transactions that also exist in new blocks.\n        dispatch_.ordered(\n            std::bind(&tx_pool::remove,\n                      this, new_blocks));\n    }\n    else\n    {\n        // See http://www.jwz.org/doc/worse-is-better.html\n        // for why we take this approach. We return with an error_code.\n        // An alternative would be resubmit all tx from the cleared blocks.\n        dispatch_.ordered(\n            std::bind(&tx_pool::clear,\n                      this, error::blockchain_reorganized));\n    }\n\n    return true;\n}\n\nvoid tx_pool::subscribe_transaction(\n    transaction_handler handle_transaction)\n{\n    subscriber_->subscribe(handle_transaction, error::service_stopped, {}, {});\n}\n\nvoid tx_pool::notify_transaction(const point::indexes &unconfirmed,\n                                          transaction_ptr tx)\n{\n    subscriber_->relay(error::success, unconfirmed, tx);\n}\n\n// Entry methods.\n// ----------------------------------------------------------------------------\n\n// A new transaction has been received, add it to the memory pool.\nvoid tx_pool::add(transaction_ptr tx, confirm_handler handler)\n{\n    // When a new tx is added to the buffer drop the oldest.\n    if (maintain_consistency_ && buffer_.size() == buffer_.capacity())\n        delete_package(error::pool_filled);\n\n    buffer_.push_back({tx, handler});\n}\n\n// There has been a reorg, clear the memory pool using the given reason code.\nvoid tx_pool::clear(const code &ec)\n{\n    for (const auto &entry : buffer_)\n        entry.handle_confirm(ec, entry.tx);\n\n    buffer_.clear();\n}\n\n// Delete memory pool txs that are obsoleted by a new block acceptance.\nvoid tx_pool::remove(const block_list &blocks)\n{\n    // Delete by hash sets a success code.\n    delete_confirmed_in_blocks(blocks);\n\n    // Delete by spent sets a double-spend error.\n    if (maintain_consistency_)\n        delete_spent_in_blocks(blocks);\n}\n\n// Consistency methods.\n// ----------------------------------------------------------------------------\n\n// Delete mempool txs that are duplicated in the new blocks.\nvoid tx_pool::delete_confirmed_in_blocks(const block_list &blocks)\n{\n    if (stopped() || buffer_.empty())\n        return;\n\n    for (const auto block : blocks)\n        for (const auto &tx : block->transactions)\n            delete_single(tx.hash(), error::success);\n}\n\n// Delete all txs that spend a previous output of any tx in the new blocks.\nvoid tx_pool::delete_spent_in_blocks(const block_list &blocks)\n{\n    if (stopped() || buffer_.empty())\n        return;\n\n    for (const auto block : blocks)\n        for (const auto &tx : block->transactions)\n            for (const auto &input : tx.inputs)\n                delete_dependencies(input.previous_output,\n                                    error::double_spend);\n}\n\n// Delete any tx that spends any output of this tx.\nvoid tx_pool::delete_dependencies(const output_point &point,\n                                           const code &ec)\n{\n    const auto comparitor = [&point](const input &input) {\n        return input.previous_output == point;\n    };\n\n    delete_dependencies(comparitor, ec);\n}\n\n// Delete any tx that spends any output of this tx.\nvoid tx_pool::delete_dependencies(const hash_digest &tx_hash,\n                                           const code &ec)\n{\n    const auto comparitor = [&tx_hash](const input &input) {\n        return input.previous_output.hash == tx_hash;\n    };\n\n    delete_dependencies(comparitor, ec);\n}\n\n// This is horribly inefficient, but it's simple.\n// TODO: Create persistent multi-indexed memory pool (including age and\n// children) and perform this pruning trivialy (and add policy over it).\nvoid tx_pool::delete_dependencies(input_compare is_dependency,\n                                           const code &ec)\n{\n    std::vector<entry> dependencies;\n    for (const auto &entry : buffer_)\n        for (const auto &input : entry.tx->inputs)\n            if (is_dependency(input))\n            {\n                dependencies.push_back(entry);\n                break;\n            }\n\n    // We queue deletion to protect the iterator.\n    for (const auto &dependency : dependencies)\n        delete_package(dependency.tx, ec);\n}\n\nvoid tx_pool::delete_package(const code &ec)\n{\n    if (stopped() || buffer_.empty())\n        return;\n\n    // Must copy the entry because it is going to be deleted from the list.\n    const auto oldest = buffer_.front();\n\n    oldest.handle_confirm(ec, oldest.tx);\n    delete_package(oldest.tx, ec);\n}\n\nvoid tx_pool::delete_package(transaction_ptr tx, const code &ec)\n{\n    if (delete_single(tx->hash(), ec))\n        delete_dependencies(tx->hash(), ec);\n}\n\nbool tx_pool::delete_single(const hash_digest &tx_hash, const code &ec)\n{\n    if (stopped())\n        return false;\n\n    const auto matched = [&tx_hash](const entry &entry) {\n        return entry.tx->hash() == tx_hash;\n    };\n\n    const auto it = std::find_if(buffer_.begin(), buffer_.end(), matched);\n\n    if (it == buffer_.end())\n        return false;\n\n    it->handle_confirm(ec, it->tx);\n    buffer_.erase(it);\n\n    while (1)\n    {\n        const auto it = std::find_if(buffer_.begin(), buffer_.end(), matched);\n\n        if (it == buffer_.end())\n            break;\n\n        it->handle_confirm(ec, it->tx);\n        buffer_.erase(it);\n    }\n\n    return true;\n}\n\nbool tx_pool::find(transaction_ptr &out_tx,\n                            const hash_digest &tx_hash) const\n{\n    const auto it = find(tx_hash);\n    const auto found = it != buffer_.end();\n\n    if (found)\n        out_tx = it->tx;\n\n    return found;\n}\n\nbool tx_pool::find(chain::transaction &out_tx,\n                            const hash_digest &tx_hash) const\n{\n    const auto it = find(tx_hash);\n    const auto found = it != buffer_.end();\n\n    if (found)\n    {\n        // TRANSACTION COPY\n        out_tx = *(it->tx);\n    }\n\n    return found;\n}\n\ntx_pool::const_iterator tx_pool::find(\n    const hash_digest &tx_hash) const\n{\n    const auto found = [&tx_hash](const entry &entry) {\n        return entry.tx->hash() == tx_hash;\n    };\n\n    return std::find_if(buffer_.begin(), buffer_.end(), found);\n}\n\nbool tx_pool::is_in_pool(const hash_digest &tx_hash) const\n{\n    return find(tx_hash) != buffer_.end();\n}\n\nbool tx_pool::is_spent_in_pool(transaction_ptr tx) const\n{\n    return is_spent_in_pool(*tx);\n}\n\nbool tx_pool::is_spent_in_pool(const transaction &tx) const\n{\n    const auto found = [this](const input &input) {\n        return is_spent_in_pool(input.previous_output);\n    };\n\n    const auto &inputs = tx.inputs;\n    return std::any_of(inputs.begin(), inputs.end(), found);\n}\n\nbool tx_pool::is_spent_in_pool(const output_point &outpoint) const\n{\n    const auto found = [&outpoint](const entry &entry) {\n        return is_spent_by_tx(outpoint, entry.tx);\n    };\n\n    return std::any_of(buffer_.begin(), buffer_.end(), found);\n}\n\nbool tx_pool::is_spent_by_tx(const output_point &outpoint,\n                                      transaction_ptr tx)\n{\n    const auto found = [&outpoint](const input &input) {\n        return input.previous_output == outpoint;\n    };\n\n    const auto &inputs = tx->inputs;\n    return std::any_of(inputs.begin(), inputs.end(), found);\n}\n\n} // namespace blockchain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/blockchain/tx_pool_index.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-node.\n *\n * UChain-node is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/blockchain/tx_pool_index.hpp>\n\n#include <algorithm>\n#include <atomic>\n#include <cstddef>\n#include <cstdint>\n#include <UChain/coin.hpp>\n#include <UChain/blockchain/block.hpp>\n#include <UChain/blockchain/block_chain.hpp>\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\n\n#define NAME \"index\"\n\nusing namespace bc::blockchain;\nusing namespace bc::chain;\nusing namespace bc::wallet;\nusing namespace std::placeholders;\n\nstatic constexpr uint64_t genesis_height = 0;\n\ntx_pool_index::tx_pool_index(threadpool &pool,\n                                               block_chain &blockchain)\n    : stopped_(true),\n      dispatch_(pool, NAME),\n      blockchain_(blockchain)\n{\n}\n\n// Start and stop.\n// ----------------------------------------------------------------------------\n\nvoid tx_pool_index::start()\n{\n    stopped_ = false;\n}\n\nvoid tx_pool_index::stop()\n{\n    stopped_ = true;\n}\n\n// Utility templates.\n// ----------------------------------------------------------------------------\n\ntemplate <typename Point, typename Multimap>\nvoid erase(const payment_address &key, const Point &value_point, Multimap &map)\n{\n    auto match = [&value_point](const typename Multimap::value_type &entry) {\n        return entry.second.point == value_point;\n    };\n\n    const auto range = map.equal_range(key);\n    const auto it = std::find_if(range.first, range.second, match);\n\n    if (it != range.second)\n        map.erase(it);\n}\n\ntemplate <typename InfoList, typename Multimap>\nInfoList to_info_list(const payment_address &address, Multimap &map)\n{\n    auto convert = [](const typename Multimap::value_type &entry) {\n        return entry.second;\n    };\n\n    InfoList out;\n    const auto range = map.equal_range(address);\n    out.resize(std::distance(range.first, range.second));\n    std::transform(range.first, range.second, out.begin(), convert);\n    return out;\n}\n\n// Add sequence.\n// ----------------------------------------------------------------------------\n\nvoid tx_pool_index::add(const transaction &tx,\n                                 completion_handler handler)\n{\n    dispatch_.ordered(\n        std::bind(&tx_pool_index::do_add,\n                  this, tx, handler));\n}\n\nvoid tx_pool_index::do_add(const transaction &tx,\n                                    completion_handler handler)\n{\n    uint32_t index = 0;\n    const auto tx_hash = tx.hash();\n\n    for (const auto &input : tx.inputs)\n    {\n        const auto address = payment_address::extract(input.script);\n\n        if (address)\n        {\n            const input_point point{tx_hash, index};\n            const spend_info info{point, input.previous_output};\n            spends_map_.emplace(std::move(address), std::move(info));\n        }\n\n        ++index;\n    }\n\n    index = 0;\n\n    for (const auto &output : tx.outputs)\n    {\n        const auto address = payment_address::extract(output.script);\n\n        if (address)\n        {\n            const output_point point{tx_hash, index};\n            const output_info info{point, output.value};\n            outputs_map_.emplace(std::move(address), std::move(info));\n        }\n\n        ++index;\n    }\n\n    // This is the end of the add sequence.\n    handler(error::success);\n}\n\n// Remove sequence.\n// ----------------------------------------------------------------------------\n\nvoid tx_pool_index::remove(const transaction &tx,\n                                    completion_handler handler)\n{\n    dispatch_.ordered(\n        std::bind(&tx_pool_index::do_remove,\n                  this, tx, handler));\n}\n\nvoid tx_pool_index::do_remove(const transaction &tx,\n                                       completion_handler handler)\n{\n    uint32_t index = 0;\n    const auto tx_hash = tx.hash();\n\n    for (const auto &input : tx.inputs)\n    {\n        const auto address = payment_address::extract(input.script);\n\n        if (address)\n            erase(address, input_point{tx_hash, index}, spends_map_);\n\n        ++index;\n    }\n\n    index = 0;\n\n    for (const auto &output : tx.outputs)\n    {\n        const auto address = payment_address::extract(output.script);\n\n        if (address)\n            erase(address, output_point{tx_hash, index}, outputs_map_);\n\n        ++index;\n    }\n\n    // This is the end of the remove sequence.\n    handler(error::success);\n}\n\n// Fetch all history sequence.\n// ----------------------------------------------------------------------------\n\n// Fetch the history first from the blockchain and then from the tx pool index.\nvoid tx_pool_index::fetch_all_history(const payment_address &address,\n                                               size_t limit, size_t from_height, fetch_handler handler)\n{\n    blockchain_.fetch_history(address, limit, from_height,\n                              std::bind(&tx_pool_index::blockchain_history_fetched,\n                                        this, _1, _2, address, handler));\n}\n\nvoid tx_pool_index::blockchain_history_fetched(const code &ec,\n                                                        const history_list &history, const payment_address &address,\n                                                        fetch_handler handler)\n{\n    if (ec)\n    {\n        handler(ec, {});\n        return;\n    }\n\n    fetch_index_history(address,\n                        std::bind(&tx_pool_index::index_history_fetched,\n                                  _1, _2, _3, history, handler));\n}\n\nvoid tx_pool_index::index_history_fetched(const code &ec,\n                                                   const spend_info::list &spends, const output_info::list &outputs,\n                                                   const history_list &history, fetch_handler handler)\n{\n    if (ec)\n    {\n        handler(ec, {});\n        return;\n    }\n\n    // Copy the list for modification and return.\n    auto out = history;\n\n    // Race conditions raise the possiblity of seeing a spend or output more\n    // than once. We collapse any duplicates here and continue.\n    add(out, spends);\n    add(out, outputs);\n\n    // This is the end of the fetch_all_history sequence.\n    handler(error::success, out);\n}\n\n// Fetch index history sequence.\n// ----------------------------------------------------------------------------\n\n// Fetch history from the transaction pool index only.\nvoid tx_pool_index::fetch_index_history(\n    const payment_address &address, query_handler handler)\n{\n    dispatch_.ordered(\n        std::bind(&tx_pool_index::do_fetch,\n                  this, address, handler));\n}\n\nvoid tx_pool_index::do_fetch(const payment_address &address,\n                                      query_handler handler)\n{\n    // This is the end of the fetch_index_history sequence.\n    handler(error::success,\n            to_info_list<spend_info::list>(address, spends_map_),\n            to_info_list<output_info::list>(address, outputs_map_));\n}\n\n// Static helpers\n// ----------------------------------------------------------------------------\n// Transactions may exist in the memory pool and in the blockchain,\n// although this circumstance should not persist.\n\nbool tx_pool_index::exists(history_list &history,\n                                    const spend_info &spend)\n{\n    const auto match = [&spend](const history_compact &row) {\n        return row.kind == point_kind::spend && row.point == spend.point;\n    };\n\n    return std::any_of(history.begin(), history.end(), match);\n}\n\nbool tx_pool_index::exists(history_list &history,\n                                    const output_info &output)\n{\n    const auto match = [&output](const history_compact &row) {\n        return row.kind == point_kind::output && row.point == output.point;\n    };\n\n    return std::any_of(history.begin(), history.end(), match);\n}\n\nvoid tx_pool_index::add(history_list &history, const spend_info &spend)\n{\n    const history_compact row{\n        point_kind::spend,\n        spend.point,\n        genesis_height,\n        {spend.previous_output.checksum()}};\n\n    history.emplace_back(std::move(row));\n}\n\nvoid tx_pool_index::add(history_list &history, const output_info &output)\n{\n    const history_compact row{\n        point_kind::output,\n        output.point,\n        genesis_height,\n        {output.value}};\n\n    history.emplace_back(std::move(row));\n}\n\nvoid tx_pool_index::add(history_list &history,\n                                 const spend_info::list &spends)\n{\n    const auto action = [&history](const spend_info &spend) {\n        if (!exists(history, spend))\n            add(history, spend);\n    };\n\n    std::for_each(spends.begin(), spends.end(), action);\n}\n\nvoid tx_pool_index::add(history_list &history,\n                                 const output_info::list &outputs)\n{\n    const auto action = [&history](const output_info &output) {\n        if (!exists(history, output))\n            add(history, output);\n    };\n\n    std::for_each(outputs.begin(), outputs.end(), action);\n}\n\n} // namespace blockchain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/blockchain/validate_block.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/blockchain/validate_block.hpp>\n\n#include <set>\n#include <algorithm>\n#include <chrono>\n#include <cstddef>\n#include <cstdint>\n#include <system_error>\n#include <vector>\n#include <UChain/coin.hpp>\n#include <UChain/blockchain/block.hpp>\n#include <UChain/blockchain/validate_tx_engine.hpp>\n//#include <UChainService/consensus/miner/MinerAux.h>\n//#include <UChainService/consensus/libdevcore/BasicType.h>\n#include <UChainService/consensus/miner.hpp>\n#include <UChain/coin/chain/output.hpp>\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\n\n// To improve readability.\n#define RETURN_IF_STOPPED() \\\n    if (stopped())          \\\n    return error::service_stopped\n\nusing namespace chain;\n\n// Consensus rule change activation and enforcement parameters.\nstatic constexpr uint8_t version_4 = 4;\nstatic constexpr uint8_t version_3 = 3;\nstatic constexpr uint8_t version_2 = 2;\nstatic constexpr uint8_t version_1 = 1;\n\n// Mainnet activation parameters.\nstatic constexpr size_t mainnet_active = 51;\nstatic constexpr size_t mainnet_enforce = 75;\nstatic constexpr size_t mainnet_sample = 100;\n\n// Testnet activation parameters.\nstatic constexpr size_t testnet_active = 750u;\nstatic constexpr size_t testnet_enforce = 950u;\nstatic constexpr size_t testnet_sample = 1000u;\n\n// Block 173805 is the first mainnet block after date-based activation.\n// Block 514 is the first testnet block after date-based activation.\nstatic constexpr size_t mainnet_bip16_activation_height = 173805;\nstatic constexpr size_t testnet_bip16_activation_height = 514;\n\n// github.com/bitcoin/bips/blob/master/bip-0030.mediawiki#specification\nstatic constexpr size_t mainnet_bip30_exception_height1 = 91842;\nstatic constexpr size_t mainnet_bip30_exception_height2 = 91880;\nstatic constexpr size_t testnet_bip30_exception_height1 = 0;\nstatic constexpr size_t testnet_bip30_exception_height2 = 0;\n\n// The default sigops count for mutisignature scripts.\nstatic constexpr uint32_t multisig_default_sigops = 20;\n\n// Value used to define retargeting range constraint.\nstatic constexpr uint64_t retargeting_factor = 4;\n\n// Aim for blocks every 10 mins (600 seconds).\nstatic constexpr uint64_t target_spacing_seconds = 10 * 60;\n\n// Target readjustment every 2 weeks (1209600 seconds).\nstatic constexpr uint64_t target_timespan_seconds = 2 * 7 * 24 * 60 * 60;\n\n// The target number of blocks for 2 weeks of work (2016 blocks).\nstatic constexpr uint64_t retargeting_interval = target_timespan_seconds /\n                                                 target_spacing_seconds;\n\n// The window by which a time stamp may exceed our current time (2 hours).\n//static const auto time_stamp_window = asio::seconds(2 * 60 * 60);\nstatic const auto time_stamp_window = asio::seconds(time_stamp_window_senconds);\n//static const auto time_stamp_window_future_blocktime_fix = asio::seconds(24);\n\n// The nullptr option is for backward compatibility only.\nvalidate_block::validate_block(size_t height, const block &block, bool testnet,\n                               const config::checkpoint::list &checks, stopped_callback callback)\n    : testnet_(testnet),\n      height_(height),\n      activations_(script_context::none_enabled),\n      minimum_version_(0),\n      current_block_(block),\n      checkpoints_(checks),\n      stop_callback_(callback)\n{\n}\n\nvoid validate_block::initialize_context()\n{\n    /*const auto bip30_exception_height1 = testnet_ ?\n                                         testnet_bip30_exception_height1 :\n                                         mainnet_bip30_exception_height1;\n\n    const auto bip30_exception_height2 = testnet_ ?\n                                         testnet_bip30_exception_height2 :\n                                         mainnet_bip30_exception_height2;\n\n    const auto bip16_activation_height = testnet_ ?\n                                         testnet_bip16_activation_height :\n                                         mainnet_bip16_activation_height;\n\n    const auto active = testnet_ ? testnet_active : mainnet_active;\n    const auto enforce = testnet_ ? testnet_enforce : mainnet_enforce;\n    const auto sample = testnet_ ? testnet_sample : mainnet_sample;\n\n    // Continue even if this is too small or empty (fast and simpler).\n    const auto versions = preceding_block_versions(sample);\n\n    const auto ge_4 = [](uint8_t version) { return version >= version_4; };\n    const auto ge_3 = [](uint8_t version) { return version >= version_3; };\n    const auto ge_2 = [](uint8_t version) { return version >= version_2; };\n\n    const auto count_4 = std::count_if(versions.begin(), versions.end(), ge_4);\n    const auto count_3 = std::count_if(versions.begin(), versions.end(), ge_3);\n    const auto count_2 = std::count_if(versions.begin(), versions.end(), ge_2);\n\n    const auto activate = [active](size_t count) { return count >= active; };\n    const auto enforced = [enforce](size_t count) { return count >= enforce; };\n\n    // version 4/3/2 enforced based on 95% of preceding 1000 mainnet blocks.\n    if (enforced(count_4))\n        minimum_version_ = version_4;\n    else if (enforced(count_3))\n        minimum_version_ = version_3;\n    else if (enforced(count_2))\n        minimum_version_ = version_2;\n    else\n        minimum_version_ = version_1;\n\n    // good for all, no votes is needed.\n    activations_ |= script_context::attenuation_enabled;\n\n    // bip65 is activated based on 75% of preceding 1000 mainnet blocks.\n    if (activate(count_4))\n        activations_ |= script_context::bip65_enabled;\n\n    // bip66 is activated based on 75% of preceding 1000 mainnet blocks.\n    if (activate(count_3))\n        activations_ |= script_context::bip66_enabled;\n\n    // bip34 is activated based on 75% of preceding 1000 mainnet blocks.\n    if (activate(count_2))\n        activations_ |= script_context::bip34_enabled;\n\n    // bip30 applies to all but two mainnet blocks that violate the rule.\n    if (height_ != bip30_exception_height1 &&\n            height_ != bip30_exception_height2)\n        activations_ |= script_context::bip30_enabled;\n\n    // bip16 was activated with a one-time test on mainnet/testnet (~55% rule).\n    if (height_ >= bip16_activation_height)\n        activations_ |= script_context::bip16_enabled;*/\n    activations_ |= script_context::attenuation_enabled;\n    activations_ |= script_context::bip65_enabled;\n    activations_ |= script_context::bip66_enabled;\n    activations_ |= script_context::bip34_enabled;\n    activations_ |= script_context::bip30_enabled;\n    activations_ |= script_context::bip16_enabled;\n}\n\n// initialize_context must be called first (to set activations_).\nbool validate_block::is_active(script_context flag) const\n{\n    if (!script::is_active(activations_, flag))\n        return false;\n\n    const auto version = current_block_.header.version;\n    return (flag == script_context::attenuation_enabled) ||\n           (flag == script_context::bip65_enabled && version >= version_4) ||\n           (flag == script_context::bip66_enabled && version >= version_3) ||\n           (flag == script_context::bip34_enabled && version >= version_2);\n}\n\n// validate_version must be called first (to set minimum_version_).\nbool validate_block::is_valid_version() const\n{\n    return current_block_.header.version >= minimum_version_;\n}\n\nbool validate_block::stopped() const\n{\n    return stop_callback_();\n}\n\ncode validate_block::check_block(blockchain::block_chain_impl &chain) const\n{\n    // These are checks that are independent of the blockchain\n    // that can be validated before saving an orphan block.\n\n    const auto &transactions = current_block_.transactions;\n\n    if (transactions.empty() || current_block_.serialized_size() > max_block_size)\n        return error::size_limits;\n\n    if (!transactions[0].is_coinbase())\n    {\n        return error::first_not_coinbase;\n    }\n\n    const auto &header = current_block_.header;\n\n    /*if (!is_valid_proof_of_work(header))\n        return error::proof_of_work;*/\n\n    RETURN_IF_STOPPED();\n\n    //future time check selfish mining\n    if (height_ > 1)\n    {\n        if (!is_valid_time_stamp(header.timestamp))\n            return error::futuristic_timestamp;\n        // last block time check\n        chain::header prev_header = fetch_block(height_ - 1);\n        if (current_block_.header.timestamp < prev_header.timestamp)\n            return error::timestamp_too_early;\n\n        //Todo cannot check\n        /*if(!consensus::miner::is_address_in_turn_with_now_height(height_-1,transactions[0].outputs[0].get_script_address())) {\n            return error::first_coinbase_index_error;\n        }*/\n    }\n\n    //unsigned int coinbase_count = 0;\n\n    std::set<string> tokens;\n    std::set<string> token_certs;\n    std::set<string> candidates;\n    std::set<string> uids;\n    std::set<string> uidaddreses;\n    code first_tx_ec = error::success;\n    for (const auto &tx : transactions)\n    {\n        RETURN_IF_STOPPED();\n        /*if (tx.is_coinbase()) {\n            ++coinbase_count;\n        }*/\n\n        const auto validate_tx = std::make_shared<validate_tx_engine>(chain, tx, *this);\n        auto ec = validate_tx->check_transaction();\n        if (!ec)\n        {\n            ec = validate_tx->check_transaction_connect_input(header.number);\n        }\n\n        for (size_t i = 0; (!ec) && (i < tx.outputs.size()); ++i)\n        {\n            const auto &output = tx.outputs[i];\n            if (output.is_token_issue())\n            {\n                auto r = tokens.insert(output.get_token_symbol());\n                if (r.second == false)\n                {\n                    log::debug(LOG_BLOCKCHAIN)\n                        << \"check_block token \" + output.get_token_symbol()\n                        << \" already exists in block!\"\n                        << \" \" << tx.to_string(1);\n                    ec = error::token_exist;\n                    break;\n                }\n            }\n            else if (output.is_token_cert())\n            {\n                auto &&key = output.get_token_cert().get_key();\n                auto r = token_certs.insert(key);\n                if (r.second == false)\n                {\n                    log::debug(LOG_BLOCKCHAIN)\n                        << \"check_block cert \" + output.get_token_cert_symbol()\n                        << \" with type \" << output.get_token_cert_type()\n                        << \" already exists in block!\"\n                        << \" \" << tx.to_string(1);\n                    ec = error::token_cert_exist;\n                    break;\n                }\n            }\n            else if (output.is_candidate())\n            {\n                auto r = candidates.insert(output.get_token_symbol());\n                if (r.second == false)\n                {\n                    log::debug(LOG_BLOCKCHAIN)\n                        << \"check_block candidate \" + output.get_token_symbol()\n                        << \" already exists in block!\"\n                        << \" \" << tx.to_string(1);\n                    ec = error::candidate_exist;\n                    break;\n                }\n            }\n            else if (output.is_uid())\n            {\n                auto uidexist = uids.insert(output.get_uid_symbol());\n                if (uidexist.second == false)\n                {\n                    log::debug(LOG_BLOCKCHAIN)\n                        << \"check_block uid \" + output.get_uid_symbol()\n                        << \" already exists in block!\"\n                        << \" \" << tx.to_string(1);\n                    ec = error::uid_exist;\n                    break;\n                }\n\n                auto uidaddress = uidaddreses.insert(output.get_uid_address());\n                if (uidaddress.second == false)\n                {\n                    log::debug(LOG_BLOCKCHAIN)\n                        << \"check_block uid \" + output.get_uid_address()\n                        << \" address_registered_uid!\"\n                        << \" \" << tx.to_string(1);\n                    ec = error::address_registered_uid;\n                    break;\n                }\n            }\n        }\n\n        if (ec)\n        {\n            if (!first_tx_ec)\n            {\n                first_tx_ec = ec;\n            }\n            chain.pool().delete_tx(tx.hash());\n        }\n    }\n\n    /*if (coinbase_count != 1) {\n        return error::extra_coinbases;\n    }*/\n\n    if (first_tx_ec)\n    {\n        return first_tx_ec;\n    }\n\n    RETURN_IF_STOPPED();\n\n    if (!is_distinct_tx_set(transactions))\n    {\n        log::warning(LOG_BLOCKCHAIN) << \"is_distinct_tx_set!!!\";\n        return error::duplicate;\n    }\n\n    RETURN_IF_STOPPED();\n\n    const auto sigops = legacy_sigops_count(transactions);\n    if (sigops > max_block_script_sigops)\n        return error::too_many_sigs;\n\n    RETURN_IF_STOPPED();\n\n    if (header.merkle != block::generate_merkle_root(transactions))\n        return error::merkle_mismatch;\n\n    return error::success;\n}\n\nbool validate_block::is_distinct_tx_set(const transaction::list &txs)\n{\n    // We define distinctness by transaction hash.\n    const auto hasher = [](const transaction &transaction) {\n        return transaction.hash();\n    };\n\n    std::vector<hash_digest> hashes(txs.size());\n    std::transform(txs.begin(), txs.end(), hashes.begin(), hasher);\n    std::sort(hashes.begin(), hashes.end());\n    auto distinct_end = std::unique(hashes.begin(), hashes.end());\n#ifdef UC_DEBUG\n    if (distinct_end != hashes.end())\n    {\n        for (auto item : txs)\n            log::warning(LOG_BLOCKCHAIN) << \"hash:\" << encode_hash(item.hash()) << \" data:\" << item.to_string(1);\n    }\n#endif\n    return distinct_end == hashes.end();\n}\n\nbool validate_block::is_valid_time_stamp(uint32_t timestamp) const\n{\n    return check_time_stamp(timestamp, time_stamp_window);\n}\n\nbool validate_block::check_time_stamp(uint32_t timestamp, const asio::seconds &window) const\n{\n    // Use system clock because we require accurate time of day.\n    typedef std::chrono::system_clock wall_clock;\n    const auto block_time = wall_clock::from_time_t(timestamp);\n    const auto future_time = wall_clock::now() + window;\n    return block_time <= future_time;\n}\n\n// TODO: move to bc::chain::opcode.\n// Determine if code is in the op_n range.\ninline bool within_op_n(opcode code)\n{\n    const auto value = static_cast<uint8_t>(code);\n    constexpr auto op_1 = static_cast<uint8_t>(opcode::op_1);\n    constexpr auto op_16 = static_cast<uint8_t>(opcode::op_16);\n    return op_1 <= value && value <= op_16;\n}\n\n// TODO: move to bc::chain::opcode.\n// Return the op_n index (i.e. value of n).\ninline uint8_t decode_op_n(opcode code)\n{\n    BITCOIN_ASSERT(within_op_n(code));\n    const auto value = static_cast<uint8_t>(code);\n    constexpr auto op_0 = static_cast<uint8_t>(opcode::op_1) - 1;\n    return value - op_0;\n}\n\n// TODO: move to bc::chain::operation::stack.\ninline size_t count_script_sigops(const operation::stack &operations,\n                                  bool accurate)\n{\n    size_t total_sigs = 0;\n    opcode last_opcode = opcode::bad_operation;\n    for (const auto &op : operations)\n    {\n        if (op.code == opcode::checksig ||\n            op.code == opcode::checksigverify)\n        {\n            total_sigs++;\n        }\n        else if (op.code == opcode::checkmultisig ||\n                 op.code == opcode::checkmultisigverify)\n        {\n            if (accurate && within_op_n(last_opcode))\n                total_sigs += decode_op_n(last_opcode);\n            else\n                total_sigs += multisig_default_sigops;\n        }\n\n        last_opcode = op.code;\n    }\n\n    return total_sigs;\n}\n\n// TODO: move to bc::chain::transaction.\nsize_t validate_block::legacy_sigops_count(const transaction &tx)\n{\n    size_t total_sigs = 0;\n    for (const auto &input : tx.inputs)\n    {\n        const auto &operations = input.script.operations;\n        total_sigs += count_script_sigops(operations, false);\n    }\n\n    for (const auto &output : tx.outputs)\n    {\n        const auto &operations = output.script.operations;\n        total_sigs += count_script_sigops(operations, false);\n    }\n\n    return total_sigs;\n}\n\nsize_t validate_block::legacy_sigops_count(const transaction::list &txs)\n{\n    size_t total_sigs = 0;\n    for (const auto &tx : txs)\n        total_sigs += legacy_sigops_count(tx);\n\n    return total_sigs;\n}\n\n// BUGBUG: we should confirm block hash doesn't exist.\ncode validate_block::accept_block() const\n{\n    const auto &header = current_block_.header;\n    /*if (header.bits != work_required(testnet_))\n        return error::incorrect_proof_of_work;*/\n\n    RETURN_IF_STOPPED();\n\n    //-. future blocktime attack\n#if 0\n    if (header.number >= bc::consensus::future_blocktime_fork_height) {\n\n    } else {\n        if (header.timestamp <= median_time_past())\n            return error::timestamp_too_early;\n    }\n#endif\n\n    RETURN_IF_STOPPED();\n\n    // Txs should be final when included in a block.\n    for (const auto &tx : current_block_.transactions)\n    {\n        if (!tx.is_final(height_, header.timestamp))\n            return error::non_final_transaction;\n\n        RETURN_IF_STOPPED();\n    }\n\n    // Ensure that the block passes checkpoints.\n    // This is both DOS protection and performance optimization for sync.\n    const auto block_hash = header.hash();\n    if (!config::checkpoint::validate(block_hash, height_, checkpoints_))\n        return error::checkpoints_failed;\n\n    RETURN_IF_STOPPED();\n\n    // Reject blocks that are below the minimum version for the current height.\n    if (!is_valid_version())\n        return error::old_version_block;\n\n    RETURN_IF_STOPPED();\n\n    // Enforce rule that the coinbase starts with serialized height.\n    if (is_active(script_context::bip34_enabled) &&\n        !is_valid_coinbase_height(height_, current_block_))\n        return error::coinbase_height_mismatch;\n\n    return error::success;\n}\n\n/*u256 validate_block::work_required(bool is_testnet) const\n{\n    chain::header prev_header = fetch_block(height_ - 1);\n    return HeaderAux::calculateDifficulty(const_cast<chain::header&>(current_block_.header), prev_header);\n}*/\n\nbool validate_block::is_valid_coinbase_height(size_t height, const block &block)\n{\n    // There must be a transaction with an input.\n    if (block.transactions.empty() ||\n        block.transactions.front().inputs.empty())\n        return false;\n\n    // Get the serialized coinbase input script as a byte vector.\n    const auto &actual_tx = block.transactions.front();\n    const auto &actual_script = actual_tx.inputs.front().script;\n    const auto actual = actual_script.to_data(false);\n\n    // Create the expected script as a byte vector.\n    script expected_script;\n    script_number number(height);\n    expected_script.operations.push_back({opcode::special, number.data()});\n    const auto expected = expected_script.to_data(false);\n\n    // Require that the coinbase script match the expected coinbase script.\n    return std::equal(expected.begin(), expected.end(), actual.begin());\n}\n\ncode validate_block::connect_block(hash_digest &err_tx, blockchain::block_chain_impl &chain) const\n{\n    err_tx = null_hash;\n    const auto &transactions = current_block_.transactions;\n\n    // BIP30 duplicate exceptions are spent and are not indexed.\n    if (is_active(script_context::bip30_enabled))\n    {\n        ////////////// TODO: parallelize. //////////////\n        for (const auto &tx : transactions)\n        {\n            if (is_spent_duplicate(tx))\n            {\n                err_tx = tx.hash();\n                return error::duplicate_or_spent;\n            }\n\n            RETURN_IF_STOPPED();\n        }\n    }\n\n    uint64_t fees = 0;\n    size_t total_sigops = 0;\n    const auto count = transactions.size();\n    size_t coinage_reward_coinbase_index = 1;\n    size_t get_coinage_reward_tx_count = 0;\n\n    ////////////// TODO: parallelize. //////////////\n    for (size_t tx_index = 0; tx_index < count; ++tx_index)\n    {\n        uint64_t value_in = 0;\n        const auto &tx = transactions[tx_index];\n\n        // It appears that this is also checked in check_block().\n        total_sigops += legacy_sigops_count(tx);\n        if (total_sigops > max_block_script_sigops)\n            return error::too_many_sigs;\n\n        RETURN_IF_STOPPED();\n\n        // coinbase that has no inputs does not need to check\n        if (tx.is_strict_coinbase())\n            continue;\n\n        for (auto &output : transactions[tx_index].outputs)\n        {\n            if (chain::operation::is_pay_key_hash_with_lock_height_pattern(output.script.operations))\n            {\n                uint64_t lock_height = chain::operation::get_lock_height_from_pay_key_hash_with_lock_height(output.script.operations);\n\n                if (lock_height == VOTE_LOCKED_TIME)\n                {\n                    break;\n                }\n                uint64_t coinbase_lock_height = chain::operation::get_lock_height_from_pay_key_hash_with_lock_height(transactions[coinage_reward_coinbase_index].outputs[0].script.operations);\n\n                if (check_get_coinage_reward_transaction(transactions[coinage_reward_coinbase_index++], output, transactions[tx_index].has_candidate_register()) == false)\n                {\n                    err_tx = transactions[tx_index].hash();\n                    return error::invalid_coinage_reward_coinbase;\n                }\n                ++get_coinage_reward_tx_count;\n            }\n        }\n\n        RETURN_IF_STOPPED();\n\n        // Consensus checks here.\n        if (!validate_inputs(tx, tx_index, value_in, total_sigops))\n        {\n            log::debug(LOG_BLOCKCHAIN) << \"validate inputs of block failed. tx hash:\"\n                                       << encode_hash(tx.hash());\n            err_tx = tx.hash();\n            return error::validate_inputs_failed;\n        }\n\n        RETURN_IF_STOPPED();\n\n        if (!validate_tx_engine::tally_fees(chain, tx, value_in, fees))\n        {\n            err_tx = tx.hash();\n            return error::fees_out_of_range;\n        }\n    }\n\n    if (get_coinage_reward_tx_count != coinage_reward_coinbase_index - 1)\n    {\n        return error::invalid_coinage_reward_coinbase;\n    }\n\n    RETURN_IF_STOPPED();\n\n    const auto &coinbase = transactions.front();\n    const auto reward = coinbase.total_output_value();\n    const auto value = consensus::miner::calculate_block_subsidy(height_, testnet_) + fees;\n    return reward > value ? error::coinbase_too_large : error::success;\n}\n\nbool validate_block::is_spent_duplicate(const transaction &tx) const\n{\n    const auto tx_hash = tx.hash();\n\n    // Is there a matching previous tx?\n    if (!transaction_exists(tx_hash))\n        return false;\n\n    // Are all outputs spent?\n    ////////////// TODO: parallelize. //////////////\n    for (uint32_t output_index = 0; output_index < tx.outputs.size();\n         ++output_index)\n    {\n        if (!is_output_spent({tx_hash, output_index}))\n            return false;\n    }\n\n    return true;\n}\n\nbool validate_block::validate_inputs(const transaction &tx,\n                                     size_t index_in_parent, uint64_t &value_in, size_t &total_sigops) const\n{\n    //BITCOIN_ASSERT(!tx.is_coinbase());\n\n    ////////////// TODO: parallelize. //////////////\n    for (size_t input_index = 0; input_index < tx.inputs.size(); ++input_index)\n        if (!connect_input(index_in_parent, tx, input_index, value_in,\n                           total_sigops))\n        {\n            log::warning(LOG_BLOCKCHAIN) << \"Invalid input [\"\n                                         << encode_hash(tx.hash()) << \":\"\n                                         << input_index << \"]\";\n            return false;\n        }\n\n    return true;\n}\n\nbool validate_block::script_hash_signature_operations_count(size_t &out_count,\n                                                            const script &output_script, const script &input_script)\n{\n    using namespace chain;\n    constexpr auto strict = script::parse_mode::strict;\n\n    if (input_script.operations.empty() ||\n        output_script.pattern() != script_pattern::pay_script_hash)\n    {\n        out_count = 0;\n        return true;\n    }\n\n    const auto &last_data = input_script.operations.back().data;\n    script eval_script;\n    if (!eval_script.from_data(last_data, false, strict))\n    {\n        return false;\n    }\n\n    out_count = count_script_sigops(eval_script.operations, true);\n    return true;\n}\n\nbool validate_block::get_transaction(const hash_digest &tx_hash,\n                                     chain::transaction &prev_tx, size_t &prev_height) const\n{\n    return fetch_transaction(prev_tx, prev_height, tx_hash);\n}\n\nbool validate_block::connect_input(size_t index_in_parent,\n                                   const transaction &current_tx, size_t input_index, uint64_t &value_in,\n                                   size_t &total_sigops) const\n{\n    BITCOIN_ASSERT(input_index < current_tx.inputs.size());\n\n    // Lookup previous output\n    size_t previous_height;\n    transaction previous_tx;\n    const auto &input = current_tx.inputs[input_index];\n    const auto &previous_output = input.previous_output;\n\n    // This searches the blockchain and then the orphan pool up to and\n    // including the current (orphan) block and excluding blocks above fork.\n    if (!fetch_transaction(previous_tx, previous_height, previous_output.hash))\n    {\n        log::warning(LOG_BLOCKCHAIN)\n            << \"Failure fetching input transaction [\"\n            << encode_hash(previous_output.hash) << \"]\";\n        return false;\n    }\n\n    const auto &previous_tx_out = previous_tx.outputs[previous_output.index];\n\n    // Signature operations count if script_hash payment type.\n    size_t count;\n    if (!script_hash_signature_operations_count(count,\n                                                previous_tx_out.script, input.script))\n    {\n        log::warning(LOG_BLOCKCHAIN) << \"Invalid eval script.\";\n        return false;\n    }\n\n    total_sigops += count;\n    if (total_sigops > max_block_script_sigops)\n    {\n        log::warning(LOG_BLOCKCHAIN) << \"Total sigops exceeds block maximum.\";\n        return false;\n    }\n\n    // Get output amount\n    const auto output_value = previous_tx_out.value;\n    if (output_value > max_money())\n    {\n        log::warning(LOG_BLOCKCHAIN) << \"Output money exceeds 21 million.\";\n        return false;\n    }\n\n    // Check coinbase maturity has been reached\n    if (previous_tx.is_coinbase())\n    {\n        BITCOIN_ASSERT(previous_height <= height_);\n        const auto height_difference = height_ - previous_height;\n        if (height_difference < coinbase_maturity)\n        {\n            log::warning(LOG_BLOCKCHAIN) << \"Immature coinbase spend attempt.\";\n            return false;\n        }\n    }\n\n    if (!validate_tx_engine::check_consensus(previous_tx_out.script,\n                                               current_tx, input_index, activations_))\n    {\n        log::warning(LOG_BLOCKCHAIN) << \"Input script invalid consensus.\";\n        return false;\n    }\n\n    // Search for double spends.\n    if (is_output_spent(previous_output, index_in_parent, input_index))\n    {\n        log::warning(LOG_BLOCKCHAIN) << \"Double spend attempt.\";\n        return false;\n    }\n\n    // Increase value_in by this output's value\n    value_in += output_value;\n    if (value_in > max_money())\n    {\n        log::warning(LOG_BLOCKCHAIN) << \"Input money exceeds 21 million.\";\n        return false;\n    }\n\n    return true;\n}\n\n#undef RETURN_IF_STOPPED\n\n} // namespace blockchain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/blockchain/validate_block_impl.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/blockchain/validate_block_impl.hpp>\n#include <UChainService/consensus/miner.hpp>\n\n#include <cstddef>\n#include <UChain/coin.hpp>\n#include <UChain/blockchain/block_info.hpp>\n#include <UChain/blockchain/simple_chain.hpp>\n//#include <UChainService/consensus/miner/MinerAux.h>\n#include <UChain/blockchain/block_chain_impl.hpp>\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\n\n// Value used to define median time past.\nstatic constexpr size_t median_time_past_blocks = 11;\n\nvalidate_block_impl::validate_block_impl(simple_chain &chain,\n                                         size_t fork_index, const block_info::list &orphan_chain,\n                                         size_t orphan_index, size_t height, const chain::block &block,\n                                         bool testnet, const config::checkpoint::list &checks,\n                                         stopped_callback stopped)\n    : validate_block(height, block, testnet, checks, stopped),\n      chain_(chain),\n      height_(height),\n      fork_index_(fork_index),\n      orphan_index_(orphan_index),\n      orphan_chain_(orphan_chain)\n{\n}\n\n/*bool validate_block_impl::is_valid_proof_of_work(const chain::header& header) const\n{\n    chain::header parent_header;\n    if (orphan_index_ != 0) {\n        parent_header = orphan_chain_[orphan_index_ - 1]->actual()->header;\n    }\n    else {\n        static_cast<block_chain_impl&>(chain_).get_header(parent_header, header.number - 1);\n    }\n    return MinerAux::verifySeal(const_cast<chain::header&>(header), parent_header);\n}*/\n\n/*u256 validate_block_impl::previous_block_bits() const\n{\n    // Read block header (top - 1) and return bits\n    return fetch_block(height_ - 1).bits;\n}*/\n\nvalidate_block::versions validate_block_impl::preceding_block_versions(\n    size_t maximum) const\n{\n    // 1000 previous versions maximum sample.\n    // 950 previous versions minimum required for enforcement.\n    // 750 previous versions minimum required for activation.\n    const auto size = std::min(maximum, height_);\n\n    // Read block (top - 1) through (top - 1000) and return version vector.\n    versions result;\n    for (size_t index = 0; index < size; ++index)\n    {\n        const auto version = fetch_block(height_ - index - 1).version;\n\n        // Some blocks have high versions, see block #390777.\n        static const auto maximum = static_cast<uint32_t>(max_uint8);\n        const auto normal = std::min(version, maximum);\n        result.push_back(static_cast<uint8_t>(normal));\n    }\n\n    return result;\n}\n\nuint64_t validate_block_impl::actual_time_span(size_t interval) const\n{\n    BITCOIN_ASSERT(height_ > 0 && height_ >= interval);\n\n    // height - interval and height - 1, return time difference\n    return fetch_block(height_ - 1).timestamp - fetch_block(height_ - interval).timestamp;\n}\n\nuint64_t validate_block_impl::median_time_past() const\n{\n    // Read last 11 (or height if height < 11) block times into array.\n    const auto count = std::min(height_, median_time_past_blocks);\n\n    std::vector<uint64_t> times;\n    for (size_t i = 0; i < count; ++i)\n        times.push_back(fetch_block(height_ - i - 1).timestamp);\n\n    // Sort and select middle (median) value from the array.\n    std::sort(times.begin(), times.end());\n    return times.empty() ? 0 : times[times.size() / 2];\n}\n\nchain::header validate_block_impl::fetch_block(size_t fetch_height) const\n{\n    if (fetch_height > fork_index_)\n    {\n        const auto fetch_index = fetch_height - fork_index_ - 1;\n        BITCOIN_ASSERT(fetch_index <= orphan_index_);\n        BITCOIN_ASSERT(orphan_index_ < orphan_chain_.size());\n        return orphan_chain_[fetch_index]->actual()->header;\n    }\n\n    chain::header out;\n    DEBUG_ONLY(const auto result =)\n    chain_.get_header(out, fetch_height);\n    BITCOIN_ASSERT(result);\n    return out;\n}\n\nbool tx_after_fork(size_t tx_height, size_t fork_index)\n{\n    return tx_height > fork_index;\n}\n\nbool validate_block_impl::transaction_exists(const hash_digest &tx_hash) const\n{\n    uint64_t out_height;\n    chain::transaction unused;\n    const auto result = chain_.get_transaction(unused, out_height, tx_hash);\n    if (!result)\n        return false;\n\n    BITCOIN_ASSERT(out_height <= max_size_t);\n    const auto tx_height = static_cast<size_t>(out_height);\n    return tx_height <= fork_index_;\n}\n\nbool validate_block_impl::is_output_spent(\n    const chain::output_point &outpoint) const\n{\n    hash_digest out_hash;\n    const auto result = chain_.get_outpoint_transaction(out_hash, outpoint);\n    if (!result)\n        return false;\n\n    // Lookup block height. Is the spend after the fork point?\n    return transaction_exists(out_hash);\n}\n\nbool validate_block_impl::fetch_transaction(chain::transaction &tx,\n                                            size_t &tx_height, const hash_digest &tx_hash) const\n{\n    uint64_t out_height;\n    const auto result = chain_.get_transaction(tx, out_height, tx_hash);\n\n    BITCOIN_ASSERT(out_height <= max_size_t);\n    tx_height = static_cast<size_t>(out_height);\n\n    if (!result || tx_after_fork(tx_height, fork_index_))\n    {\n        return fetch_orphan_transaction(tx, tx_height, tx_hash);\n    }\n\n    return true;\n}\n\nbool validate_block_impl::fetch_orphan_transaction(chain::transaction &tx,\n                                                   size_t &tx_height, const hash_digest &tx_hash) const\n{\n    for (size_t orphan = 0; orphan <= orphan_index_; ++orphan)\n    {\n        const auto &orphan_block = orphan_chain_[orphan]->actual();\n        for (const auto &orphan_tx : orphan_block->transactions)\n        {\n            if (orphan_tx.hash() == tx_hash)\n            {\n                // TRANSACTION COPY\n                tx = orphan_tx;\n                tx_height = fork_index_ + orphan + 1;\n                return true;\n            }\n        }\n    }\n\n    return false;\n}\n\nstd::string validate_block_impl::get_uid_from_address_consider_orphan_chain(\n    const std::string &address, const std::string &uid_symbol) const\n{\n    BITCOIN_ASSERT(!address.empty());\n\n    if (address.empty())\n    {\n        log::debug(\"blockchain\") << \"get_uid_from_address_consider_orphan_chain: address is empty\";\n        return \"\";\n    }\n\n    auto orphan = orphan_index_;\n    while (orphan > 0)\n    {\n        const auto &orphan_block = orphan_chain_[--orphan]->actual();\n        for (const auto &orphan_tx : orphan_block->transactions)\n        {\n            // iter outputs\n            for (const auto &output : orphan_tx.outputs)\n            {\n                if (output.is_uid_register() || output.is_uid_transfer())\n                {\n                    if (address == output.get_uid_address())\n                    {\n                        return output.get_uid_symbol();\n                    }\n                }\n            }\n\n            // iter inputs\n            for (const auto &input : orphan_tx.inputs)\n            {\n                size_t previous_height;\n                transaction previous_tx;\n                const auto &previous_output = input.previous_output;\n\n                // This searches the blockchain and then the orphan pool up to and\n                // including the current (orphan) block and excluding blocks above fork.\n                if (!fetch_transaction(previous_tx, previous_height, previous_output.hash))\n                {\n                    log::warning(LOG_BLOCKCHAIN)\n                        << \"Failure fetching input transaction [\"\n                        << encode_hash(previous_output.hash) << \"]\";\n                    return \"\";\n                }\n\n                const auto &previous_tx_out = previous_tx.outputs[previous_output.index];\n\n                if (previous_tx_out.is_uid_register() || previous_tx_out.is_uid_transfer())\n                {\n                    if (address == previous_tx_out.get_uid_address())\n                    {\n                        return \"\";\n                    }\n                }\n            }\n        }\n    }\n\n    return uid_symbol;\n}\n\nbool validate_block_impl::is_uid_match_address_in_orphan_chain(const std::string &uid, const std::string &address) const\n{\n    BITCOIN_ASSERT(!uid.empty());\n    BITCOIN_ASSERT(!address.empty());\n\n    if (address.empty())\n    {\n        log::debug(\"blockchain\") << \"check uid match address in orphan chain: address is null for uid: \" << uid;\n        return false;\n    }\n\n    auto orphan = orphan_index_;\n    while (orphan > 0)\n    {\n        const auto &orphan_block = orphan_chain_[--orphan]->actual();\n        for (const auto &orphan_tx : orphan_block->transactions)\n        {\n            for (auto &output : orphan_tx.outputs)\n            {\n                if (output.is_uid_register() || output.is_uid_transfer())\n                {\n                    if (uid == output.get_uid_symbol())\n                    {\n                        return address == output.get_uid_address();\n                    }\n                }\n            }\n        }\n    }\n\n    return false;\n}\n\nbool validate_block_impl::is_uid_in_orphan_chain(const std::string &uid) const\n{\n    BITCOIN_ASSERT(!uid.empty());\n\n    for (size_t orphan = 0; orphan < orphan_index_; ++orphan)\n    {\n        const auto &orphan_block = orphan_chain_[orphan]->actual();\n        for (const auto &orphan_tx : orphan_block->transactions)\n        {\n            for (auto &output : orphan_tx.outputs)\n            {\n                if (output.is_uid_register())\n                {\n                    if (uid == output.get_uid_symbol())\n                    {\n                        return true;\n                    }\n                }\n            }\n        }\n    }\n\n    return false;\n}\n\nbool validate_block_impl::is_token_in_orphan_chain(const std::string &symbol) const\n{\n    BITCOIN_ASSERT(!symbol.empty());\n\n    for (size_t orphan = 0; orphan < orphan_index_; ++orphan)\n    {\n        const auto &orphan_block = orphan_chain_[orphan]->actual();\n        for (const auto &orphan_tx : orphan_block->transactions)\n        {\n            for (const auto &output : orphan_tx.outputs)\n            {\n                if (output.is_token_issue())\n                {\n                    if (symbol == output.get_token_symbol())\n                    {\n                        return true;\n                    }\n                }\n            }\n        }\n    }\n\n    return false;\n}\n\nbool validate_block_impl::is_token_cert_in_orphan_chain(const std::string &symbol, token_cert_type cert_type) const\n{\n    BITCOIN_ASSERT(!symbol.empty());\n\n    for (size_t orphan = 0; orphan < orphan_index_; ++orphan)\n    {\n        const auto &orphan_block = orphan_chain_[orphan]->actual();\n        for (const auto &orphan_tx : orphan_block->transactions)\n        {\n            for (const auto &output : orphan_tx.outputs)\n            {\n                if (symbol == output.get_token_cert_symbol() &&\n                    cert_type == output.get_token_cert_type())\n                {\n                    return true;\n                }\n            }\n        }\n    }\n\n    return false;\n}\n\nbool validate_block_impl::is_candidate_in_orphan_chain(const std::string &symbol) const\n{\n    BITCOIN_ASSERT(!symbol.empty());\n\n    for (size_t orphan = 0; orphan < orphan_index_; ++orphan)\n    {\n        const auto &orphan_block = orphan_chain_[orphan]->actual();\n        for (const auto &orphan_tx : orphan_block->transactions)\n        {\n            for (const auto &output : orphan_tx.outputs)\n            {\n                if (output.is_candidate_register())\n                {\n                    if (symbol == output.get_candidate_symbol())\n                    {\n                        return true;\n                    }\n                }\n            }\n        }\n    }\n\n    return false;\n}\n\nbool validate_block_impl::is_output_spent(\n    const chain::output_point &previous_output,\n    size_t index_in_parent, size_t input_index) const\n{\n    // Search for double spends. This must be done in both chain AND orphan.\n    // Searching chain when this tx is an orphan is redundant but it does not\n    // happen enough to care.\n    if (is_output_spent(previous_output))\n        return true;\n\n    if (orphan_is_spent(previous_output, index_in_parent, input_index))\n        return true;\n\n    return false;\n}\n\nbool validate_block_impl::orphan_is_spent(\n    const chain::output_point &previous_output,\n    size_t skip_tx, size_t skip_input) const\n{\n    for (size_t orphan = 0; orphan <= orphan_index_; ++orphan)\n    {\n        const auto &orphan_block = orphan_chain_[orphan]->actual();\n        const auto &transactions = orphan_block->transactions;\n\n        BITCOIN_ASSERT(!transactions.empty());\n        BITCOIN_ASSERT(transactions.front().is_coinbase());\n\n        for (size_t tx_index = 0; tx_index < transactions.size(); ++tx_index)\n        {\n            // TODO: too deep, move this section to subfunction.\n            const auto &orphan_tx = transactions[tx_index];\n\n            for (size_t input_index = 0; input_index < orphan_tx.inputs.size(); ++input_index)\n            {\n                const auto &orphan_input = orphan_tx.inputs[input_index];\n\n                if (orphan == orphan_index_ && tx_index == skip_tx && input_index == skip_input)\n                    continue;\n\n                if (orphan_input.previous_output == previous_output)\n                    return true;\n            }\n        }\n    }\n\n    return false;\n}\n\nbool validate_block_impl::check_get_coinage_reward_transaction(const chain::transaction &coinage_reward_coinbase, const chain::output &output, bool is_candidate) const\n{\n    uint64_t lock_height = chain::operation::get_lock_height_from_pay_key_hash_with_lock_height(output.script.operations);\n    uint64_t coinbase_lock_height = chain::operation::get_lock_height_from_pay_key_hash_with_lock_height(coinage_reward_coinbase.outputs[0].script.operations);\n    bc::wallet::payment_address addr1 = bc::wallet::payment_address::extract(coinage_reward_coinbase.outputs[0].script);\n    bc::wallet::payment_address addr2 = bc::wallet::payment_address::extract(output.script);\n    uint64_t coinage_reward_value = libbitcoin::consensus::miner::calculate_lockblock_reward(lock_height, output.value);\n\n    if (is_candidate && output.value != bc::min_lock_to_issue_candidate)\n    {\n        return false;\n    }\n    else\n    {\n        return (is_candidate || addr1 == addr2) && lock_height == coinbase_lock_height && coinage_reward_value == coinage_reward_coinbase.outputs[0].value;\n    }\n}\n\n} // namespace blockchain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/blockchain/validate_tx_engine.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/blockchain/validate_tx_engine.hpp>\n#include <UChain/coin/chain/script/operation.hpp>\n\n#include <cstddef>\n#include <cstdint>\n#include <functional>\n#include <numeric>\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/blockchain/tx_pool.hpp>\n#include <UChain/blockchain/validate_block.hpp>\n#include <UChainService/consensus/miner.hpp>\n\n#ifdef WITH_CONSENSUS\n#include <UChainService/consensus.hpp>\n#endif\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\n\nstatic BC_CONSTEXPR unsigned int min_tx_fee = 10000;\n\nusing namespace chain;\nusing namespace std::placeholders;\n\n// Max transaction size is set to max block size (1,000,000).\nstatic constexpr uint32_t max_transaction_size = 1000000;\n\nvalidate_tx_engine::validate_tx_engine(block_chain &chain,\n                                           const chain::transaction &tx, const validate_block &validate_block)\n    : blockchain_(static_cast<blockchain::block_chain_impl &>(chain)),\n      tx_(std::make_shared<message::tx_message>(tx)),\n      pool_(nullptr),\n      dispatch_(nullptr),\n      validate_block_(&validate_block),\n      tx_hash_(tx.hash())\n{\n}\n\nvalidate_tx_engine::validate_tx_engine(block_chain &chain,\n                                           const chain::transaction &tx, const tx_pool &pool, dispatcher &dispatch)\n    : blockchain_(static_cast<blockchain::block_chain_impl &>(chain)),\n      tx_(std::make_shared<message::tx_message>(tx)),\n      pool_(&pool),\n      dispatch_(&dispatch),\n      validate_block_(nullptr),\n      tx_hash_(tx.hash())\n{\n}\n\nvoid validate_tx_engine::start(validate_handler handler)\n{\n    BITCOIN_ASSERT(tx_ && pool_ && dispatch_);\n\n    handle_validate_ = handler;\n    const auto ec = basic_checks();\n\n    if (ec)\n    {\n        if (ec == error::input_not_found)\n        {\n            handle_validate_(ec, tx_, {current_input_});\n            return;\n        }\n\n        handle_validate_(ec, tx_, {});\n        return;\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n    // TODO: change to fetch_unspent_transaction, spent dups ok (BIP30).\n    ///////////////////////////////////////////////////////////////////////////\n    // Check for duplicates in the blockchain.\n    blockchain_.fetch_transaction(tx_hash_,\n                                  dispatch_->unordered_delegate(\n                                      &validate_tx_engine::handle_duplicate_check,\n                                      shared_from_this(), _1));\n}\n\ncode validate_tx_engine::basic_checks() const\n{\n    const auto ec = check_transaction();\n\n    if (ec)\n        return ec;\n\n    // This should probably preceed check_transaction.\n    if (tx_->is_strict_coinbase())\n        return error::coinbase_transaction;\n\n    // Ummm...\n    //if ((int64)nLockTime > INT_MAX)\n\n    if (!is_standard())\n        return error::is_not_standard;\n\n    if (pool_->is_in_pool(tx_hash_))\n        return error::duplicate;\n\n    // Check for blockchain duplicates in start (after this returns).\n    return error::success;\n}\n\nbool validate_tx_engine::is_standard() const\n{\n    return true;\n}\n\nvoid validate_tx_engine::handle_duplicate_check(\n    const code &ec)\n{\n    if (ec != (code)error::not_found)\n    {\n        ///////////////////////////////////////////////////////////////////////\n        // BUGBUG: overly restrictive, spent dups ok (BIP30).\n        ///////////////////////////////////////////////////////////////////////\n        handle_validate_(error::duplicate, tx_, {});\n        return;\n    }\n\n    // TODO: we may want to allow spent-in-pool (RBF).\n    if (pool_->is_spent_in_pool(tx_))\n    {\n        handle_validate_(error::double_spend, tx_, {});\n        return;\n    }\n\n    // Check inputs, we already know it is not a coinbase tx.\n    blockchain_.fetch_last_height(\n        dispatch_->unordered_delegate(&validate_tx_engine::set_last_height,\n                                      shared_from_this(), _1, _2));\n}\n\nvoid validate_tx_engine::reset(size_t last_height)\n{\n    // Used for checking coinbase maturity\n    last_block_height_ = last_height;\n    current_input_ = 0;\n    value_in_ = 0;\n    token_amount_in_ = 0;\n    token_certs_in_.clear();\n    old_symbol_in_ = \"\";\n    old_cert_symbol_in_ = \"\";\n}\n\nvoid validate_tx_engine::set_last_height(const code &ec,\n                                           size_t last_height)\n{\n    if (ec)\n    {\n        handle_validate_(ec, tx_, {});\n        return;\n    }\n\n    reset(last_height);\n\n    // Begin looping through the inputs, fetching the previous tx.\n    if (!tx_->inputs.empty())\n        next_previous_transaction();\n}\n\nvoid validate_tx_engine::next_previous_transaction()\n{\n    BITCOIN_ASSERT(current_input_ < tx_->inputs.size());\n\n    // First we fetch the parent block height for a transaction.\n    // Needed for checking the coinbase maturity.\n    blockchain_.fetch_transaction_index(\n        tx_->inputs[current_input_].previous_output.hash,\n        dispatch_->unordered_delegate(\n            &validate_tx_engine::previous_tx_index,\n            shared_from_this(), _1, _2));\n}\n\nvoid validate_tx_engine::previous_tx_index(const code &ec,\n                                             size_t parent_height)\n{\n    if (ec)\n    {\n        search_pool_previous_tx();\n        return;\n    }\n\n    BITCOIN_ASSERT(current_input_ < tx_->inputs.size());\n    const auto &prev_tx_hash = tx_->inputs[current_input_].previous_output.hash;\n\n    // Now fetch actual transaction body\n    blockchain_.fetch_transaction(prev_tx_hash,\n                                  dispatch_->unordered_delegate(&validate_tx_engine::handle_previous_tx,\n                                                                shared_from_this(), _1, _2, parent_height));\n}\n\nbool validate_tx_engine::get_previous_tx(chain::transaction &prev_tx,\n                                           uint64_t &prev_height, const chain::input &input) const\n{\n    prev_height = 0;\n    if (pool_)\n    {\n        if (blockchain_.get_transaction(prev_tx, prev_height, input.previous_output.hash))\n        {\n            return true; // find in block chain\n        }\n        if (pool_->find(prev_tx, input.previous_output.hash))\n        {\n            return true; // find in memory pool\n        }\n    }\n    else\n    {\n        size_t temp_height = 0;\n        if (validate_block_ &&\n            validate_block_->get_transaction(input.previous_output.hash, prev_tx, temp_height))\n        {\n            prev_height = temp_height;\n            return true; // find in block chain or orphan pool\n        }\n    }\n    return false; // failed\n}\n\nvoid validate_tx_engine::search_pool_previous_tx()\n{\n    transaction previous_tx;\n    const auto &current_input = tx_->inputs[current_input_];\n\n    if (!pool_->find(previous_tx, current_input.previous_output.hash))\n    {\n        log::debug(LOG_BLOCKCHAIN) << \"search_pool_previous_tx failed: prev hash\"\n                                   << encode_hash(current_input.previous_output.hash);\n        const auto list = point::indexes{current_input_};\n        handle_validate_(error::input_not_found, tx_, list);\n        return;\n    }\n\n    // parent_height ignored here as mempool transactions cannot be coinbase.\n    BITCOIN_ASSERT(!previous_tx.is_coinbase());\n    static constexpr size_t parent_height = 0;\n    handle_previous_tx(error::success, previous_tx, parent_height);\n    unconfirmed_.push_back(current_input_);\n}\n\nvoid validate_tx_engine::handle_previous_tx(const code &ec,\n                                              const transaction &previous_tx, size_t parent_height)\n{\n    if (ec)\n    {\n        log::debug(LOG_BLOCKCHAIN) << \"handle_previous_tx failed: error: \"\n                                   << std::to_string(ec.value()) << \", prev hash: \"\n                                   << encode_hash(previous_tx.hash());\n        const auto list = point::indexes{current_input_};\n        handle_validate_(error::input_not_found, tx_, list);\n        return;\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n    // HACK: this assumes that the mempool is operating at min block version 4.\n    ///////////////////////////////////////////////////////////////////////////\n\n    // Should check if inputs are standard here...\n    if (!connect_input(previous_tx, parent_height))\n    {\n        log::debug(LOG_BLOCKCHAIN) << \"connect_input of transaction failed. prev tx hash:\"\n                                   << encode_hash(previous_tx.hash());\n        const auto list = point::indexes{current_input_};\n        handle_validate_(error::validate_inputs_failed, tx_, list);\n        return;\n    }\n\n    // Search for double spends...\n    blockchain_.fetch_spend(tx_->inputs[current_input_].previous_output,\n                            dispatch_->unordered_delegate(&validate_tx_engine::check_double_spend,\n                                                          shared_from_this(), _1, _2));\n}\n\nvoid validate_tx_engine::check_double_spend(const code &ec,\n                                              const chain::input_point &)\n{\n    if (ec != (code)error::unspent_output)\n    {\n        handle_validate_(error::double_spend, tx_, {});\n        return;\n    }\n\n    // End of connect_input checks.\n    ++current_input_;\n    if (current_input_ < tx_->inputs.size())\n    {\n        next_previous_transaction();\n        return;\n    }\n\n    // current_input_ will be invalid on last pass.\n    check_fees();\n}\n\nvoid validate_tx_engine::check_fees() const\n{\n    code ec = check_tx_connect_input();\n    if (ec != error::success)\n    {\n        handle_validate_(ec, tx_, {});\n        return;\n    }\n    if (tx_->has_token_vote())\n    {\n        code eo = check_tx_connect_output();\n        if (eo != error::success)\n        {\n            handle_validate_(eo, tx_, {});\n            return;\n        }\n    }\n\n    // Who cares?\n    // Fuck the police\n    // Every tx equal!\n    handle_validate_(error::success, tx_, unconfirmed_);\n}\n\ncode validate_tx_engine::check_tx_connect_input() const\n{\n    uint64_t fee = 0;\n\n    if (!tally_fees(blockchain_, *tx_, value_in_, fee))\n    {\n        return error::fees_out_of_range;\n    }\n\n    if (tx_->has_token_transfer())\n    {\n        if (!check_token_amount(*tx_))\n        {\n            return error::token_amount_not_equal;\n        }\n        if (!check_token_symbol(*tx_))\n        {\n            return error::token_symbol_not_match;\n        }\n    }\n\n    if (tx_->has_token_cert())\n    {\n        if (!check_token_certs(*tx_))\n        {\n            log::debug(LOG_BLOCKCHAIN) << \"failed to check token cert.\" << tx_->to_string(1);\n            return error::token_cert_error;\n        }\n    }\n\n    if (tx_->has_candidate_transfer())\n    {\n        if (!check_candidate(*tx_))\n        {\n            log::debug(LOG_BLOCKCHAIN) << \"failed to check candidate token.\" << tx_->to_string(1);\n            return error::candidate_error;\n        }\n    }\n\n    if (tx_->has_uid_transfer())\n    {\n        if (!check_uid_symbol_match(*tx_))\n        {\n            return error::uid_symbol_not_match;\n        }\n    }\n\n    return error::success;\n}\n\ncode validate_tx_engine::check_tx_connect_output() const\n{\n    uint64_t value = 0, quatity = 0, lock_height = 0;\n\n    for (auto &ele : tx_->outputs)\n    {\n        if (chain::operation::is_pay_key_hash_with_lock_height_pattern(ele.script.operations))\n        {\n            lock_height = chain::operation::get_lock_height_from_pay_key_hash_with_lock_height(ele.script.operations);\n            if (lock_height == VOTE_LOCKED_TIME)\n                value += ele.value;\n        }\n        if (ele.is_vote())\n        {\n            auto &&token_transfer = ele.get_token_transfer();\n            quatity += token_transfer.get_quantity();\n        }\n    }\n\n    if (quatity * TIMES_QUANTITY_TO_VALUE != value)\n    { // TODO: for debug\n        return error::invalid_quantity_or_value;\n    }\n    return error::success;\n}\n\nstatic bool check_same(std::string &dest, const std::string &src)\n{\n    if (dest.empty())\n    {\n        dest = src;\n    }\n    else if (dest != src)\n    {\n        log::debug(LOG_BLOCKCHAIN) << \"check_same: \" << dest << \" != \" << src;\n        return false;\n    }\n    return true;\n}\n\ncode validate_tx_engine::check_secondaryissue_transaction() const\n{\n    const chain::transaction &tx = *tx_;\n    blockchain::block_chain_impl &blockchain = blockchain_;\n\n    bool is_token_secondaryissue{false};\n    for (auto &output : tx.outputs)\n    {\n        if (output.is_token_secondaryissue())\n        {\n            is_token_secondaryissue = true;\n            break;\n        }\n    }\n    if (!is_token_secondaryissue)\n    {\n        return error::success;\n    }\n\n    is_token_secondaryissue = false;\n    std::string token_symbol;\n    std::string token_address;\n    std::string token_cert_owner;\n    uint8_t secondaryissue_threshold{0};\n    uint64_t secondaryissue_token_amount{0};\n    uint64_t token_transfer_volume{0};\n    int num_token_secondaryissue{0};\n    int num_token_transfer{0};\n    int num_token_cert{0};\n    std::vector<token_cert_type> certs_out;\n    for (auto &output : tx.outputs)\n    {\n        if (output.is_token_secondaryissue())\n        {\n            ++num_token_secondaryissue;\n            if (num_token_secondaryissue > 1)\n            {\n                log::debug(LOG_BLOCKCHAIN) << \"secondaryissue: num of secondaryissue output > 1, \" << token_symbol;\n                return error::token_secondaryissue_error;\n            }\n\n            auto &&token_detail = output.get_token_detail();\n            if (!token_detail.is_token_secondaryissue() || !token_detail.is_secondaryissue_threshold_value_ok())\n            {\n                log::debug(LOG_BLOCKCHAIN) << \"secondaryissue: threshold value invalid, \" << token_symbol;\n                return error::token_secondaryissue_threshold_invalid;\n            }\n            if (!check_same(token_symbol, token_detail.get_symbol()))\n            {\n                return error::token_secondaryissue_error;\n            }\n            if (!check_same(token_address, token_detail.get_address()))\n            {\n                return error::token_secondaryissue_error;\n            }\n            if (operation::is_pay_key_hash_with_attenuation_model_pattern(output.script.operations))\n            {\n                const auto &model_param = output.get_attenuation_model_param();\n                if (!attenuation_model::check_model_param(\n                        model_param, token_detail.get_maximum_supply()))\n                {\n                    log::debug(LOG_BLOCKCHAIN) << \"secondaryissue: model param invalid, \"\n                                               << token_symbol << \" \" << model_param;\n                    return error::attenuation_model_param_error;\n                }\n            }\n            secondaryissue_threshold = token_detail.get_secondaryissue_threshold();\n            secondaryissue_token_amount = token_detail.get_maximum_supply();\n        }\n        else if (output.is_token_transfer())\n        {\n            ++num_token_transfer;\n            auto &&token_transfer = output.get_token_transfer();\n            if (!check_same(token_symbol, token_transfer.get_symbol()))\n            {\n                return error::token_secondaryissue_error;\n            }\n            if (!check_same(token_address, output.get_script_address()))\n            {\n                return error::token_secondaryissue_error;\n            }\n            token_transfer_volume += token_transfer.get_quantity();\n        }\n        else if (output.is_token_cert())\n        {\n            ++num_token_cert;\n            if (num_token_cert > 1)\n            {\n                log::debug(LOG_BLOCKCHAIN) << \"secondaryissue: cert numbers > 1, \" << token_symbol;\n                return error::token_secondaryissue_error;\n            }\n            auto &&token_cert = output.get_token_cert();\n            auto cur_cert_type = token_cert.get_type();\n            if (cur_cert_type == token_cert_ns::issue)\n            {\n                if (!check_same(token_symbol, token_cert.get_symbol()))\n                {\n                    return error::token_secondaryissue_error;\n                }\n                if (!check_same(token_cert_owner, token_cert.get_owner()))\n                {\n                    return error::token_secondaryissue_error;\n                }\n                certs_out.push_back(cur_cert_type);\n            }\n            else\n            {\n                log::debug(LOG_BLOCKCHAIN) << \"secondaryissue: invalid output of cert \"\n                                           << token_cert.to_string();\n                return error::token_secondaryissue_error;\n            }\n        }\n        else if (!output.is_ucn() && !output.is_message())\n        {\n            log::debug(LOG_BLOCKCHAIN) << \"secondaryissue: illega output, \"\n                                       << token_symbol << \" : \" << output.to_string(1);\n            return error::token_secondaryissue_error;\n        }\n    }\n\n    if (tx.version >= transaction_version::check_uid_feature && !token_cert::test_certs(certs_out, token_cert_ns::issue))\n    {\n        log::debug(LOG_BLOCKCHAIN) << \"secondaryissue: no issue token cert, \" << token_symbol;\n        return error::token_cert_error;\n    }\n\n    auto total_volume = blockchain.get_token_volume(token_symbol);\n    if (total_volume > max_uint64 - secondaryissue_token_amount)\n    {\n        log::debug(LOG_BLOCKCHAIN)\n            << \"secondaryissue: total token volume cannot exceed maximum value, \"\n            << token_symbol;\n        return error::token_secondaryissue_error;\n    }\n\n    if (!token_detail::is_secondaryissue_owns_enough(token_transfer_volume, total_volume, secondaryissue_threshold))\n    {\n        log::debug(LOG_BLOCKCHAIN) << \"secondaryissue: no enough token volume, \" << token_symbol;\n        return error::token_secondaryissue_share_not_enough;\n    }\n\n    // check inputs token address\n    for (const auto &input : tx.inputs)\n    {\n        chain::transaction prev_tx;\n        uint64_t prev_height{0};\n        if (!get_previous_tx(prev_tx, prev_height, input))\n        {\n            log::debug(LOG_BLOCKCHAIN) << \"secondaryissue: input not found: \"\n                                       << encode_hash(input.previous_output.hash);\n            return error::input_not_found;\n        }\n        auto prev_output = prev_tx.outputs.at(input.previous_output.index);\n        if (prev_output.is_token() || prev_output.is_token_cert())\n        {\n            auto &&token_address_in = prev_output.get_script_address();\n            if (prev_output.is_token_cert())\n            {\n                auto &&prev_token_cert = prev_output.get_token_cert();\n                if (prev_token_cert.get_symbol() != token_symbol || prev_token_cert.get_type() != token_cert_ns::issue)\n                {\n                    log::debug(LOG_BLOCKCHAIN) << \"secondaryissue: invalid cert input, \" << token_symbol;\n                    return error::validate_inputs_failed;\n                }\n            }\n            else if (token_address != token_address_in)\n            {\n                log::debug(LOG_BLOCKCHAIN) << \"secondaryissue: invalid token input, \" << token_symbol;\n                return error::validate_inputs_failed;\n            }\n        }\n    }\n\n    return error::success;\n}\n\ncode validate_tx_engine::check_token_issue_transaction() const\n{\n    const chain::transaction &tx = *tx_;\n    blockchain::block_chain_impl &chain = blockchain_;\n\n    bool is_token_issue{false};\n    for (auto &output : tx.outputs)\n    {\n        if (output.is_token_issue())\n        {\n            is_token_issue = true;\n            break;\n        }\n    }\n    if (!is_token_issue)\n    {\n        return error::success;\n    }\n\n    is_token_issue = false;\n    int num_cert_issue{0};\n    int num_cert_domain_or_naming{0};\n    std::vector<token_cert_type> cert_mask;\n    std::vector<token_cert_type> cert_type;\n    std::string token_symbol;\n    std::string token_address;\n    std::string cert_owner;\n    for (auto &output : tx.outputs)\n    {\n        if (output.is_token_issue())\n        {\n            if (is_token_issue)\n            {\n                // can not issue multiple tokens at the same transaction\n                return error::token_issue_error;\n            }\n            is_token_issue = true;\n            token_detail &&detail = output.get_token_detail();\n            if (!detail.is_secondaryissue_threshold_value_ok())\n            {\n                return error::token_secondaryissue_threshold_invalid;\n            }\n            if (!check_same(token_symbol, detail.get_symbol()))\n            {\n                return error::token_issue_error;\n            }\n            if (!check_same(token_address, detail.get_address()))\n            {\n                return error::token_issue_error;\n            }\n            if (check_token_exist(token_symbol))\n            {\n                return error::token_exist;\n            }\n            if (operation::is_pay_key_hash_with_attenuation_model_pattern(output.script.operations))\n            {\n                const auto &model_param = output.get_attenuation_model_param();\n                if (!attenuation_model::check_model_param(\n                        model_param, detail.get_maximum_supply()))\n                {\n                    log::debug(LOG_BLOCKCHAIN) << \"issue: model param invalid, \"\n                                               << token_symbol << \" \" << model_param;\n                    return error::attenuation_model_param_error;\n                }\n            }\n            cert_mask = detail.get_token_cert_mask();\n        }\n        else if (output.is_token_cert())\n        {\n            token_cert &&cert_info = output.get_token_cert();\n\n            // check cert\n            token_cert_type cur_cert_type = cert_info.get_type();\n            if (cur_cert_type == token_cert_ns::issue)\n            {\n                ++num_cert_issue;\n                if (num_cert_issue > 1)\n                {\n                    return error::token_issue_error;\n                }\n\n                if (!check_same(token_symbol, cert_info.get_symbol()))\n                {\n                    return error::token_issue_error;\n                }\n\n                if (!check_same(token_address, output.get_script_address()))\n                {\n                    return error::token_issue_error;\n                }\n            }\n            else if (cur_cert_type == token_cert_ns::domain)\n            {\n                ++num_cert_domain_or_naming;\n                if (num_cert_domain_or_naming > 1)\n                {\n                    return error::token_issue_error;\n                }\n\n                if (!token_symbol.empty())\n                {\n                    auto &&domain = token_cert::get_domain(token_symbol);\n                    if (domain != cert_info.get_symbol())\n                    {\n                        return error::token_issue_error;\n                    }\n                }\n\n                if (!check_same(cert_owner, cert_info.get_owner()))\n                {\n                    return error::token_issue_error;\n                }\n            }\n            else if (cur_cert_type == token_cert_ns::naming)\n            {\n                ++num_cert_domain_or_naming;\n                if (num_cert_domain_or_naming > 1)\n                {\n                    return error::token_issue_error;\n                }\n\n                if (!check_same(token_symbol, cert_info.get_symbol()))\n                {\n                    return error::token_issue_error;\n                }\n\n                if (!check_same(cert_owner, cert_info.get_owner()))\n                {\n                    return error::token_issue_error;\n                }\n            }\n            else\n            {\n                log::debug(LOG_BLOCKCHAIN) << \"issue: invalid output of cert \"\n                                           << cert_info.to_string();\n                return error::token_issue_error;\n            }\n\n            cert_type.push_back(cur_cert_type);\n        }\n        else if (!output.is_ucn() && !output.is_message())\n        {\n            log::debug(LOG_BLOCKCHAIN) << \"issue: illega output, \"\n                                       << token_symbol << \" : \" << output.to_string(1);\n            return error::token_issue_error;\n        }\n    }\n\n    // check cert for transactions after check_uid_feature version.\n    if (tx.version >= transaction_version::check_uid_feature)\n    {\n        if (!token_cert::test_certs(cert_type, cert_mask))\n        {\n            log::debug(LOG_BLOCKCHAIN) << \"issue token: \"\n                                       << \"not enough cert.\";\n            return error::token_issue_error;\n        }\n\n        auto &&domain = token_cert::get_domain(token_symbol);\n        if (token_cert::is_valid_domain(domain))\n        {\n            if (cert_owner.empty())\n            {\n                log::debug(LOG_BLOCKCHAIN) << \"issue token: owner of cert \"\n                                           << token_symbol << \" is empty!\";\n                return error::token_cert_error;\n            }\n\n            if (num_cert_domain_or_naming < 1)\n            {\n                // no valid domain or naming cert\n                log::debug(LOG_BLOCKCHAIN) << \"issue token: not cert provided!\";\n                return error::token_cert_not_provided;\n            }\n        }\n    }\n\n    return error::success;\n}\n\ncode validate_tx_engine::check_token_cert_transaction() const\n{\n    const chain::transaction &tx = *tx_;\n    blockchain::block_chain_impl &chain = blockchain_;\n\n    bool is_cert{false};\n    for (auto &output : tx.outputs)\n    {\n        if (output.is_token_cert_issue() || output.is_token_cert_transfer())\n        {\n            is_cert = true;\n            break;\n        }\n    }\n\n    if (!is_cert)\n    {\n        return error::success;\n    }\n\n    int num_cert_issue{0};\n    int num_cert_domain{0};\n    int num_cert_transfer{0};\n    token_cert_type issue_cert_type{token_cert_ns::none};\n    std::vector<token_cert_type> cert_type;\n    std::string cert_symbol;\n    std::string domain_symbol;\n    std::string cert_owner;\n    for (auto &output : tx.outputs)\n    {\n        if (output.is_token_cert_issue())\n        {\n            ++num_cert_issue;\n            if (num_cert_issue > 1)\n            {\n                // can not issue multiple token cert at the same transaction\n                return error::token_cert_issue_error;\n            }\n\n            token_cert &&cert_info = output.get_token_cert();\n            token_cert_type cur_cert_type = cert_info.get_type();\n\n            if (!check_same(cert_symbol, cert_info.get_symbol()))\n            {\n                log::debug(LOG_BLOCKCHAIN) << \"issue cert: \"\n                                           << cert_info.get_symbol() << \" does not match.\";\n                return error::token_cert_issue_error;\n            }\n\n            // check cert not exists\n            if (check_token_cert_exist(cert_symbol, cur_cert_type))\n            {\n                log::debug(LOG_BLOCKCHAIN) << \"issue cert: \"\n                                           << cert_info.get_symbol() << \" already exists.\";\n                return error::token_cert_exist;\n            }\n\n            issue_cert_type = cur_cert_type;\n        }\n        else if (output.is_token_cert_transfer())\n        {\n            ++num_cert_transfer;\n            if (num_cert_transfer > 1)\n            {\n                // can not transfer multiple token cert at the same transaction\n                return error::token_cert_error;\n            }\n\n            token_cert &&cert_info = output.get_token_cert();\n            if (!check_same(cert_symbol, cert_info.get_symbol()))\n            {\n                log::debug(LOG_BLOCKCHAIN) << \"transfer cert: \"\n                                           << cert_info.get_symbol() << \" does not match.\";\n                return error::token_cert_error;\n            }\n        }\n        else if (output.is_token_cert())\n        {\n            token_cert &&cert_info = output.get_token_cert();\n\n            // check cert\n            token_cert_type cur_cert_type = cert_info.get_type();\n            if (cur_cert_type == token_cert_ns::domain)\n            {\n                if (issue_cert_type != token_cert_ns::naming)\n                {\n                    log::debug(LOG_BLOCKCHAIN) << \"issue cert: redundant output of domain cert.\";\n                    return error::token_cert_issue_error;\n                }\n\n                ++num_cert_domain;\n                if (num_cert_domain > 1)\n                {\n                    return error::token_cert_issue_error;\n                }\n\n                domain_symbol = cert_info.get_symbol();\n\n                // check owner\n                cert_owner = cert_info.get_owner();\n                auto uiddetail = chain.get_registered_uid(cert_owner);\n                auto address = cert_info.get_address();\n                if (!uiddetail)\n                {\n                    log::debug(LOG_BLOCKCHAIN) << \"issue cert: cert owner is not issued. \"\n                                               << cert_info.to_string();\n                    return error::token_cert_issue_error;\n                }\n                if (address != uiddetail->get_address())\n                {\n                    log::debug(LOG_BLOCKCHAIN) << \"issue cert: cert address dismatch cert owner. \"\n                                               << cert_info.to_string();\n                    return error::token_cert_issue_error;\n                }\n            }\n            else\n            {\n                log::debug(LOG_BLOCKCHAIN) << \"issue cert: invalid output of cert \"\n                                           << cert_info.to_string();\n                return error::token_cert_issue_error;\n            }\n\n            cert_type.push_back(cur_cert_type);\n        }\n        else if (!output.is_ucn() && !output.is_message())\n        {\n            log::debug(LOG_BLOCKCHAIN) << \"cert: illegal output asset type:\"\n                                       << output.attach_data.get_type()\n                                       << \", tx: \" << output.to_string(1);\n            return error::token_cert_issue_error;\n        }\n    }\n\n    if ((num_cert_issue == 0 && num_cert_transfer == 0) || (num_cert_issue > 0 && num_cert_transfer > 0) || (num_cert_transfer > 0 && num_cert_domain > 0))\n    {\n        log::debug(LOG_BLOCKCHAIN) << \"cert: illegal output.\";\n        return error::token_cert_error;\n    }\n\n    if (num_cert_issue == 1)\n    {\n        if (issue_cert_type == token_cert_ns::none)\n        {\n            return error::token_cert_issue_error;\n        }\n\n        if (issue_cert_type == token_cert_ns::naming)\n        {\n            if (!token_cert::test_certs(cert_type, token_cert_ns::domain) || cert_owner.empty())\n            {\n                log::debug(LOG_BLOCKCHAIN) << \"issue cert: \"\n                                           << \"no domain cert provided to issue naming cert.\";\n                return error::token_cert_issue_error;\n            }\n\n            auto &&domain = token_cert::get_domain(cert_symbol);\n            if (domain != domain_symbol)\n            {\n                log::debug(LOG_BLOCKCHAIN) << \"issue cert: \"\n                                           << \"invalid domain cert provided to issue naming cert.\";\n                return error::token_cert_issue_error;\n            }\n\n            // check token not exist.\n            if (check_token_exist(cert_symbol))\n            {\n                log::debug(LOG_BLOCKCHAIN) << \"issue cert: \"\n                                           << \"token symbol '\" + cert_symbol + \"' already exists in blockchain!\";\n                return error::token_exist;\n            }\n        }\n    }\n\n    return error::success;\n}\n\ncode validate_tx_engine::check_candidate_transaction() const\n{\n    const chain::transaction &tx = *tx_;\n    blockchain::block_chain_impl &chain = blockchain_;\n\n    bool is_candidate{false};\n    for (auto &output : tx.outputs)\n    {\n        if (output.is_candidate())\n        {\n            is_candidate = true;\n            break;\n        }\n    }\n\n    if (!is_candidate)\n    {\n        return error::success;\n    }\n\n    std::string token_symbol;\n    std::string token_address;\n    size_t num_candidate_transfer = 0;\n    size_t num_candidate_register = 0;\n    for (auto &output : tx.outputs)\n    {\n        if (output.is_candidate_register())\n        {\n            ++num_candidate_register;\n\n            auto &&token_info = output.get_candidate();\n            token_symbol = token_info.get_symbol();\n\n            if (!check_same(token_address, token_info.get_address()))\n            {\n                log::debug(LOG_BLOCKCHAIN) << \"register candidate: \"\n                                           << \" address is not same. \"\n                                           << token_address << \" != \" << token_info.get_address();\n                return error::candidate_register_error;\n            }\n\n            // check token not exists\n            if (check_candidate_exist(token_symbol))\n            {\n                log::debug(LOG_BLOCKCHAIN) << \"register candidate: \"\n                                           << token_symbol << \" already exists.\";\n                return error::candidate_exist;\n            }\n        }\n        else if (output.is_candidate_transfer())\n        {\n            if (++num_candidate_transfer > 1)\n            {\n                log::debug(LOG_BLOCKCHAIN) << \"transfer candidate: more than on candidate output.\" << output.to_string(1);\n                return error::candidate_error;\n            }\n\n            auto &&token_info = output.get_candidate();\n            token_symbol = token_info.get_symbol();\n        }\n        else if (output.is_ucn())\n        {\n            if (!check_same(token_address, output.get_script_address()))\n            {\n                log::debug(LOG_BLOCKCHAIN) << \"candidate: \"\n                                           << \" address is not same. \"\n                                           << token_address << \" != \" << output.get_script_address();\n                return error::candidate_register_error;\n            }\n        }\n        else if (!output.is_message())\n        {\n            log::debug(LOG_BLOCKCHAIN) << \"candidate: illegal output, \"\n                                       << token_symbol << \" : \" << output.to_string(1);\n            return error::candidate_error;\n        }\n    }\n\n    if ((num_candidate_register == 0 && num_candidate_transfer == 0) || (num_candidate_register > 0 && num_candidate_transfer > 0))\n    {\n        log::debug(LOG_BLOCKCHAIN) << \"candidate: illegal output.\";\n        return error::candidate_error;\n    }\n\n    // check inputs\n    bool has_input_transfer = false;\n    for (const auto &input : tx.inputs)\n    {\n        chain::transaction prev_tx;\n        uint64_t prev_height{0};\n        if (!get_previous_tx(prev_tx, prev_height, input))\n        {\n            log::debug(LOG_BLOCKCHAIN) << \"candidate: input not found: \"\n                                       << encode_hash(input.previous_output.hash);\n            return error::input_not_found;\n        }\n\n        auto prev_output = prev_tx.outputs.at(input.previous_output.index);\n        if (prev_output.is_ucn())\n        {\n            auto &&token_address_in = prev_output.get_script_address();\n            if (token_address != token_address_in)\n            {\n                log::debug(LOG_BLOCKCHAIN) << \"candidate: invalid input address to pay fee: \"\n                                           << token_address_in << \" != \" << token_address;\n                return error::validate_inputs_failed;\n            }\n        }\n        else if (prev_output.is_candidate())\n        {\n            auto &&token_info = prev_output.get_candidate();\n            if (token_symbol != token_info.get_symbol())\n            {\n                log::debug(LOG_BLOCKCHAIN) << \"candidate: invalid candidate to transfer: \"\n                                           << token_info.get_symbol() << \" != \" << token_symbol;\n                return error::validate_inputs_failed;\n            }\n\n            has_input_transfer = true;\n        }\n    }\n\n    if (num_candidate_transfer > 0 && !has_input_transfer)\n    {\n        log::debug(LOG_BLOCKCHAIN) << \"candidate: no input candidate to transfer \" << token_symbol;\n        return error::validate_inputs_failed;\n    }\n\n    return error::success;\n}\n\nbool validate_tx_engine::check_uid_exist(const std::string &uid) const\n{\n    uint64_t height = blockchain_.get_uid_height(uid);\n\n    if (validate_block_)\n    {\n        //register before fork or find in orphan chain\n        if (height <= validate_block_->get_fork_index() || validate_block_->is_uid_in_orphan_chain(uid))\n        {\n            return true;\n        }\n\n        return false;\n    }\n\n    return height != max_uint64;\n}\n\nbool validate_tx_engine::check_token_exist(const std::string &symbol) const\n{\n    uint64_t height = blockchain_.get_token_height(symbol);\n\n    if (validate_block_)\n    {\n        //register before fork or find in orphan chain\n        if (height <= validate_block_->get_fork_index() || validate_block_->is_token_in_orphan_chain(symbol))\n        {\n            return true;\n        }\n\n        return false;\n    }\n\n    return height != max_uint64;\n}\n\nbool validate_tx_engine::check_token_cert_exist(const std::string &cert, token_cert_type cert_type) const\n{\n    uint64_t height = blockchain_.get_token_cert_height(cert, cert_type);\n\n    if (validate_block_)\n    {\n        //register before fork or find in orphan chain\n        if (height <= validate_block_->get_fork_index() || validate_block_->is_token_cert_in_orphan_chain(cert, cert_type))\n        {\n            return true;\n        }\n\n        return false;\n    }\n\n    return height != max_uint64;\n}\n\nbool validate_tx_engine::check_candidate_exist(const std::string &candidate) const\n{\n    uint64_t height = blockchain_.get_candidate_height(candidate);\n\n    if (validate_block_)\n    {\n        //register before fork or find in orphan chain\n        if (height <= validate_block_->get_fork_index() || validate_block_->is_candidate_in_orphan_chain(candidate))\n        {\n            return true;\n        }\n\n        return false;\n    }\n\n    return height != max_uint64;\n}\n\nbool validate_tx_engine::check_address_registered_uid(const std::string &address) const\n{\n    uint64_t fork_index = validate_block_ ? validate_block_->get_fork_index() : max_uint64;\n    auto uid_symbol = blockchain_.get_uid_from_address(address, fork_index);\n    if (!validate_block_)\n    {\n        if (uid_symbol.empty())\n        {\n            return false;\n        }\n    }\n    else\n    {\n        uid_symbol = validate_block_->get_uid_from_address_consider_orphan_chain(address, uid_symbol);\n        if (uid_symbol.empty())\n        {\n            return false;\n        }\n    }\n\n    log::debug(LOG_BLOCKCHAIN) << \"address \" << address << \" already exists uid \" << uid_symbol;\n    return true;\n}\n\ncode validate_tx_engine::check_uid_transaction() const\n{\n    const chain::transaction &tx = *tx_;\n    blockchain::block_chain_impl &chain = blockchain_;\n    uint64_t fork_index = validate_block_ ? validate_block_->get_fork_index() : max_uint64;\n\n    code ret = error::success;\n\n    uint8_t type = 255;\n\n    for (const auto &output : tx.outputs)\n    {\n        if ((ret = output.check_asset_address(chain)) != error::success)\n            return ret;\n\n        //to_uid check(strong check)\n        if ((ret = check_asset_to_uid(output)) != error::success)\n            return ret;\n\n        //from_uid (weak check)\n        if ((ret = connect_asset_from_uid(output)) != error::success)\n        {\n            return ret;\n        }\n\n        if (output.is_uid_register())\n        {\n            if (chain.is_valid_address(output.get_uid_symbol()))\n            {\n                return error::uid_symbol_invalid;\n            }\n\n            if (check_uid_exist(output.get_uid_symbol()))\n            {\n                log::debug(LOG_BLOCKCHAIN) << \"uid_register: \"\n                                           << output.get_uid_symbol() << \" already exists\";\n                return error::uid_exist;\n            }\n\n            if (check_address_registered_uid(output.get_uid_address()))\n            {\n                log::debug(LOG_BLOCKCHAIN) << \"address \"\n                                           << output.get_uid_address() << \" already exists uid, cannot register uid.\";\n                return error::address_registered_uid;\n            }\n\n            if (type != 255)\n            {\n                return error::uid_multi_type_exist;\n            }\n            type = UID_DETAIL_TYPE;\n\n            if (!connect_uid_input(boost::get<uid>(output.get_uid())))\n            {\n                return error::uid_input_error;\n            }\n        }\n        else if (output.is_uid_transfer())\n        {\n            if (check_address_registered_uid(output.get_uid_address()))\n            {\n                log::debug(LOG_BLOCKCHAIN) << \"address \"\n                                           << output.get_uid_address() << \" already exists uid, cannot transfer uid.\";\n                return error::address_registered_uid;\n            }\n            if (chain.exist_in_candidates(output.get_uid_symbol()))\n                return error::uid_in_candidate;\n\n            if (type != 255)\n            {\n                return error::uid_multi_type_exist;\n            }\n            type = UID_TRANSFERABLE_TYPE;\n\n            if (!connect_uid_input(boost::get<uid>(output.get_uid())))\n            {\n                return error::uid_input_error;\n            }\n        }\n        else if (output.is_token_issue() || output.is_token_secondaryissue())\n        {\n            if (output.attach_data.get_version() == UID_ASSET_VERIFY_VERSION && output.get_token_issuer() != output.attach_data.get_to_uid())\n            {\n                log::debug(LOG_BLOCKCHAIN)\n                    << \"token issuer \" << output.get_token_issuer()\n                    << \" , does not match uid \" << output.attach_data.get_to_uid()\n                    << \" , attach_data: \" << output.attach_data.to_string();\n                return error::token_uid_registerr_not_match;\n            }\n        }\n        else if (output.is_token_cert())\n        {\n            if (output.attach_data.get_version() == UID_ASSET_VERIFY_VERSION)\n            {\n                if (output.get_token_cert_owner() != output.attach_data.get_to_uid())\n                {\n                    log::debug(LOG_BLOCKCHAIN)\n                        << \"cert owner \" << output.get_token_cert_owner()\n                        << \" , does not match uid \" << output.attach_data.get_to_uid()\n                        << \" , attach_data: \" << output.attach_data.to_string();\n                    return error::token_uid_registerr_not_match;\n                }\n            }\n        }\n        else if (output.is_vote() || output.is_candidate_transfer())\n        {\n            if (!output.is_uid_full_filled())\n            {\n                log::debug(LOG_BLOCKCHAIN)\n                    << \"both fromuid and touid are needed , attach_data: \" << output.attach_data.to_string();\n                return error::token_uid_registerr_not_match;\n            }\n        }\n        else if (output.is_ucn_award())\n        {\n            if (!output.is_touid_filled())\n            {\n                log::debug(LOG_BLOCKCHAIN)\n                    << \"touid is needed , attach_data: \" << output.attach_data.to_string();\n                return error::token_uid_registerr_not_match;\n            }\n        }\n        else if (output.is_candidate_register())\n        {\n            if (!output.is_fromuid_filled())\n            {\n                log::debug(LOG_BLOCKCHAIN)\n                    << \"fromuid is needed , attach_data: \" << output.attach_data.to_string();\n                return error::token_uid_registerr_not_match;\n            }\n            if (chain.exist_in_candidates(output.attach_data.get_from_uid()))\n                return error::uid_in_candidate;\n        }\n    }\n\n    return ret;\n}\n\nbool validate_tx_engine::connect_uid_input(const uid &info) const\n{\n    const chain::transaction &tx = *tx_;\n    blockchain::block_chain_impl &chain = blockchain_;\n\n    if (info.get_status() == UID_TRANSFERABLE_TYPE && tx.inputs.size() != 2)\n    {\n        return false;\n    }\n\n    auto detail_info = boost::get<uid_detail>(info.get_data());\n    bool found_uid_info = false;\n    bool found_address_info = false;\n\n    for (const auto &input : tx.inputs)\n    {\n        chain::transaction prev_tx;\n        uint64_t prev_height{0};\n        if (!get_previous_tx(prev_tx, prev_height, input))\n        {\n            log::debug(LOG_BLOCKCHAIN) << \"connect_uid_input: input not found: \"\n                                       << encode_hash(input.previous_output.hash);\n            return false;\n        }\n\n        auto prev_output = prev_tx.outputs.at(input.previous_output.index);\n\n        if (prev_output.is_uid_register() || prev_output.is_uid_transfer())\n        {\n            if (info.get_status() == UID_TRANSFERABLE_TYPE)\n            {\n                if (detail_info.get_symbol() == prev_output.get_uid_symbol())\n                {\n                    found_uid_info = true;\n                }\n            }\n        }\n        else if (prev_output.is_ucn())\n        {\n            auto uid_address_in = prev_output.get_script_address();\n            if (detail_info.get_address() == uid_address_in)\n            {\n                found_address_info = true;\n            }\n        }\n    }\n\n    return (found_uid_info && found_address_info && info.get_status() == UID_TRANSFERABLE_TYPE) || (found_address_info && info.get_status() == UID_DETAIL_TYPE);\n}\n\nbool validate_tx_engine::is_uid_match_address_in_orphan_chain(const std::string &uid, const std::string &address) const\n{\n    if (validate_block_ && validate_block_->is_uid_match_address_in_orphan_chain(uid, address))\n    {\n        log::debug(LOG_BLOCKCHAIN) << \"uid_in_orphan_chain: \"\n                                   << uid << \", match address: \" << address;\n        return true;\n    }\n\n    return false;\n}\n\nbool validate_tx_engine::is_uid_in_orphan_chain(const std::string &uid) const\n{\n    if (validate_block_ && validate_block_->is_uid_in_orphan_chain(uid))\n    {\n        log::debug(LOG_BLOCKCHAIN) << \"uid_in_orphan_chain: \" << uid << \" exist\";\n        return true;\n    }\n\n    return false;\n}\n\ncode validate_tx_engine::check_asset_to_uid(const output &output) const\n{\n    auto touid = output.attach_data.get_to_uid();\n    if (touid.empty())\n    {\n        return error::success;\n    }\n\n    auto address = output.get_script_address();\n\n    if (is_uid_match_address_in_orphan_chain(touid, address))\n    {\n        return error::success;\n    }\n\n    uint64_t fork_index = validate_block_ ? validate_block_->get_fork_index() : max_uint64;\n    auto uid = blockchain_.get_uid_from_address(address, fork_index);\n    if (touid == uid)\n    {\n        return error::success;\n    }\n\n    log::debug(LOG_BLOCKCHAIN) << \"check_asset_to_uid: \"\n                               << touid << \", address: \" << address\n                               << \"; get uid from address is \" << uid;\n    return error::uid_address_not_match;\n}\n\ncode validate_tx_engine::connect_asset_from_uid(const output &output) const\n{\n    auto from_uid = output.attach_data.get_from_uid();\n    if (from_uid.empty())\n    {\n        return error::success;\n    }\n\n    for (auto &input : tx_->inputs)\n    {\n        chain::transaction prev_tx;\n        uint64_t prev_height{0};\n        if (!get_previous_tx(prev_tx, prev_height, input))\n        {\n            log::debug(LOG_BLOCKCHAIN) << \"connect_asset_from_uid: input not found: \"\n                                       << encode_hash(input.previous_output.hash);\n            return error::input_not_found;\n        }\n\n        auto prev_output = prev_tx.outputs.at(input.previous_output.index);\n        auto address = prev_output.get_script_address();\n\n        if (is_uid_match_address_in_orphan_chain(from_uid, address))\n        {\n            return error::success;\n        }\n\n        uint64_t fork_index = validate_block_ ? validate_block_->get_fork_index() : max_uint64;\n        if (from_uid == blockchain_.get_uid_from_address(address, fork_index))\n        {\n            return error::success;\n        }\n    }\n\n    log::debug(LOG_BLOCKCHAIN) << \"connect_asset_from_uid: input not found for from_uid: \"\n                               << from_uid;\n    return error::uid_address_not_match;\n}\n\ncode validate_tx_engine::check_transaction_connect_input(size_t last_height)\n{\n    if (last_height == 0 || tx_->is_strict_coinbase())\n    {\n        return error::success;\n    }\n\n    reset(last_height);\n\n    for (const auto &input : tx_->inputs)\n    {\n        chain::transaction prev_tx;\n        uint64_t prev_height{0};\n        if (!get_previous_tx(prev_tx, prev_height, input))\n        {\n            log::debug(LOG_BLOCKCHAIN) << \"check_transaction_connect_input: input not found: \"\n                                       << encode_hash(input.previous_output.hash);\n            return error::input_not_found;\n        }\n        if (!connect_input(prev_tx, prev_height))\n        {\n            log::debug(LOG_BLOCKCHAIN) << \"connect_input failed. prev height:\"\n                                       << std::to_string(prev_height)\n                                       << \", prev hash: \" << encode_hash(prev_tx.hash());\n            return error::validate_inputs_failed;\n        }\n        ++current_input_;\n    }\n\n    return check_tx_connect_input();\n}\n\ncode validate_tx_engine::check_transaction() const\n{\n    code ret = error::success;\n\n    if ((ret = check_transaction_basic()) != error::success)\n    {\n        return ret;\n    }\n\n    if ((ret = check_token_issue_transaction()) != error::success)\n    {\n        return ret;\n    }\n\n    if (tx_->version >= transaction_version::check_uid_feature)\n    {\n        if ((ret = check_token_cert_transaction()) != error::success)\n        {\n            return ret;\n        }\n\n        if ((ret = check_secondaryissue_transaction()) != error::success)\n        {\n            return ret;\n        }\n\n        if ((ret = check_candidate_transaction()) != error::success)\n        {\n            return ret;\n        }\n\n        if ((ret = check_uid_transaction()) != error::success)\n        {\n            return ret;\n        }\n\n        if ((ret = attenuation_model::check_model_param(*this)) != error::success)\n        {\n            return ret;\n        }\n    }\n\n    return ret;\n}\n\ncode validate_tx_engine::check_transaction_basic() const\n{\n    const chain::transaction &tx = *tx_;\n    blockchain::block_chain_impl &chain = blockchain_;\n\n    if (tx.version >= transaction_version::max_version)\n    {\n        return error::transaction_version_error;\n    }\n\n    if (tx.version == transaction_version::check_uid_feature && !is_uid_feature_activated(chain))\n    {\n        return error::uid_feature_not_activated;\n    }\n\n    if (tx.version == transaction_version::check_uid_testnet && !chain.chain_settings().use_testnet_rules)\n    {\n        return error::transaction_version_error;\n    }\n\n    if (tx.version >= transaction_version::check_output_script)\n    {\n        for (auto &i : tx.outputs)\n        {\n            if (i.script.pattern() == script_pattern::non_standard)\n            {\n                return error::script_not_standard;\n            }\n        }\n    }\n\n    if (tx.inputs.empty() || tx.outputs.empty())\n        return error::empty_transaction;\n\n    if (tx.serialized_size() > max_transaction_size)\n        return error::size_limits;\n\n    // check double spend in inputs\n    std::set<std::string> set;\n    for (auto &input : tx.inputs)\n    {\n        auto tx_hash = libbitcoin::encode_hash(input.previous_output.hash);\n        auto value = tx_hash + \":\" + std::to_string(input.previous_output.index);\n        if (set.count(value))\n        {\n            return error::double_spend;\n        }\n\n        set.insert(value);\n    }\n\n    // Check for negative or overflow output values\n    uint64_t total_output_value = 0;\n\n    for (const auto &output : tx.outputs)\n    {\n        if (output.value > max_money())\n            return error::output_value_overflow;\n\n        total_output_value += output.value;\n\n        if (total_output_value > max_money())\n            return error::output_value_overflow;\n    }\n\n    for (auto &output : tx.outputs)\n    {\n        if (output.is_token_issue())\n        {\n            if (!chain::output::is_valid_symbol(output.get_token_symbol(), tx.version))\n            {\n                return error::token_symbol_invalid;\n            }\n        }\n        else if (output.is_token_cert())\n        {\n            if (!chain::output::is_valid_symbol(output.get_token_symbol(), tx.version))\n            {\n                return error::token_symbol_invalid;\n            }\n        }\n        else if (output.is_uid_register())\n        {\n            auto is_test = chain.chain_settings().use_testnet_rules;\n            if (!chain::output::is_valid_uid_symbol(output.get_uid_symbol(), !is_test))\n            {\n                return error::uid_symbol_invalid;\n            }\n        }\n        else if (output.is_candidate_register())\n        {\n            if (!chain::output::is_valid_candidate_symbol(output.get_token_symbol(), true))\n            {\n                return error::candidate_symbol_invalid;\n            }\n        }\n\n        // check asset, from uid version.\n        if ((tx.version >= transaction_version::check_uid_feature) && (!output.attach_data.is_valid()))\n        {\n            log::debug(LOG_BLOCKCHAIN) << \"invalid asset : \"\n                                       << output.attach_data.to_string();\n            return error::asset_invalid;\n        }\n    }\n\n    if (tx.is_coinbase())\n    {\n        const auto &coinbase_script = tx.inputs[0].script;\n        const auto coinbase_size = coinbase_script.serialized_size(false);\n        if (coinbase_size < 2 || coinbase_size > 200)\n            return error::invalid_coinbase_script_size;\n    }\n    else\n    {\n        for (const auto &input : tx.inputs)\n        {\n            if (input.previous_output.is_null())\n                return error::previous_output_null;\n\n            if (chain::operation::is_sign_key_hash_with_lock_height_pattern(input.script.operations))\n            {\n                uint64_t prev_output_blockheight = 0;\n                chain::transaction prev_tx;\n                uint64_t current_blockheight = 0;\n\n                chain.get_last_height(current_blockheight);\n                if (!get_previous_tx(prev_tx, prev_output_blockheight, input))\n                {\n                    log::debug(LOG_BLOCKCHAIN) << \"check_transaction_basic deposit : input not found: \"\n                                               << encode_hash(input.previous_output.hash);\n                    return error::input_not_found;\n                }\n\n                uint64_t lock_height = chain::operation::get_lock_height_from_sign_key_hash_with_lock_height(input.script.operations);\n                if (lock_height > current_blockheight - prev_output_blockheight)\n                {\n                    return error::invalid_input_script_lock_height;\n                }\n            }\n        }\n\n        for (auto &output : tx.outputs)\n        {\n            if (chain::operation::is_pay_key_hash_with_lock_height_pattern(output.script.operations))\n            {\n                uint64_t lock_height = chain::operation::get_lock_height_from_pay_key_hash_with_lock_height(output.script.operations);\n                if ((int)lock_height < 0\n                    /*|| consensus::miner::get_lock_heights_index(lock_height) < 0*/)\n                {\n                    return error::invalid_output_script_lock_height;\n                }\n            }\n        }\n    }\n\n    return error::success;\n}\n\n// Validate script consensus conformance based on flags provided.\nbool validate_tx_engine::check_consensus(const script &prevout_script,\n                                           const transaction &current_tx, size_t input_index, uint32_t flags)\n{\n    BITCOIN_ASSERT(input_index <= max_uint32);\n    BITCOIN_ASSERT(input_index < current_tx.inputs.size());\n    const auto input_index32 = static_cast<uint32_t>(input_index);\n\n#ifdef WITH_CONSENSUS\n    using namespace bc::consensus;\n    const auto previous_output_script = prevout_script.to_data(false);\n    data_chunk current_transaction = current_tx.to_data();\n\n    // Convert native flags to libbitcoin-consensus flags.\n    uint32_t consensus_flags = verify_flags_none;\n\n    if ((flags & script_context::bip16_enabled) != 0)\n        consensus_flags |= verify_flags_p2sh;\n\n    if ((flags & script_context::bip65_enabled) != 0)\n        consensus_flags |= verify_flags_checklocktimeverify;\n\n    if ((flags & script_context::bip66_enabled) != 0)\n        consensus_flags |= verify_flags_dersig;\n\n    if ((flags & script_context::attenuation_enabled) != 0)\n        consensus_flags |= verify_flags_checkattenuationverify;\n\n    const auto result = verify_script(current_transaction.data(),\n                                      current_transaction.size(), previous_output_script.data(),\n                                      previous_output_script.size(), input_index32, consensus_flags);\n\n    const auto valid = (result == verify_result::verify_result_eval_true);\n#else\n    // Copy the const prevout script so it can be run.\n    auto previous_output_script = prevout_script;\n    const auto &current_input_script = current_tx.inputs[input_index].script;\n\n    const auto valid = script::verify(current_input_script,\n                                      previous_output_script, current_tx, input_index32, flags);\n#endif\n\n    if (!valid)\n    {\n        log::warning(LOG_BLOCKCHAIN)\n            << \"Invalid transaction [\"\n            << encode_hash(current_tx.hash()) << \"]\";\n    }\n\n    return valid;\n}\n\nbool validate_tx_engine::connect_input(const transaction &previous_tx, size_t parent_height)\n{\n    const auto &input = tx_->inputs[current_input_];\n    const auto &previous_outpoint = input.previous_output;\n\n    if (previous_outpoint.index >= previous_tx.outputs.size())\n    {\n        log::debug(LOG_BLOCKCHAIN) << \"output point index outof bounds!\";\n        return false;\n    }\n\n    const auto &previous_output = previous_tx.outputs[previous_outpoint.index];\n    const auto output_value = previous_output.value;\n    if (output_value > max_money())\n    {\n        log::debug(LOG_BLOCKCHAIN) << \"output ucn value exceeds max amount!\";\n        return false;\n    }\n\n    token_cert_type token_certs = token_cert_ns::none;\n    uint64_t token_transfer_amount = 0;\n    if (previous_output.is_token())\n    {\n        auto new_symbol_in = previous_output.get_token_symbol();\n        // 1. do token transfer amount check\n        token_transfer_amount = previous_output.get_token_amount();\n\n        // 2. do token symbol check\n        if (!check_same(old_symbol_in_, new_symbol_in))\n        {\n            return false;\n        }\n        // check forbidden symbol\n        if (bc::wallet::symbol::is_forbidden(new_symbol_in))\n        {\n            return false;\n        }\n    }\n    else if (previous_output.is_token_cert())\n    {\n        token_certs = previous_output.get_token_cert_type();\n        if (!check_same(old_cert_symbol_in_, previous_output.get_token_cert_symbol()))\n        {\n            return false;\n        }\n    }\n    else if (previous_output.is_candidate())\n    {\n        if (!check_same(old_symbol_in_, previous_output.get_candidate_symbol()))\n        {\n            return false;\n        }\n    }\n    else if (previous_output.is_uid())\n    {\n        // 1. do uid symbol check\n        if (!check_same(old_symbol_in_, previous_output.get_uid_symbol()))\n        {\n            return false;\n        }\n    }\n\n    /*if (previous_tx.is_coinbase()) {\n        const auto height_difference = last_block_height_ - parent_height;\n        if (height_difference < coinbase_maturity) {\n            return false;\n        }\n    }*/\n\n    if (!check_consensus(previous_output.script, *tx_, current_input_, script_context::all_enabled))\n    {\n        log::debug(LOG_BLOCKCHAIN) << \"check_consensus failed\";\n        return false;\n    }\n\n    value_in_ += output_value;\n\n    //for block token amount +1\n    if (tx_->is_coinbase())\n    {\n        token_amount_in_ += (token_transfer_amount + 1);\n    }\n    else\n    {\n        token_amount_in_ += token_transfer_amount;\n    }\n\n    if (token_certs != token_cert_ns::none)\n    {\n        token_certs_in_.push_back(token_certs);\n    }\n    return value_in_ <= max_money();\n}\n\nbool validate_tx_engine::check_special_fees(bool is_testnet, const chain::transaction &tx, uint64_t fee)\n{\n    // check fee of issue token or register uid\n    auto developer_community_address = bc::get_developer_community_address(is_testnet);\n    std::vector<uint64_t> ucn_vec;\n    uint32_t special_fee_type = 0;\n    std::string to_address;\n    for (auto &output : tx.outputs)\n    {\n        if (output.is_ucn())\n        {\n            if (output.get_script_address() == developer_community_address)\n            {\n                ucn_vec.push_back(output.value);\n            }\n            else\n            {\n                ucn_vec.push_back(0);\n            }\n        }\n        else if (output.is_token_issue())\n        {\n            special_fee_type = 1;\n            to_address = output.get_script_address();\n        }\n        else if (output.is_uid_register() || output.is_candidate_register())\n        {\n            special_fee_type = 2;\n            to_address = output.get_script_address();\n        }\n    }\n\n    // skip transaction to developer community address\n    if (special_fee_type > 0 && to_address != developer_community_address)\n    {\n        uint64_t fee_to_developer = std::accumulate(ucn_vec.begin(), ucn_vec.end(), (uint64_t)0);\n        if (fee_to_developer > 0)\n        {\n            uint64_t total_fee = fee + fee_to_developer;\n            uint32_t percentage_to_miner = (uint32_t)std::ceil((fee * 100.0) / total_fee);\n\n            bool result = false;\n            if (special_fee_type == 1)\n            {\n                result = (total_fee >= bc::min_fee_to_issue_token && percentage_to_miner >= min_fee_percentage_to_miner);\n            }\n            else if (special_fee_type == 2)\n            {\n                result = (total_fee >= bc::min_fee_to_register_uid && percentage_to_miner >= min_fee_percentage_to_miner);\n            }\n\n            if (!result)\n            {\n                log::debug(LOG_BLOCKCHAIN) << \"check fees failed: \"\n                                           << (special_fee_type == 1 ? \"issue token\" : \"register uid\")\n                                           << \", total_fee: \" << std::to_string(total_fee)\n                                           << \", fee_percentage_to_miner: \" << std::to_string(percentage_to_miner);\n                return false;\n            }\n        }\n        else\n        {\n            if (special_fee_type == 1)\n            {\n                if (fee < bc::min_fee_to_issue_token)\n                {\n                    log::debug(LOG_BLOCKCHAIN) << \"check fees failed: fee for issuing token less than \"\n                                               << std::to_string(bc::min_fee_to_issue_token);\n                    return false;\n                }\n            }\n            else if (special_fee_type == 2)\n            {\n                if (fee < bc::min_fee_to_register_uid)\n                {\n                    log::debug(LOG_BLOCKCHAIN) << \"check fees failed: fee for registerring uid less than \"\n                                               << std::to_string(bc::min_fee_to_register_uid);\n                    return false;\n                }\n            }\n        }\n    }\n\n    return true;\n}\n\nbool validate_tx_engine::tally_fees(blockchain::block_chain_impl &chain,\n                                      const transaction &tx, uint64_t value_in, uint64_t &total_fees)\n{\n    const auto value_out = tx.total_output_value();\n\n    if (tx.is_coinbase() && value_in == 0)\n    {\n        return true;\n    }\n    else\n    {\n        if (value_in < value_out)\n            return false;\n\n        const auto fee = value_in - value_out;\n\n        if (fee < min_tx_fee)\n        {\n            return false;\n        }\n\n        total_fees += fee;\n    }\n\n    return total_fees <= max_money();\n}\n\nbool validate_tx_engine::check_token_amount(const transaction &tx) const\n{\n    const auto token_amount_out = tx.total_output_transfer_amount();\n    if (token_amount_in_ != token_amount_out) // token amount must be equal\n        return false;\n\n    return true;\n}\n\nbool validate_tx_engine::check_token_symbol(const transaction &tx) const\n{\n    for (const auto &output : tx.outputs)\n    {\n        if (output.is_token())\n        {\n            if (old_symbol_in_ != output.get_token_symbol() && !output.is_vote())\n            {\n                return false;\n            }\n        }\n        else if (output.is_token_cert())\n        { // token cert related\n            continue;\n        }\n        else if (!output.is_ucn() && !output.is_message())\n        {\n            // token tx only related to token_cert and ucn output\n            return false;\n        }\n    }\n    return true;\n}\n\nbool validate_tx_engine::check_token_certs(const transaction &tx) const\n{\n    bool is_cert_transfer = false;\n    bool is_cert_issue = false;\n    bool has_cert_autoissue = false;\n    bool has_token_issue = false;\n    bool has_token_output = false;\n    std::vector<token_cert_type> token_certs_out;\n    for (auto &output : tx.outputs)\n    {\n        if (output.is_token_cert())\n        {\n            auto &&token_cert = output.get_token_cert();\n            auto cert_type = token_cert.get_type();\n\n            if (token_cert.get_status() == TOKEN_CERT_TRANSFER_TYPE)\n            {\n                is_cert_transfer = true;\n            }\n            else if (token_cert.get_status() == TOKEN_CERT_ISSUE_TYPE)\n            {\n                is_cert_issue = true;\n            }\n            else if (token_cert.get_status() == TOKEN_CERT_AUTOISSUE_TYPE)\n            {\n                has_cert_autoissue = true;\n            }\n\n            if (token_cert::test_certs(token_certs_out, cert_type))\n            { // double certs exists\n                return false;\n            }\n\n            // check token cert symbol\n            if (token_cert::test_certs(token_certs_in_, token_cert_ns::domain) && (cert_type == token_cert_ns::naming))\n            {\n                auto &&domain = token_cert::get_domain(token_cert.get_symbol());\n                if (domain != old_cert_symbol_in_)\n                {\n                    log::debug(LOG_BLOCKCHAIN) << \"cert domain error: \"\n                                               << \"symbol : \" << token_cert.get_symbol() << \"; \"\n                                               << old_cert_symbol_in_ << \" != \" << domain;\n                    return false;\n                }\n            }\n            else if (!token_cert.is_newly_generated())\n            {\n                if (old_cert_symbol_in_ != token_cert.get_symbol())\n                {\n                    log::debug(LOG_BLOCKCHAIN) << \"cert symbol error: \"\n                                               << old_cert_symbol_in_ << \" != \" << token_cert.get_symbol();\n                    return false;\n                }\n            }\n\n            if (!token_cert.is_newly_generated())\n            {\n                if (!token_cert::test_certs(token_certs_in_, cert_type))\n                {\n                    log::debug(LOG_BLOCKCHAIN) << \"input lack of cert: \" << token_cert.get_type_name();\n                    return false;\n                }\n            }\n\n            token_certs_out.push_back(cert_type);\n        }\n        else if (output.is_token())\n        { // token related\n            has_token_output = true;\n            if (output.is_token_issue())\n            {\n                has_token_issue = true;\n            }\n        }\n        else if (!output.is_ucn() && !output.is_message())\n        {\n            // token cert transfer tx only related to token_cert and ucn output\n            log::debug(LOG_BLOCKCHAIN) << \"cert tx mix other illegal output\";\n            return false;\n        }\n    }\n\n    if ((is_cert_issue || is_cert_transfer) && has_token_output)\n    {\n        log::debug(LOG_BLOCKCHAIN) << \"issue/transfer cert can not mix with token output\";\n        return false;\n    }\n\n    if (has_cert_autoissue && !has_token_issue)\n    {\n        log::debug(LOG_BLOCKCHAIN) << \"only issue command can has cert with autoissue status\";\n        return false;\n    }\n\n    if (is_cert_transfer)\n    {\n        if (token_certs_in_.size() != 1)\n        {\n            log::debug(LOG_BLOCKCHAIN) << \"transfer cert: invalid number of cert in inputs: \"\n                                       << token_certs_in_.size();\n            return false;\n        }\n        if (token_certs_out.size() != 1)\n        {\n            log::debug(LOG_BLOCKCHAIN) << \"transfer cert: invalid number of cert in outputs: \"\n                                       << token_certs_out.size();\n            return false;\n        }\n    }\n\n    if (!token_cert::test_certs(token_certs_out, token_certs_in_))\n    {\n        log::debug(LOG_BLOCKCHAIN) << \"some inputed certs is missed in outputs\";\n        return false;\n    }\n    return true;\n}\n\nbool validate_tx_engine::check_candidate(const transaction &tx) const\n{\n    size_t num_candidate = 0;\n    for (const auto &output : tx.outputs)\n    {\n        if (output.is_candidate_transfer())\n        {\n            if (++num_candidate > 1)\n            {\n                return false;\n            }\n\n            auto &&token_info = output.get_candidate();\n            if (old_symbol_in_ != token_info.get_symbol())\n            {\n                return false;\n            }\n        }\n        else if (!output.is_ucn() && !output.is_message())\n        {\n            return false;\n        }\n    }\n\n    return (num_candidate == 1);\n}\n\nbool validate_tx_engine::check_uid_symbol_match(const transaction &tx) const\n{\n    for (const auto &output : tx.outputs)\n    {\n        if (output.is_uid())\n        {\n            if (old_symbol_in_ != output.get_uid_symbol())\n            {\n                return false;\n            }\n        }\n        else if (!output.is_ucn() && !output.is_message())\n        {\n            return false;\n        }\n    }\n    return true;\n}\n\nbool validate_tx_engine::is_uid_feature_activated(blockchain::block_chain_impl &chain)\n{\n    /*if (chain.chain_settings().use_testnet_rules) {\n        return true;\n    }\n\n    uint64_t current_blockheight = 0;\n    chain.get_last_height(current_blockheight);\n\n    // active SuperNove on 2018-06-18 (duanwu festival)\n    return (current_blockheight > 1270000);*/\n    return true;\n}\n\n} // namespace blockchain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/blockchain/wallet_security_strategy.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/blockchain/wallet_security_strategy.hpp>\n#include <chrono>\n\nnamespace libbitcoin\n{\nnamespace blockchain\n{\nwallet_security_strategy *wallet_security_strategy::instance = nullptr;\n\nvoid WalletInfo::lock()\n{\n    counter = 0;\n    const uint32_t now = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();\n    lock_start = now;\n}\n\nwallet_security_strategy::wallet_security_strategy(const uint8_t &passwd_max_try, const uint8_t &lastwd_max_try, const uint32_t &max_lock_time) : MAX_TRY{passwd_max_try, lastwd_max_try},\n                                                                                                                                                  MAX_LOCK_TIME(max_lock_time)\n{\n}\n\nwallet_security_strategy::~wallet_security_strategy()\n{\n}\n\nwallet_security_strategy *wallet_security_strategy::get_instance()\n{\n    if (instance == nullptr)\n    {\n        instance = new wallet_security_strategy(10, 8, 30 * 60); // 10 times for password, 8 times for lastword, and 30 minutes for lock period\n    }\n\n    return instance;\n}\n\nvoid wallet_security_strategy::check_locked(const std::string &wallet_name)\n{\n    unique_lock lock(mutex_);\n    for (auto &acc : acc_info_)\n    {\n        auto iter = acc.find(wallet_name);\n        if (iter == acc.end())\n        {\n            continue;\n        }\n        if (iter->second.lock_start == 0)\n        {\n            continue;\n        }\n\n        const uint32_t now = std::chrono::duration_cast<std::chrono::seconds>(\n                                 std::chrono::system_clock::now().time_since_epoch())\n                                 .count();\n\n        if (iter->second.lock_start + MAX_LOCK_TIME > now)\n        {\n            throw std::logic_error{\"wallet locked, retry 30 minutes later.\"};\n        }\n\n        acc.erase(iter);\n    }\n}\n\nvoid wallet_security_strategy::on_auth_passwd(const std::string &wallet_name, const bool &result)\n{\n    on_auth(wallet_name, result, auth_type::AUTH_PASSWD);\n}\n\nvoid wallet_security_strategy::on_auth_lastwd(const std::string &wallet_name, const bool &result)\n{\n    on_auth(wallet_name, result, auth_type::AUTH_LASTWD);\n}\n\nvoid wallet_security_strategy::on_auth(const std::string &wallet_name, const bool &result, const auth_type &type)\n{\n    unique_lock lock(mutex_);\n\n    auto &acc = acc_info_[static_cast<uint8_t>(type)];\n\n    if (result)\n    {\n        //auth success\n        auto iter = acc.find(wallet_name);\n        if (iter == acc.end())\n        {\n            return;\n        }\n\n        acc.erase(iter);\n    }\n    else\n    {\n        //auth fail\n        auto iter = acc.find(wallet_name);\n        if (iter == acc.end())\n        {\n            acc[wallet_name] = WalletInfo{1, 0};\n        }\n        else\n        {\n            if (++(iter->second.counter) >= MAX_TRY[static_cast<uint8_t>(type)])\n            {\n                iter->second.lock();\n            }\n        }\n    }\n}\n\n} // namespace blockchain\n} // namespace libbitcoin"
  },
  {
    "path": "src/UChain/client/CMakeLists.txt",
    "content": "FILE(GLOB_RECURSE client_SOURCES \"*.cpp\")\n\nADD_DEFINITIONS(-DBCC_STATIC=1)\n\nSET(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} -fno-strict-aliasing\")\n\nADD_LIBRARY(client_static STATIC ${client_SOURCES})\nSET_TARGET_PROPERTIES(client_static PROPERTIES OUTPUT_NAME uc_client)\nTARGET_LINK_LIBRARIES(client_static ${Boost_LIBRARIES} ${txs_LIBRARY} ${bitcoin_LIBRARY} ${protocol_LIBRARY})\nINSTALL(TARGETS client_static DESTINATION lib)\n\nIF(ENABLE_SHARED_LIBS)\n    #    ADD_DEFINITIONS(-DBCD_DLL=1)\n  ADD_LIBRARY(client_shared SHARED ${client_SOURCES})\n  SET_TARGET_PROPERTIES(client_shared PROPERTIES OUTPUT_NAME uc_client)\n  TARGET_LINK_LIBRARIES(client_shared ${Boost_LIBRARIES} ${txs_LIBRARY} ${bitcoin_LIBRARY} ${protocol_LIBRARY})\n  INSTALL(TARGETS client_shared DESTINATION lib)\nENDIF()\n"
  },
  {
    "path": "src/UChain/client/dealer.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-client.\n *\n * UChain-client is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/client/dealer.hpp>\n\n#include <algorithm>\n#include <chrono>\n#include <cstdint>\n#include <string>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/client/stream.hpp>\n\n// A REQ socket always adds a delimiter.\n// Server v1/v2 expect no delimiter and therefore will fail REQ clients.\n// A delimiter frame is optional for a DEALER socket (v1/v2/v3 clients).\n// In v3 we don't add the delimiter but the v3 server allows it.\n// By v4 client we can always send the delimiter (expecting v3+ server).\n#undef USE_ADDRESS_DELIMITER\n\nnamespace libbitcoin\n{\nnamespace client\n{\n\nusing namespace bc::chain;\nusing namespace bc::wallet;\n\ntypedef boost::iostreams::stream<byte_source<data_chunk>> byte_stream;\n\nstatic const auto on_update_nop = [](const payment_address &, size_t,\n                                     const hash_digest &, const transaction &) {\n};\n\nstatic const auto on_stealth_update_nop = [](const binary &, size_t,\n                                             const hash_digest &, const transaction &) {\n};\n\nstatic int32_t unsigned_to_signed(uint32_t value)\n{\n    const auto maximum_unsigned = static_cast<uint32_t>(max_int32);\n    const auto capped_signed = std::min(value, maximum_unsigned);\n    return static_cast<int32_t>(capped_signed);\n}\n\ndealer::dealer(stream &out, unknown_handler on_unknown_command,\n               uint32_t timeout_milliseconds, uint8_t resends)\n    : last_request_index_(0),\n      resends_(resends),\n      timeout_milliseconds_(unsigned_to_signed(timeout_milliseconds)),\n      on_unknown_(on_unknown_command),\n      on_update_(on_update_nop),\n      on_stealth_update_(on_stealth_update_nop),\n      out_(out)\n{\n}\n\ndealer::~dealer()\n{\n    clear(error::channel_timeout);\n}\n\nbool dealer::empty() const\n{\n    return pending_.empty();\n}\n\nvoid dealer::clear(const code &code)\n{\n    for (const auto &request : pending_)\n        request.second.on_error(code);\n\n    pending_.clear();\n}\n\nvoid dealer::set_on_update(update_handler on_update)\n{\n    on_update_ = on_update;\n}\n\nvoid dealer::set_on_stealth_update(stealth_update_handler on_update)\n{\n    on_stealth_update_ = on_update;\n}\n\n// Send, kill or ignore pending messages as necessary.\n// Return maximum time before next required refresh in milliseconds.\n// Subscriptions notification handlers are not registered in pending.\nint32_t dealer::refresh()\n{\n    auto interval = timeout_milliseconds_;\n\n    // Use explicit iteration to allow for erase in loop.\n    auto request = pending_.begin();\n    while (request != pending_.end())\n    {\n        const auto milliseconds_remain = remaining(request->second.deadline);\n\n        if (milliseconds_remain > 0)\n        {\n            // Not timed out, go to sleep for no more than remaining time.\n            interval = milliseconds_remain;\n            ++request;\n        }\n        else if (request->second.resends < resends_)\n        {\n            // Resend is helpful in the case where the server is overloaded.\n            // A zmq router drops messages as it reaches the high water mark.\n            request->second.resends++;\n            request->second.deadline = asio::steady_clock::now() +\n                                       asio::milliseconds(timeout_milliseconds_);\n\n            // Timed out and not done, go to sleep for no more than timeout.\n            interval = std::min(interval, timeout_milliseconds_);\n\n            // Resend the request message due to response timeout.\n            send(request->second.message);\n            ++request;\n        }\n        else\n        {\n            // Timed out and exceeded retries, handle error and dequeue.\n            request->second.on_error(error::channel_timeout);\n            request = pending_.erase(request);\n        }\n    }\n\n    // We emit as int32 because of poller.wait.\n    return interval;\n}\n\n// Return time to deadline in milliseconds.\nint32_t dealer::remaining(const asio::time_point &deadline)\n{\n    // Convert bounds to the larger type of the conversion.\n    static constexpr auto maximum = static_cast<int64_t>(max_int32);\n    static constexpr auto minimum = static_cast<int64_t>(min_int32);\n\n    // Get the remaining time in milliseconds (may be negative).\n    const auto remainder = deadline - asio::steady_clock::now();\n    const auto count = std::chrono::duration_cast<asio::milliseconds>(\n                           remainder)\n                           .count();\n\n    // Prevent overflow and underflow in the conversion to int32.\n    const auto capped = std::min(count, maximum);\n    const auto bounded = std::max(capped, minimum);\n    return static_cast<int32_t>(bounded);\n}\n\n// Create a message with identity and send it via the message stream.\n// This is invoked by derived class message senders, such as the proxy.\nbool dealer::send_request(const std::string &command,\n                          const data_chunk &payload, error_handler on_error, decoder on_reply)\n{\n    const auto now = asio::steady_clock::now();\n    const auto id = ++last_request_index_;\n    auto &request = pending_[id];\n    request.message = obelisk_message{command, id, payload};\n    request.on_error = on_error;\n    request.on_reply = on_reply;\n    request.resends = 0;\n    request.deadline = now + asio::milliseconds(timeout_milliseconds_);\n    return send(request.message);\n}\n\n// Send or resend an existing message by writing it to the message stream.\nbool dealer::send(const obelisk_message &message)\n{\n    data_stack data;\n\n#ifdef USE_ADDRESS_DELIMITER\n    data.push_back({});\n#endif\n\n    data.push_back(to_chunk(message.command));\n    data.push_back(to_chunk(to_little_endian(message.id)));\n    data.push_back(message.payload);\n\n    // This creates a message and sends it on the socket.\n    return out_.write(data);\n}\n\n// Stream interface, not utilized on this class.\nbool dealer::read(stream &stream)\n{\n    return false;\n}\n\n// stream interface.\nbool dealer::write(const data_stack &data)\n{\n    if (data.size() < 3 || data.size() > 4)\n        return false;\n\n    obelisk_message message;\n    auto it = data.begin();\n\n    // See note in send().\n    // Forward compatibility with a future server would send the delimiter.\n    // Strip the delimiter if the server includes it.\n    if (data.size() == 4)\n        ++it;\n\n    // Copy the first token into command.\n    message.command = std::string(it->begin(), it->end());\n\n    // Require the second token is 4 bytes.\n    if ((++it)->size() == sizeof(uint32_t))\n    {\n        // Copy the second token into id.\n        message.id = from_little_endian_unsafe<uint32_t>(it->begin());\n\n        // Copy the third token into id.\n        message.payload = *(++it);\n    }\n\n    return receive(message);\n}\n\n// Handle a message, call from write.\nbool dealer::receive(const obelisk_message &message)\n{\n    // Subscription updates are not tracked in pending.\n    if (message.command == \"address.update\")\n    {\n        decode_payment_update(message);\n        return true;\n    }\n\n    // Subscription updates are not tracked in pending.\n    if (message.command == \"address.stealth_update\")\n    {\n        decode_stealth_update(message);\n        return true;\n    }\n\n    const auto command = pending_.find(message.id);\n    if (command == pending_.end())\n    {\n        on_unknown_(message.command);\n        return false;\n    }\n\n    decode_reply(message, command->second.on_error, command->second.on_reply);\n    pending_.erase(command);\n    return true;\n}\n\nvoid dealer::decode_reply(const obelisk_message &message,\n                          error_handler &on_error, decoder &on_reply)\n{\n    byte_stream istream(message.payload);\n    istream_reader source(istream);\n    code ec = static_cast<error::error_code_t>(\n        source.read_4_bytes_little_endian());\n\n    if (ec)\n        on_error(ec);\n    else if (!on_reply(source))\n        on_error(error::bad_stream);\n}\n\nvoid dealer::decode_payment_update(const obelisk_message &message)\n{\n    byte_stream istream(message.payload);\n    istream_reader source(istream);\n\n    // This message does not have an error_code at the beginning.\n    const auto version_byte = source.read_byte();\n    const auto address_hash = source.read_short_hash();\n    const payment_address address(address_hash, version_byte);\n    const auto height = source.read_4_bytes_little_endian();\n    const auto block_hash = source.read_hash();\n    transaction tx;\n\n    if (!tx.from_data(source) || !source.is_exhausted())\n    {\n        // This is incorrect, we need an error handler member.\n        on_unknown_(message.command);\n        return;\n    }\n\n    on_update_(address, height, block_hash, tx);\n}\n\nvoid dealer::decode_stealth_update(const obelisk_message &message)\n{\n    byte_stream istream(message.payload);\n    istream_reader source(istream);\n\n    // This message does not have an error_code at the beginning.\n    static constexpr size_t prefix_size = sizeof(uint32_t);\n    binary prefix(prefix_size * byte_bits, source.read_bytes<prefix_size>());\n    const auto height = source.read_4_bytes_little_endian();\n    const auto block_hash = source.read_hash();\n    transaction tx;\n\n    if (!tx.from_data(source) || !source.is_exhausted())\n    {\n        // This is incorrect, we need an error handler member.\n        on_unknown_(message.command);\n        return;\n    }\n\n    on_stealth_update_(prefix, height, block_hash, tx);\n}\n\n} // namespace client\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/client/obelisk_client.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain-client.\n *\n * UChain-client is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/client/obelisk_client.hpp>\n\n#include <algorithm>\n#include <cstdint>\n#include <thread>\n#include <UChain/protocol.hpp>\n\nusing namespace bc;\nusing namespace bc::config;\nusing namespace bc::protocol;\nusing namespace std::this_thread;\n\nnamespace libbitcoin\n{\nnamespace client\n{\n\nstatic uint32_t to_milliseconds(uint16_t seconds)\n{\n    const auto milliseconds = static_cast<uint32_t>(seconds) * 1000;\n    return std::min(milliseconds, max_uint32);\n};\n\nstatic const auto on_unknown = [](const std::string &) {};\n\n// Retries is overloaded as configuration for resends as well.\n// Timeout is capped at ~ 25 days by signed/millsecond conversions.\nobelisk_client::obelisk_client(uint16_t timeout_seconds, uint8_t retries)\n    : socket_(context_, zmq::socket::role::dealer),\n      stream_(socket_),\n      retries_(retries),\n      proxy(stream_, on_unknown, to_milliseconds(timeout_seconds), retries)\n{\n}\n\nobelisk_client::obelisk_client(const connection_type &channel)\n    : obelisk_client(channel.timeout_seconds, channel.retries)\n{\n}\n\nbool obelisk_client::connect(const connection_type &channel)\n{\n    return connect(channel.server, channel.server_public_key,\n                   channel.client_private_key);\n}\n\nbool obelisk_client::connect(const endpoint &address)\n{\n    const auto host_address = address.to_string();\n\n    for (auto attempt = 0; attempt < 1 + retries_; ++attempt)\n    {\n        if (socket_.connect(host_address) == (code)error::success)\n            return true;\n\n        // Arbitrary delay between connection attempts.\n        sleep_for(asio::milliseconds(100));\n    }\n\n    return false;\n}\n\nbool obelisk_client::connect(const endpoint &address,\n                             const sodium &server_public_key, const sodium &client_private_key)\n{\n    // Only apply the client (and server) key if server key is configured.\n    if (server_public_key)\n    {\n        if (!socket_.set_curve_client(server_public_key))\n            return false;\n\n        // Generates arbitrary client keys if private key is not configured.\n        if (!socket_.set_certificate({client_private_key}))\n            return false;\n    }\n\n    return connect(address);\n}\n\n// Used by fetch-* commands, fires reply, unknown or error handlers.\nvoid obelisk_client::wait()\n{\n    zmq::poller poller;\n    poller.add(socket_);\n    auto delay = refresh();\n\n    while (!empty() && poller.wait(delay).contains(socket_.id()))\n    {\n        stream_.read(*this);\n        delay = refresh();\n    }\n\n    // Invoke error handlers for any still pending.\n    clear(error::channel_timeout);\n}\n\n// Used by watch-* commands, fires registered update or unknown handlers.\nvoid obelisk_client::monitor(uint32_t timeout_seconds)\n{\n    const auto deadline = asio::steady_clock::now() +\n                          asio::seconds(timeout_seconds);\n\n    zmq::poller poller;\n    poller.add(socket_);\n    auto delay = remaining(deadline);\n\n    while (poller.wait(delay).contains(socket_.id()))\n    {\n        stream_.read(*this);\n        delay = remaining(deadline);\n    }\n}\n\n} // namespace client\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/client/proxy.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-client.\n *\n * UChain-client is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/client/proxy.hpp>\n\n#include <unordered_map>\n#include <cstdint>\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/client/dealer.hpp>\n#include <UChain/client/define.hpp>\n#include <UChain/client/stream.hpp>\n\nnamespace libbitcoin\n{\nnamespace client\n{\n\nusing std::placeholders::_1;\nusing namespace bc::chain;\nusing namespace bc::wallet;\n\nproxy::proxy(stream &out, unknown_handler on_unknown_command,\n             uint32_t timeout_milliseconds, uint8_t resends)\n    : dealer(out, on_unknown_command, timeout_milliseconds, resends)\n{\n}\n\n// Fetchers.\n//-----------------------------------------------------------------------------\n\nvoid proxy::protocol_broadcast_transaction(error_handler on_error,\n                                           empty_handler on_reply, const chain::transaction &tx)\n{\n    send_request(\"protocol.broadcast_transaction\", tx.to_data(),\n                 on_error,\n                 std::bind(decode_empty,\n                           _1, on_reply));\n}\n\nvoid proxy::tx_pool_validate(error_handler on_error,\n                                      validate_handler on_reply, const chain::transaction &tx)\n{\n    send_request(\"tx_pool.validate\", tx.to_data(),\n                 on_error,\n                 std::bind(decode_validate,\n                           _1, on_reply));\n}\n\nvoid proxy::tx_pool_fetch_transaction(error_handler on_error,\n                                               transaction_handler on_reply, const hash_digest &tx_hash)\n{\n    const auto data = build_chunk({tx_hash});\n\n    send_request(\"tx_pool.fetch_transaction\", data,\n                 on_error,\n                 std::bind(decode_transaction,\n                           _1, on_reply));\n}\n\nvoid proxy::blockchain_fetch_transaction(error_handler on_error,\n                                         transaction_handler on_reply, const hash_digest &tx_hash)\n{\n    const auto data = build_chunk({tx_hash});\n\n    send_request(\"blockchain.fetch_transaction\", data, on_error,\n                 std::bind(decode_transaction,\n                           _1, on_reply));\n}\n\nvoid proxy::blockchain_fetch_last_height(error_handler on_error,\n                                         height_handler on_reply)\n{\n    const data_chunk data;\n\n    send_request(\"blockchain.fetch_last_height\", data, on_error,\n                 std::bind(decode_height,\n                           _1, on_reply));\n}\n\nvoid proxy::blockchain_fetch_block_header(error_handler on_error,\n                                          block_header_handler on_reply, uint32_t height)\n{\n    const auto data = build_chunk({to_little_endian<uint32_t>(height)});\n\n    send_request(\"blockchain.fetch_block_header\", data, on_error,\n                 std::bind(decode_block_header,\n                           _1, on_reply));\n}\n\nvoid proxy::blockchain_fetch_block_headers(error_handler on_error,\n                                           block_headers_handler on_reply, uint32_t start, uint32_t end, bool order)\n{\n    const auto data = build_chunk({to_little_endian<uint32_t>(start),\n                                   to_little_endian<uint32_t>(end),\n                                   to_little_endian<bool>(order)});\n\n    send_request(\"blockchain.fetch_block_header\", data, on_error,\n                 std::bind(decode_block_headers,\n                           _1, on_reply));\n}\n\nvoid proxy::blockchain_fetch_block_header(error_handler on_error,\n                                          block_header_handler on_reply, const hash_digest &block_hash)\n{\n    const auto data = build_chunk({block_hash});\n\n    send_request(\"blockchain.fetch_block_header\", data, on_error,\n                 std::bind(decode_block_header,\n                           _1, on_reply));\n}\n\nvoid proxy::blockchain_fetch_transaction_index(error_handler on_error,\n                                               transaction_index_handler on_reply, const hash_digest &tx_hash)\n{\n    const auto data = build_chunk({tx_hash});\n\n    send_request(\"blockchain.fetch_transaction_index\", data,\n                 on_error,\n                 std::bind(decode_transaction_index,\n                           _1, on_reply));\n}\n\nvoid proxy::blockchain_fetch_stealth(error_handler on_error,\n                                     stealth_handler on_reply, const binary &prefix, uint32_t from_height)\n{\n    if (prefix.size() > max_uint8)\n    {\n        on_error(error::bad_stream);\n        return;\n    }\n\n    const auto data = build_chunk(\n        {to_array(static_cast<uint8_t>(prefix.size())),\n         prefix.blocks(),\n         to_little_endian<uint32_t>(from_height)});\n\n    send_request(\"blockchain.fetch_stealth\", data, on_error,\n                 std::bind(decode_stealth,\n                           _1, on_reply));\n}\n\n// Address hash reversal is an idiosyncracy of the original Obelisk protocol.\nvoid proxy::blockchain_fetch_history(error_handler on_error,\n                                     history_handler on_reply, const payment_address &address,\n                                     uint32_t from_height)\n{\n    auto hash = address.hash();\n    std::reverse(hash.begin(), hash.end());\n    const auto data = build_chunk(\n        {to_array(address.version()),\n         hash,\n         to_little_endian<uint32_t>(from_height)});\n\n    send_request(\"blockchain.fetch_history\", data, on_error,\n                 std::bind(decode_history,\n                           _1, on_reply));\n}\n\n// Address hash reversal is an idiosyncracy of the original Obelisk protocol.\n// address.fetch_history is obsoleted in bs 3.0 (use address.fetch_history2).\nvoid proxy::address_fetch_history(error_handler on_error,\n                                  history_handler on_reply, const payment_address &address,\n                                  uint32_t from_height)\n{\n    auto hash = address.hash();\n    std::reverse(hash.begin(), hash.end());\n    const auto data = build_chunk(\n        {to_array(address.version()),\n         hash,\n         to_little_endian<uint32_t>(from_height)});\n\n    // address.fetch_history is first available in sx and deprecated in bs 2.0.\n    send_request(\"address.fetch_history\", data, on_error,\n                 std::bind(decode_expanded_history,\n                           _1, on_reply));\n}\n\n// The difference between fetch_history and fetch_history2 is hash reversal.\nvoid proxy::address_fetch_history2(error_handler on_error,\n                                   history_handler on_reply, const payment_address &address,\n                                   uint32_t from_height)\n{\n    const auto data = build_chunk(\n        {to_array(address.version()),\n         address.hash(),\n         to_little_endian<uint32_t>(from_height)});\n\n    // address.fetch_history2 is first available in bs 3.0.\n    send_request(\"address.fetch_history2\", data, on_error,\n                 std::bind(decode_history,\n                           _1, on_reply));\n}\n\nvoid proxy::address_fetch_unspent_outputs(error_handler on_error,\n                                          points_info_handler on_reply, const bc::wallet::payment_address &address,\n                                          const uint64_t satoshi, const bc::wallet::select_outputs::algorithm algorithm)\n{\n    static constexpr uint32_t from_height = 0;\n\n    const auto data = build_chunk(\n        {to_array(address.version()),\n         address.hash(),\n         to_little_endian<uint32_t>(from_height)});\n\n    history_handler parse_history = [on_reply, satoshi, algorithm](\n                                        const chain::history::list &rows) {\n        chain::output_info::list unspent;\n        for (auto &row : rows)\n            if (row.spend.hash == null_hash)\n                unspent.push_back({row.output, row.value});\n\n        chain::points_info selected_utxos;\n        bc::wallet::select_outputs::select(selected_utxos, unspent, satoshi,\n                                           algorithm);\n\n        on_reply(selected_utxos);\n    };\n\n    send_request(\"address.fetch_history2\", data, on_error,\n                 std::bind(decode_history,\n                           _1, std::move(parse_history)));\n}\n\n// Subscribers.\n//-----------------------------------------------------------------------------\n\n// Ths is a simplified overload for a non-private payment address subscription.\nvoid proxy::address_subscribe(error_handler on_error, empty_handler on_reply,\n                              const payment_address &address)\n{\n    // 20 * 8 = 160 bits.\n    binary prefix(short_hash_size * byte_bits, address.hash());\n\n    // [ type:1 ] (0 = address prefix, 1 = stealth prefix)\n    // [ prefix_bitsize:1 ]\n    // [ prefix_blocks:...  ]\n    const auto data = build_chunk(\n        {to_array(static_cast<uint8_t>(subscribe_type::payment)),\n         to_array(static_cast<uint8_t>(prefix.size())),\n         prefix.blocks()});\n\n    send_request(\"address.subscribe\", data, on_error,\n                 std::bind(decode_empty,\n                           _1, on_reply));\n}\n\n// Ths overload supports only a prefix for either stealth or payment address.\nvoid proxy::address_subscribe(error_handler on_error, empty_handler on_reply,\n                              subscribe_type type, const binary &prefix)\n{\n    static constexpr auto address_bits = short_hash_size * byte_bits;\n    static constexpr auto stealth_bits = sizeof(uint32_t) * byte_bits;\n\n    const auto bit_length = prefix.size();\n\n    if ((type == subscribe_type::payment && bit_length > address_bits) ||\n        (type == subscribe_type::stealth && bit_length > stealth_bits))\n    {\n        on_error(error::bad_stream);\n        return;\n    }\n\n    const auto data = build_chunk(\n        {to_array(static_cast<uint8_t>(type)),\n         to_array(static_cast<uint8_t>(bit_length)),\n         prefix.blocks()});\n\n    send_request(\"address.subscribe\", data, on_error,\n                 std::bind(decode_empty,\n                           _1, on_reply));\n}\n\n// Response handlers.\n//-----------------------------------------------------------------------------\n\nbool proxy::decode_empty(reader &payload, empty_handler &handler)\n{\n    if (!payload.is_exhausted())\n        return false;\n\n    handler();\n    return true;\n}\n\nbool proxy::decode_transaction(reader &payload, transaction_handler &handler)\n{\n    transaction tx;\n    if (!tx.from_data(payload) || !payload.is_exhausted())\n        return false;\n\n    handler(tx);\n    return true;\n}\n\nbool proxy::decode_height(reader &payload, height_handler &handler)\n{\n    const auto last_height = payload.read_4_bytes_little_endian();\n    if (!payload.is_exhausted())\n        return false;\n\n    handler(last_height);\n    return true;\n}\n\nbool proxy::decode_block_header(reader &payload, block_header_handler &handler)\n{\n    chain::header header;\n    if (!header.from_data(payload) || !payload.is_exhausted())\n        return false;\n\n    handler(header);\n    return true;\n}\n\nbool proxy::decode_block_headers(reader &payload, block_headers_handler &handler)\n{\n    chain::header header;\n    std::vector<chain::header> headers;\n    while (!payload.is_exhausted())\n    {\n        if (header.from_data(payload))\n            headers.push_back(header);\n        else\n            return false;\n    }\n    handler(headers);\n    return true;\n}\n\nbool proxy::decode_transaction_index(reader &payload,\n                                     transaction_index_handler &handler)\n{\n    const auto block_height = payload.read_4_bytes_little_endian();\n    const auto index = payload.read_4_bytes_little_endian();\n    if (!payload.is_exhausted())\n        return false;\n\n    handler(block_height, index);\n    return true;\n}\n\nbool proxy::decode_validate(reader &payload, validate_handler &handler)\n{\n    point::indexes unconfirmed;\n\n    while (!payload.is_exhausted())\n    {\n        unconfirmed.push_back(payload.read_4_bytes_little_endian());\n        if (!payload)\n            return false;\n    }\n\n    handler(unconfirmed);\n    return true;\n}\n\n// Address hash reversal is an idiosyncracy of the original Obelisk protocol.\nstealth::list proxy::expand(stealth_compact::list &compact)\n{\n    // The sign byte of the ephmemeral key is fixed (0x02) by convention.\n    static const auto sign = to_array(ephemeral_public_key_sign);\n\n    stealth::list result;\n\n    for (const auto &in : compact)\n    {\n        stealth out;\n        out.ephemeral_public_key = splice(sign, in.ephemeral_public_key_hash);\n        out.public_key_hash = in.public_key_hash;\n        std::reverse(out.public_key_hash.begin(), out.public_key_hash.end());\n        out.transaction_hash = in.transaction_hash;\n        result.emplace_back(out);\n    }\n\n    compact.clear();\n    return result;\n}\n\n// Address hash is still reversed here, to be unreversed in expansion.\nbool proxy::decode_stealth(reader &payload, stealth_handler &handler)\n{\n    chain::stealth_compact::list compact;\n\n    while (!payload.is_exhausted())\n    {\n        chain::stealth_compact row;\n        row.ephemeral_public_key_hash = payload.read_hash();\n        row.public_key_hash = payload.read_short_hash();\n        row.transaction_hash = payload.read_hash();\n        compact.emplace_back(row);\n\n        if (!payload)\n            return false;\n    }\n\n    handler(expand(compact));\n    return true;\n}\n\nhistory::list proxy::expand(history_compact::list &compact)\n{\n    history::list result;\n    result.reserve(compact.size());\n\n    std::unordered_map<uint64_t, history *> map_output;\n    // Process and remove all outputs.\n    for (auto output = compact.begin(); output != compact.end(); ++output)\n    {\n        if (output->kind == point_kind::output)\n        {\n            history row;\n            row.output = output->point;\n            row.output_height = output->height;\n            row.value = output->value;\n            row.spend = {null_hash, max_uint32};\n            row.temporary_checksum = output->point.checksum();\n            result.emplace_back(row);\n            map_output[row.temporary_checksum] = &result.back();\n        }\n    }\n\n    //process the spends.\n    for (const auto &spend : compact)\n    {\n        auto found = false;\n\n        if (spend.kind == point_kind::output)\n            continue;\n\n        auto r = map_output.find(spend.previous_checksum);\n        if (r != map_output.end() && r->second->spend.hash == null_hash)\n        {\n            r->second->spend = spend.point;\n            r->second->spend_height = spend.height;\n            found = true;\n        }\n\n        // This will only happen if the history height cutoff comes between\n        // an output and its spend. In this case we return just the spend.\n        if (!found)\n        {\n            history row;\n            row.output = {null_hash, max_uint32};\n            row.output_height = max_uint64;\n            row.value = max_uint64;\n            row.spend = spend.point;\n            row.spend_height = spend.height;\n            result.emplace_back(row);\n        }\n    }\n\n    compact.clear();\n\n    // Clear all remaining checksums from unspent rows.\n    for (auto &row : result)\n        if (row.spend.hash == null_hash)\n            row.spend_height = max_uint64;\n\n    // TODO: sort by height and index of output, spend or both in order.\n    return result;\n}\n\n// row.value || row.previous_checksum is a union, we just decode as row.value.\nbool proxy::decode_history(reader &payload, history_handler &handler)\n{\n    chain::history_compact::list compact;\n\n    while (!payload.is_exhausted())\n    {\n        chain::history_compact row;\n        row.kind = static_cast<point_kind>(payload.read_byte());\n        const auto success = row.point.from_data(payload);\n        row.height = payload.read_4_bytes_little_endian();\n        row.value = payload.read_8_bytes_little_endian();\n        compact.push_back(row);\n\n        if (!success || !payload)\n            return false;\n    }\n\n    handler(expand(compact));\n    return true;\n}\n\n// This supports address.fetch_history (which is obsolete as of server v3).\n// In this scenario the server sends to the client a payload that matches the\n// output of decode_history(...), with the exception that spends orphaned by\n// the server's minimum history hieght not included in the payload.\nbool proxy::decode_expanded_history(reader &payload, history_handler &handler)\n{\n    chain::history::list expanded;\n\n    while (!payload.is_exhausted())\n    {\n        chain::history row;\n        auto success = row.output.from_data(payload);\n\n        // Storing uint32_t height into uint64_t.\n        row.output_height = payload.read_4_bytes_little_endian();\n        row.value = payload.read_8_bytes_little_endian();\n\n        // If there is no spend then input is null_hash/max_uint32/max_uint32.\n        success &= row.spend.from_data(payload);\n\n        // Storing uint32_t height into uint64_t.\n        row.spend_height = payload.read_4_bytes_little_endian();\n        expanded.push_back(row);\n\n        if (!success || !payload)\n            return false;\n    }\n\n    handler(expanded);\n    return true;\n}\n\n} // namespace client\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/client/socket_stream.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-client.\n *\n * UChain-client is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/client/socket_stream.hpp>\n\n#include <cstdint>\n#include <UChain/protocol.hpp>\n\nnamespace libbitcoin\n{\nnamespace client\n{\n\nusing namespace bc::protocol;\n\nsocket_stream::socket_stream(zmq::socket &socket)\n    : socket_(socket)\n{\n}\n\nzmq::socket &socket_stream::socket()\n{\n    return socket_;\n}\n\n// Stream interface, not utilized on this class.\nint32_t socket_stream::refresh()\n{\n    return 0;\n}\n\n// TODO: optimize by passing the internal type of the message object.\n// Receieve a message from this socket onto the stream parameter.\nbool socket_stream::read(stream &stream)\n{\n    data_stack data;\n    zmq::message message;\n\n    if (socket_.receive(message) != (code)error::success)\n        return false;\n\n    // Copy the message to a data stack.\n    while (!message.empty())\n        data.push_back(message.dequeue_data());\n\n    return stream.write(data);\n}\n\n////bool socket_stream::read(std::shared_ptr<response_stream> stream)\n////{\n////    if (!stream)\n////        return false;\n////\n////    response_message message;\n////\n////    if (socket_.receive(message) != (code)error::success)\n////        return false;\n////\n////    auto response = message.get_response();\n////    return response && (stream->write(response) == (code)error::success);\n////}\n\n// TODO: optimize by passing the internal type of the message object.\n// Send a message built from the stack parameter to this socket.\nbool socket_stream::write(const data_stack &data)\n{\n    zmq::message message;\n\n    // Copy the data stack to a message.\n    for (const auto &chunk : data)\n        message.enqueue(chunk);\n\n    return socket_.send(message) == (code)error::success;\n}\n\n////bool socket_stream::write(const std::shared_ptr<request>& request)\n////{\n////    if (!request)\n////        return false;\n////\n////    request_message message;\n////    message.set_request(request);\n////    return socket_.send(message) == (code)error::success;\n////}\n\n} // namespace client\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/CMakeLists.txt",
    "content": "# for C library\nADD_SUBDIRECTORY(math/external)\n\nINCLUDE_DIRECTORIES(\"${PROJECT_SOURCE_DIR}/src/UChainService/consensus/clone\")\nFILE(GLOB_RECURSE bitcoin_SOURCES \"*.cpp\")\n\nADD_DEFINITIONS(-DBC_STATIC=1)\n\n\nADD_LIBRARY(secp256k1_static STATIC IMPORTED)                                         \nSET_TARGET_PROPERTIES(secp256k1_static PROPERTIES IMPORTED_LOCATION ${secp256k1_ROOT_DIR}/lib/libsecp256k1.a)\n\nADD_LIBRARY(bitcoin_static STATIC ${bitcoin_SOURCES})\nSET_TARGET_PROPERTIES(bitcoin_static PROPERTIES OUTPUT_NAME uc_bitcoin)\n#Centos add gmp\nIF(PLATFORM MATCHES \"Redhat\")\n        TARGET_LINK_LIBRARIES(bitcoin_static gmp)\nENDIF()\nTARGET_LINK_LIBRARIES(bitcoin_static ${Boost_LIBRARIES} secp256k1_static ${bitcoinmath_LIBRARY})\nINSTALL(TARGETS bitcoin_static DESTINATION lib)\n\nIF(ENABLE_SHARED_LIBS)\n    ADD_DEFINITIONS(-DBC_DLL=1)\n  ADD_LIBRARY(bitcoin_shared SHARED ${bitcoin_SOURCES})\n  SET_TARGET_PROPERTIES(bitcoin_shared PROPERTIES OUTPUT_NAME uc_bitcoin)\n  TARGET_LINK_LIBRARIES(bitcoin_shared ${Boost_LIBRARIES} secp256k1 ${bitcoinmath_LIBRARY})\n  INSTALL(TARGETS bitcoin_shared DESTINATION lib)\nENDIF()\n"
  },
  {
    "path": "src/UChain/coin/chain/block.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/chain/block.hpp>\n\n#include <utility>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/constants.hpp>\n#include <UChain/coin/formats/base_16.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nblock block::factory_from_data(const data_chunk &data,\n                               bool with_transaction_count)\n{\n    block instance;\n    instance.from_data(data, with_transaction_count);\n    return instance;\n}\n\nblock block::factory_from_data(std::istream &stream,\n                               bool with_transaction_count)\n{\n    block instance;\n    instance.from_data(stream, with_transaction_count);\n    return instance;\n}\n\nblock block::factory_from_data(reader &source,\n                               bool with_transaction_count)\n{\n    block instance;\n    instance.from_data(source, with_transaction_count);\n    return instance;\n}\n\nblock::block()\n{\n}\n\nblock::block(const block &other)\n    : block(other.header, other.transactions)\n{\n}\n\nblock::block(const chain::header &header,\n             const chain::transaction::list &transactions)\n    : header(header), transactions(transactions)\n{\n}\n\nblock::block(block &&other)\n    : block(std::forward<chain::header>(other.header),\n            std::forward<chain::transaction::list>(other.transactions))\n{\n}\n\nblock::block(chain::header &&header, chain::transaction::list &&transactions)\n    : header(std::forward<chain::header>(header)),\n      transactions(std::forward<chain::transaction::list>(transactions))\n{\n}\n\nblock &block::operator=(block &&other)\n{\n    header = std::move(other.header);\n    transactions = std::move(other.transactions);\n    return *this;\n}\n\nbool block::is_valid() const\n{\n    return !transactions.empty() || header.is_valid();\n}\n\nvoid block::reset()\n{\n    header.reset();\n    transactions.clear();\n    transactions.shrink_to_fit();\n}\n\nbool block::from_data(const data_chunk &data, bool with_transaction_count)\n{\n    data_source istream(data);\n    return from_data(istream, with_transaction_count);\n}\n\nbool block::from_data(std::istream &stream, bool with_transaction_count)\n{\n    istream_reader source(stream);\n    return from_data(source, with_transaction_count);\n}\n\nbool block::from_data(reader &source, bool with_transaction_count)\n{\n    reset();\n\n    auto result = header.from_data(source, with_transaction_count);\n\n    if (result)\n    {\n        transactions.resize(header.transaction_count);\n\n        for (auto &tx : transactions)\n        {\n            result = tx.from_data(source);\n\n            if (!result)\n                break;\n        }\n    }\n\n    if (!result)\n        reset();\n\n    return result;\n}\n\ndata_chunk block::to_data(bool with_transaction_count) const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream, with_transaction_count);\n    ostream.flush();\n    BITCOIN_ASSERT(header.number <= 1270000 || data.size() == serialized_size(with_transaction_count));\n    return data;\n}\n\nvoid block::to_data(std::ostream &stream, bool with_transaction_count) const\n{\n    ostream_writer sink(stream);\n    to_data(sink, with_transaction_count);\n}\n\nvoid block::to_data(writer &sink, bool with_transaction_count) const\n{\n    header.to_data(sink, with_transaction_count);\n\n    for (const auto &tx : transactions)\n        tx.to_data(sink);\n}\n\nuint64_t block::serialized_size(bool with_transaction_count) const\n{\n    auto block_size = header.serialized_size(with_transaction_count);\n\n    for (const auto &tx : transactions)\n        block_size += tx.serialized_size();\n\n    return block_size;\n}\n\nhash_digest build_merkle_tree(hash_list &merkle)\n{\n    // Stop if hash list is empty.\n    if (merkle.empty())\n        return null_hash;\n\n    // While there is more than 1 hash in the list, keep looping...\n    while (merkle.size() > 1)\n    {\n        // If number of hashes is odd, duplicate last hash in the list.\n        if (merkle.size() % 2 != 0)\n            merkle.push_back(merkle.back());\n\n        // List size is now even.\n        BITCOIN_ASSERT(merkle.size() % 2 == 0);\n\n        // New hash list.\n        hash_list new_merkle;\n\n        // Loop through hashes 2 at a time.\n        for (auto it = merkle.begin(); it != merkle.end(); it += 2)\n        {\n            // Join both current hashes together (concatenate).\n            data_chunk concat_data;\n            data_sink concat_stream(concat_data);\n            ostream_writer concat_sink(concat_stream);\n            concat_sink.write_hash(*it);\n            concat_sink.write_hash(*(it + 1));\n            concat_stream.flush();\n\n            BITCOIN_ASSERT(concat_data.size() == (2 * hash_size));\n\n            // Hash both of the hashes.\n            const auto new_root = bitcoin_hash(concat_data);\n\n            // Add this to the new list.\n            new_merkle.push_back(new_root);\n        }\n\n        // This is the new list.\n        merkle = new_merkle;\n    }\n\n    // Finally we end up with a single item.\n    return merkle[0];\n}\n\nhash_digest block::generate_merkle_root(const transaction::list &transactions)\n{\n    // Generate list of transaction hashes.\n    hash_list tx_hashes;\n    for (const auto &tx : transactions)\n        tx_hashes.push_back(tx.hash());\n\n    // Build merkle tree.\n    return build_merkle_tree(tx_hashes);\n}\n\nstatic const std::string encoded_mainnet_genesis_block =\n    \"01000000\"\n    \"0000000000000000000000000000000000000000000000000000000000000000\"\n    \"3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a\"\n    \"29ab5f49\"\n    \"ffff001d\"\n    \"1dac2b7c\"\n    \"01\"\n    \"01000000\"\n    \"01\"\n    \"0000000000000000000000000000000000000000000000000000000000000000ffffffff\"\n    \"4d\"\n    \"04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73\"\n    \"ffffffff\"\n    \"01\"\n    \"00f2052a01000000\"\n    \"43\"\n    \"4104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac\"\n    \"00000000\";\n\nstatic const std::string encoded_testnet_genesis_block =\n    \"01000000\"\n    \"0000000000000000000000000000000000000000000000000000000000000000\"\n    \"3ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a\"\n    \"dae5494d\"\n    \"ffff001d\"\n    \"1aa4ae18\"\n    \"01\"\n    \"01000000\"\n    \"01\"\n    \"0000000000000000000000000000000000000000000000000000000000000000ffffffff\"\n    \"4d\"\n    \"04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73\"\n    \"ffffffff\"\n    \"01\"\n    \"00f2052a01000000\"\n    \"43\"\n    \"4104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac\"\n    \"00000000\";\n\nchain::block block::genesis_mainnet()\n{\n    data_chunk raw_block;\n    decode_base16(raw_block, encoded_mainnet_genesis_block);\n    const auto genesis = chain::block::factory_from_data(raw_block);\n\n    BITCOIN_ASSERT(genesis.is_valid());\n    BITCOIN_ASSERT(genesis.transactions.size() == 1);\n    BITCOIN_ASSERT(chain::block::generate_merkle_root(genesis.transactions) == genesis.header.merkle);\n\n    return genesis;\n}\n\nchain::block block::genesis_testnet()\n{\n    data_chunk raw_block;\n    decode_base16(raw_block, encoded_testnet_genesis_block);\n    const auto genesis = chain::block::factory_from_data(raw_block);\n\n    BITCOIN_ASSERT(genesis.is_valid());\n    BITCOIN_ASSERT(genesis.transactions.size() == 1);\n    BITCOIN_ASSERT(chain::block::generate_merkle_root(genesis.transactions) == genesis.header.merkle);\n\n    return genesis;\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/chain/header.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/chain/header.hpp>\n\n#include <utility>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/constants.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n#include <UChainService/consensus/libdevcore/FixedHash.h>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nheader header::factory_from_data(const data_chunk &data,\n                                 bool with_transaction_count)\n{\n    header instance;\n    instance.from_data(data, with_transaction_count);\n    return instance;\n}\n\nheader header::factory_from_data(std::istream &stream,\n                                 bool with_transaction_count)\n{\n    header instance;\n    instance.from_data(stream, with_transaction_count);\n    return instance;\n}\n\nheader header::factory_from_data(reader &source,\n                                 bool with_transaction_count)\n{\n    header instance;\n    instance.from_data(source, with_transaction_count);\n    return instance;\n}\n\nuint64_t header::satoshi_fixed_size_without_transaction_count()\n{\n    return 76; //148-32-8-32;\n}\n\nheader::header()\n{\n}\n\nheader::header(const header &other)\n    : header(other.version, other.previous_block_hash, other.merkle,\n             other.timestamp, /*other.bits, other.nonce, other.mixhash,*/ other.number, other.transaction_count)\n{\n}\n\nheader::header(uint32_t version, const hash_digest &previous_block_hash,\n               const hash_digest &merkle, uint32_t timestamp, /* const u256& bits,\n    u64 nonce, const u256& mixhash, */\n               uint32_t number, uint64_t transaction_count)\n    : version(version),\n      previous_block_hash(previous_block_hash),\n      merkle(merkle),\n      timestamp(timestamp),\n      //bits(bits),\n      //nonce(nonce),\n      //mixhash(mixhash),\n      number(number),\n      transaction_count(transaction_count),\n      hash_(nullptr)\n{\n}\n\nheader::header(header &&other)\n    : header(other.version, std::forward<hash_digest>(other.previous_block_hash),\n             std::forward<hash_digest>(other.merkle), other.timestamp, /*other.bits,\n        other.nonce, other.mixhash,*/\n                                                                       other.number,\n             other.transaction_count)\n{\n}\n\nheader::header(uint32_t version, hash_digest &&previous_block_hash,\n               hash_digest &&merkle, uint32_t timestamp, /*const u256& bits, u64 nonce, const u256& mixhash, */ uint32_t number,\n               uint64_t transaction_count)\n    : version(version),\n      previous_block_hash(std::forward<hash_digest>(previous_block_hash)),\n      merkle(std::forward<hash_digest>(merkle)),\n      timestamp(timestamp),\n      //bits(bits),\n      //nonce(nonce),\n      //mixhash(mixhash),\n      number(number),\n      transaction_count(transaction_count),\n      hash_(nullptr)\n{\n}\n\nheader &header::operator=(header &&other)\n{\n    version = other.version;\n    previous_block_hash = std::move(other.previous_block_hash);\n    merkle = std::move(other.merkle);\n    timestamp = other.timestamp;\n    //bits = other.bits;\n    //nonce = other.nonce;\n    //mixhash = other.mixhash;\n    number = other.number;\n    transaction_count = other.transaction_count;\n    return *this;\n}\n\n// TODO: eliminate header copies and then delete this.\nheader &header::operator=(const header &other)\n{\n    version = other.version;\n    previous_block_hash = other.previous_block_hash;\n    merkle = other.merkle;\n    timestamp = other.timestamp;\n    //bits = other.bits;\n    //nonce = other.nonce;\n    //mixhash = other.mixhash;\n    number = other.number;\n    transaction_count = other.transaction_count;\n    return *this;\n}\n\nbool header::is_valid() const\n{\n    return (version != 0) ||\n           (previous_block_hash != null_hash) ||\n           (merkle != null_hash) ||\n           (timestamp != 0) /*||\n        (bits != 0) ||\n        (nonce != 0)*/\n        ;\n}\n\nvoid header::reset()\n{\n    version = 0;\n    previous_block_hash.fill(0);\n    merkle.fill(0);\n    timestamp = 0;\n    //bits = 0;\n    //nonce = 0;\n\n    mutex_.lock();\n    hash_.reset();\n    mutex_.unlock();\n}\n\nbool header::from_data(const data_chunk &data,\n                       bool with_transaction_count)\n{\n    data_source istream(data);\n    return from_data(istream, with_transaction_count);\n}\n\nbool header::from_data(std::istream &stream, bool with_transaction_count)\n{\n    istream_reader source(stream);\n    return from_data(source, with_transaction_count);\n}\n\nbool header::from_data(reader &source, bool with_transaction_count)\n{\n    reset();\n\n    version = source.read_4_bytes_little_endian();\n    previous_block_hash = source.read_hash();\n    merkle = source.read_hash();\n    timestamp = source.read_4_bytes_little_endian();\n\n    /*unsigned char buff[32];\n    source.read_data(buff, 32);\n    bits = (h256::Arith)(h256((const uint8_t*)&buff[0], h256::ConstructFromPointer));\n\n    source.read_data(buff, 8);\n    nonce = (h64::Arith)(h64((const uint8_t*)&buff[0], h64::ConstructFromPointer));\n\n    source.read_data(buff, 32);\n    mixhash = (h256::Arith)(h256((const uint8_t*)&buff[0], h256::ConstructFromPointer));*/\n\n    number = source.read_4_bytes_little_endian();\n\n    transaction_count = 0;\n    if (with_transaction_count)\n        transaction_count = source.read_variable_uint_little_endian();\n\n    const auto result = static_cast<bool>(source);\n\n    if (!result)\n        reset();\n\n    return result;\n}\n\ndata_chunk header::to_data(bool with_transaction_count) const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream, with_transaction_count);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(with_transaction_count));\n    return data;\n}\n\nvoid header::to_data(std::ostream &stream,\n                     bool with_transaction_count) const\n{\n    ostream_writer sink(stream);\n    to_data(sink, with_transaction_count);\n}\n\nvoid header::to_data(writer &sink, bool with_transaction_count) const\n{\n    sink.write_4_bytes_little_endian(version);\n    sink.write_hash(previous_block_hash);\n    sink.write_hash(merkle);\n    sink.write_4_bytes_little_endian(timestamp);\n\n    //sink.write_data((unsigned char*)h256(bits).data(), 32);\n    //sink.write_data((unsigned char*)h64(nonce).data(), 8);\n    //sink.write_data((unsigned char*)h256(mixhash).data(), 32);\n\n    sink.write_4_bytes_little_endian(number);\n\n    if (with_transaction_count)\n        sink.write_variable_uint_little_endian(transaction_count);\n}\n\nuint64_t header::serialized_size(bool with_transaction_count) const\n{\n    auto size = satoshi_fixed_size_without_transaction_count();\n\n    if (with_transaction_count)\n        size += variable_uint_size(transaction_count);\n\n    return size;\n}\n\nhash_digest header::hash() const\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    mutex_.lock_upgrade();\n\n    if (!hash_)\n    {\n        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n        mutex_.unlock_upgrade_and_lock();\n        hash_.reset(new hash_digest(bitcoin_hash(to_data(false))));\n        mutex_.unlock_and_lock_upgrade();\n        //---------------------------------------------------------------------\n    }\n\n    hash_digest hash = *hash_;\n    mutex_.unlock_upgrade();\n    ///////////////////////////////////////////////////////////////////////////\n\n    return hash;\n}\n\nbool operator==(const header &left, const header &right)\n{\n    return (left.version == right.version) && (left.previous_block_hash == right.previous_block_hash) && (left.merkle == right.merkle) && (left.timestamp == right.timestamp)\n           /*&& (left.bits == right.bits)\n        && (left.nonce == right.nonce)*/\n           && (left.transaction_count == right.transaction_count);\n}\n\nbool operator!=(const header &left, const header &right)\n{\n    return !(left == right);\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/chain/input.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/chain/input.hpp>\n\n#include <sstream>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/constants.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\ninput input::factory_from_data(const data_chunk &data)\n{\n    input instance;\n    instance.from_data(data);\n    return instance;\n}\n\ninput input::factory_from_data(std::istream &stream)\n{\n    input instance;\n    instance.from_data(stream);\n    return instance;\n}\n\ninput input::factory_from_data(reader &source)\n{\n    input instance;\n    instance.from_data(source);\n    return instance;\n}\n\nbool input::is_valid() const\n{\n    return (sequence != 0) ||\n           previous_output.is_valid() ||\n           script.is_valid();\n}\n\nvoid input::reset()\n{\n    previous_output.reset();\n    script.reset();\n    sequence = 0;\n}\n\nbool input::from_data(const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(istream);\n}\n\nbool input::from_data(std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(source);\n}\n\nbool input::from_data(reader &source)\n{\n    reset();\n\n    auto result = previous_output.from_data(source);\n\n    if (result)\n    {\n        auto mode = script::parse_mode::raw_data_fallback;\n\n        if (previous_output.is_null())\n            mode = script::parse_mode::raw_data;\n\n        result = script.from_data(source, true, mode);\n    }\n\n    if (result)\n    {\n        sequence = source.read_4_bytes_little_endian();\n        result = source;\n    }\n\n    if (!result)\n        reset();\n\n    return result;\n}\n\ndata_chunk input::to_data() const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size());\n    return data;\n}\n\nvoid input::to_data(std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(sink);\n}\n\nvoid input::to_data(writer &sink) const\n{\n    previous_output.to_data(sink);\n    script.to_data(sink, true);\n    sink.write_4_bytes_little_endian(sequence);\n}\n\nuint64_t input::serialized_size() const\n{\n    const auto script_size = script.serialized_size(true);\n    return 4 + previous_output.serialized_size() + script_size;\n}\n\nstd::string input::to_string(uint32_t flags) const\n{\n    std::ostringstream ss;\n\n    ss << previous_output.to_string() << \"\\n\"\n       << \"\\t\" << script.to_string(flags) << \"\\n\"\n       << \"\\tsequence = \" << sequence << \"\\n\";\n\n    return ss.str();\n}\n\nbool input::is_final() const\n{\n    return (sequence == max_input_sequence);\n}\n\nstd::string input::get_script_address() const\n{\n    auto payment_address = bc::wallet::payment_address::extract(script);\n    return payment_address.encoded();\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/chain/output.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/chain/output.hpp>\n#include <cctype>\n#include <sstream>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n#include <UChain/coin/wallet/payment_address.hpp>\n#include <UChain/blockchain/block_chain_impl.hpp>\n#include <boost/algorithm/string.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\noutput output::factory_from_data(const data_chunk &data)\n{\n    output instance;\n    instance.from_data(data);\n    return instance;\n}\n\noutput output::factory_from_data(std::istream &stream)\n{\n    output instance;\n    instance.from_data(stream);\n    return instance;\n}\n\noutput output::factory_from_data(reader &source)\n{\n    output instance;\n    instance.from_data(source);\n    return instance;\n}\nbool output::is_valid_symbol(const std::string &symbol, uint32_t tx_version)\n{\n    if (symbol.empty())\n        return false;\n    // length check\n    if (symbol.length() > TOKEN_DETAIL_SYMBOL_FIX_SIZE)\n        return false;\n    // char check\n    for (const auto &i : symbol)\n    {\n        if (!(std::isalnum(i) || i == '.'))\n            return false;\n    }\n    if (tx_version >= transaction_version::check_uid_feature)\n    {\n        // upper char check\n        if (symbol != boost::to_upper_copy(symbol))\n        {\n            return false;\n        }\n        // sensitive check\n        if (bc::wallet::symbol::is_sensitive(symbol))\n        {\n            return false;\n        }\n    }\n    return true;\n}\n\nbool output::is_valid_uid_symbol(const std::string &symbol, bool check_sensitive)\n{\n    if (symbol.empty())\n        return false;\n    // length check\n    if (symbol.length() > UID_DETAIL_SYMBOL_FIX_SIZE)\n        return false;\n    // char check\n    for (const auto &i : symbol)\n    {\n        if (!(std::isalnum(i) || i == '.' || i == '@' || i == '_'))\n            return false;\n    }\n\n    if (check_sensitive)\n    {\n        // sensitive check\n        std::string symbolupper = symbol;\n        boost::to_upper(symbolupper);\n        if (bc::wallet::symbol::is_sensitive(symbolupper))\n            return false;\n    }\n\n    return true;\n}\n\nbool output::is_valid_candidate_symbol(const std::string &symbol, bool check_sensitive)\n{\n    if (symbol.empty())\n        return false;\n    // length check\n    if (symbol.length() > TOKEN_CANDIDATE_SYMBOL_FIX_SIZE)\n        return false;\n    // char check\n    for (const auto &i : symbol)\n    {\n        if (!(std::isalnum(i) || i == '.' || i == '@' || i == '_'))\n            return false;\n    }\n\n    if (check_sensitive)\n    {\n        // sensitive check\n        auto upper = boost::to_upper_copy(symbol);\n        if (bc::wallet::symbol::is_sensitive(upper))\n            return false;\n    }\n\n    /*try {\n        const auto authority = libbitcoin::config::authority(symbol);\n        if (!authority.to_network_address().is_routable()) {\n            return false;\n        }\n    }\n    catch (...)\n    {\n        return false;\n    }*/\n\n    return true;\n}\n\nbool output::is_valid() const\n{\n    return (value != 0) || script.is_valid() || attach_data.is_valid(); // added for token issue/transfer\n}\n\nstd::string output::get_script_address() const\n{\n    auto payment_address = bc::wallet::payment_address::extract(script);\n    return payment_address.encoded();\n}\n\ncode output::check_asset_address(bc::blockchain::block_chain_impl &chain) const\n{\n    bool is_token = false;\n    bool is_uid = false;\n    std::string asset_address;\n    if (is_token_issue() || is_token_secondaryissue() || is_candidate())\n    {\n        asset_address = get_token_address();\n        is_token = true;\n    }\n    else if (is_token_cert())\n    {\n        asset_address = get_token_cert_address();\n        is_token = true;\n    }\n    else if (is_uid_register() || is_uid_transfer())\n    {\n        asset_address = get_uid_address();\n        is_uid = true;\n    }\n    if (is_token || is_uid)\n    {\n        auto script_address = get_script_address();\n        if (asset_address != script_address)\n        {\n            log::debug(\"output::check_asset_address\")\n                << (is_token ? \"token\" : \"uid\")\n                << \" asset address \" << asset_address\n                << \" is not equal to script address \" << script_address;\n            if (is_token)\n            {\n                return error::token_address_not_match;\n            }\n            if (is_uid)\n            {\n                return error::uid_address_not_match;\n            }\n        }\n    }\n    return error::success;\n}\n\nvoid output::reset()\n{\n    value = 0;\n    script.reset();\n    attach_data.reset(); // added for token issue/transfer\n}\n\nbool output::from_data(const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(istream);\n}\n\nbool output::from_data(std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(source);\n}\n\nbool output::from_data(reader &source)\n{\n    reset();\n\n    value = source.read_8_bytes_little_endian();\n    auto result = static_cast<bool>(source);\n\n    if (result)\n        result = script.from_data(source, true,\n                                  script::parse_mode::raw_data_fallback);\n\n    /* begin added for token issue/transfer */\n    if (result)\n        result = attach_data.from_data(source);\n    /* end added for token issue/transfer */\n\n    if (!result)\n        reset();\n\n    return result;\n}\n\ndata_chunk output::to_data() const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream);\n    ostream.flush();\n    log::debug(\"output::to_data\") << \"data.size=\" << data.size();\n    log::debug(\"output::to_data\") << \"serialized_size=\" << serialized_size();\n    //BITCOIN_ASSERT(data.size() == serialized_size());\n    return data;\n}\n\nvoid output::to_data(std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(sink);\n}\n\nvoid output::to_data(writer &sink) const\n{\n    sink.write_8_bytes_little_endian(value);\n    script.to_data(sink, true);\n    /* begin added for token issue/transfer */\n    attach_data.to_data(sink);\n    /* end added for token issue/transfer */\n}\n\nuint64_t output::serialized_size() const\n{\n    return 8 + script.serialized_size(true) + attach_data.serialized_size(); // added for token issue/transfer\n}\n\nstd::string output::to_string(uint32_t flags) const\n{\n    std::ostringstream ss;\n\n    ss << \"\\tvalue = \" << value << \"\\n\"\n       << \"\\t\" << script.to_string(flags) << \"\\n\"\n       << \"\\t\" << attach_data.to_string() << \"\\n\"; // added for token issue/transfer\n\n    return ss.str();\n}\n\nuint64_t output::get_token_amount() const // for validate_tx_engine.cpp to calculate token transfer amount\n{\n    if (attach_data.get_type() == UC_TOKEN_TYPE)\n    {\n        auto token_info = boost::get<token>(attach_data.get_attach());\n        if (token_info.get_status() == TOKEN_DETAIL_TYPE)\n        {\n            auto detail_info = boost::get<token_detail>(token_info.get_data());\n            return detail_info.get_maximum_supply();\n        }\n        if (token_info.get_status() == TOKEN_TRANSFERABLE_TYPE)\n        {\n            auto trans_info = boost::get<token_transfer>(token_info.get_data());\n            return trans_info.get_quantity();\n        }\n    }\n    return 0;\n}\n\nbool output::is_token_transfer() const\n{\n    if (attach_data.get_type() == UC_TOKEN_TYPE)\n    {\n        auto token_info = boost::get<token>(attach_data.get_attach());\n        return (token_info.get_status() == TOKEN_TRANSFERABLE_TYPE);\n    }\n    return false;\n}\n\nbool output::is_vote() const\n{\n    return is_token_transfer() && get_token_symbol() == UC_VOTE_TOKEN_SYMBOL;\n}\n\nbool output::is_uid_transfer() const\n{\n    if (attach_data.get_type() == UID_TYPE)\n    {\n        auto uid_info = boost::get<uid>(attach_data.get_attach());\n        return (uid_info.get_status() == UID_TRANSFERABLE_TYPE);\n    }\n    return false;\n}\n\nbool output::is_token_issue() const\n{\n    if (attach_data.get_type() == UC_TOKEN_TYPE)\n    {\n        auto token_info = boost::get<token>(attach_data.get_attach());\n        if (token_info.get_status() == TOKEN_DETAIL_TYPE)\n        {\n            auto detail_info = boost::get<token_detail>(token_info.get_data());\n            return !detail_info.is_token_secondaryissue();\n        }\n    }\n    return false;\n}\n\nbool output::is_token_secondaryissue() const\n{\n    if (attach_data.get_type() == UC_TOKEN_TYPE)\n    {\n        auto token_info = boost::get<token>(attach_data.get_attach());\n        if (token_info.get_status() == TOKEN_DETAIL_TYPE)\n        {\n            auto detail_info = boost::get<token_detail>(token_info.get_data());\n            return detail_info.is_token_secondaryissue();\n        }\n    }\n    return false;\n}\n\nbool output::is_candidate() const\n{\n    return (attach_data.get_type() == TOKEN_CANDIDATE_TYPE);\n}\n\nbool output::is_fromuid_filled() const\n{\n    return attach_data.get_version() == UID_ASSET_VERIFY_VERSION && !attach_data.get_from_uid().empty();\n}\n\nbool output::is_touid_filled() const\n{\n    return attach_data.get_version() == UID_ASSET_VERIFY_VERSION && !attach_data.get_to_uid().empty();\n}\n\nbool output::is_uid_full_filled() const\n{\n    return attach_data.get_version() == UID_ASSET_VERIFY_VERSION && !attach_data.get_to_uid().empty() && !attach_data.get_from_uid().empty();\n}\n\nstd::string output::get_from_uid() const\n{\n    if (attach_data.get_version() == UID_ASSET_VERIFY_VERSION)\n    {\n        attach_data.get_from_uid();\n    }\n    return \"\";\n}\n\nstd::string output::get_to_uid() const\n{\n    if (attach_data.get_version() == UID_ASSET_VERIFY_VERSION)\n    {\n        return attach_data.get_to_uid();\n    }\n    else\n        return \"\";\n}\n\nstd::string output::get_candidate_symbol() const\n{\n    if (is_candidate())\n    {\n        auto candidate_info = boost::get<candidate>(attach_data.get_attach());\n        return candidate_info.get_symbol();\n    }\n    return std::string(\"\");\n}\n\nbool output::is_candidate_register() const\n{\n    if (is_candidate())\n    {\n        auto token_info = boost::get<candidate>(attach_data.get_attach());\n        if (token_info.is_register_status())\n        {\n            return true;\n        }\n    }\n    return false;\n}\n\nbool output::is_candidate_transfer() const\n{\n    if (is_candidate())\n    {\n        auto token_info = boost::get<candidate>(attach_data.get_attach());\n        if (token_info.is_transfer_status())\n        {\n            return true;\n        }\n    }\n    return false;\n}\n\nbool output::is_token_cert() const\n{\n    return (attach_data.get_type() == TOKEN_CERT_TYPE);\n}\n\nbool output::is_token_cert_autoissue() const\n{\n    if (attach_data.get_type() == TOKEN_CERT_TYPE)\n    {\n        auto cert_info = boost::get<token_cert>(attach_data.get_attach());\n        if (cert_info.get_status() == TOKEN_CERT_AUTOISSUE_TYPE)\n        {\n            return true;\n        }\n    }\n    return false;\n}\n\nbool output::is_token_cert_issue() const\n{\n    if (attach_data.get_type() == TOKEN_CERT_TYPE)\n    {\n        auto cert_info = boost::get<token_cert>(attach_data.get_attach());\n        if (cert_info.get_status() == TOKEN_CERT_ISSUE_TYPE)\n        {\n            return true;\n        }\n    }\n    return false;\n}\n\nbool output::is_token_cert_transfer() const\n{\n    if (attach_data.get_type() == TOKEN_CERT_TYPE)\n    {\n        auto cert_info = boost::get<token_cert>(attach_data.get_attach());\n        if (cert_info.get_status() == TOKEN_CERT_TRANSFER_TYPE)\n        {\n            return true;\n        }\n    }\n    return false;\n}\n\nbool output::is_token() const\n{\n    return (attach_data.get_type() == UC_TOKEN_TYPE);\n}\n\nbool output::is_uid() const\n{\n    return (attach_data.get_type() == UID_TYPE);\n}\n\nbool output::is_ucn() const\n{\n    return (attach_data.get_type() == UCN_TYPE);\n}\n\nbool output::is_ucn_award() const\n{\n    return (attach_data.get_type() == UCN_AWARD_TYPE);\n}\n\nbool output::is_message() const\n{\n    return (attach_data.get_type() == MESSAGE_TYPE);\n}\n\nstd::string output::get_token_symbol() const // for validate_tx_engine.cpp to calculate token transfer amount\n{\n    if (is_token())\n    {\n        auto token_info = boost::get<token>(attach_data.get_attach());\n        if (token_info.get_status() == TOKEN_DETAIL_TYPE)\n        {\n            auto detail_info = boost::get<token_detail>(token_info.get_data());\n            return detail_info.get_symbol();\n        }\n        if (token_info.get_status() == TOKEN_TRANSFERABLE_TYPE)\n        {\n            auto trans_info = boost::get<token_transfer>(token_info.get_data());\n            return trans_info.get_symbol();\n        }\n    }\n    else if (is_candidate())\n    {\n        auto token_info = boost::get<candidate>(attach_data.get_attach());\n        return token_info.get_symbol();\n    }\n    else if (is_token_cert())\n    {\n        auto cert_info = boost::get<token_cert>(attach_data.get_attach());\n        return cert_info.get_symbol();\n    }\n    return std::string(\"\");\n}\n\nstd::string output::get_token_issuer() const // for validate_tx_engine.cpp to calculate token transfer amount\n{\n    if (is_token())\n    {\n        auto token_info = boost::get<token>(attach_data.get_attach());\n        if (token_info.get_status() == TOKEN_DETAIL_TYPE)\n        {\n            auto detail_info = boost::get<token_detail>(token_info.get_data());\n            return detail_info.get_issuer();\n        }\n    }\n    else if (is_candidate())\n    {\n        BITCOIN_ASSERT(false);\n    }\n    return std::string(\"\");\n}\n\nstd::string output::get_token_address() const // for validate_tx_engine.cpp to verify token address\n{\n    if (is_token())\n    {\n        auto token_info = boost::get<token>(attach_data.get_attach());\n        if (token_info.get_status() == TOKEN_DETAIL_TYPE)\n        {\n            auto detail_info = boost::get<token_detail>(token_info.get_data());\n            return detail_info.get_address();\n        }\n    }\n    else if (is_candidate())\n    {\n        auto token_info = boost::get<candidate>(attach_data.get_attach());\n        return token_info.get_address();\n    }\n    return std::string(\"\");\n}\n\ncandidate output::get_candidate() const\n{\n    if (is_candidate())\n    {\n        return boost::get<candidate>(attach_data.get_attach());\n    }\n    log::error(\"output::get_candidate\") << \"Token type is not an candidate.\";\n    return candidate();\n}\n\ntoken_cert output::get_token_cert() const\n{\n    if (is_token_cert())\n    {\n        return boost::get<token_cert>(attach_data.get_attach());\n    }\n    log::error(\"output::get_token_cert\") << \"Token type is not an token_cert.\";\n    return token_cert();\n}\n\nstd::string output::get_token_cert_symbol() const\n{\n    if (is_token_cert())\n    {\n        auto cert_info = boost::get<token_cert>(attach_data.get_attach());\n        return cert_info.get_symbol();\n    }\n    return std::string(\"\");\n}\n\nstd::string output::get_token_cert_owner() const\n{\n    if (is_token_cert())\n    {\n        auto cert_info = boost::get<token_cert>(attach_data.get_attach());\n        return cert_info.get_owner();\n    }\n    return std::string(\"\");\n}\n\nstd::string output::get_token_cert_address() const\n{\n    if (is_token_cert())\n    {\n        auto cert_info = boost::get<token_cert>(attach_data.get_attach());\n        return cert_info.get_address();\n    }\n\n    return std::string(\"\");\n}\n\ntoken_cert_type output::get_token_cert_type() const\n{\n    if (is_token_cert())\n    {\n        auto cert_info = boost::get<token_cert>(attach_data.get_attach());\n        return cert_info.get_type();\n    }\n    return token_cert_ns::none;\n}\n\nbool output::is_uid_register() const\n{\n    if (attach_data.get_type() == UID_TYPE)\n    {\n        auto uid_info = boost::get<uid>(attach_data.get_attach());\n        return (uid_info.get_status() == UID_DETAIL_TYPE);\n    }\n    return false;\n}\n\nstd::string output::get_uid_symbol() const // for validate_tx_engine.cpp to calculate uid transfer amount\n{\n    if (attach_data.get_type() == UID_TYPE)\n    {\n        auto uid_info = boost::get<uid>(attach_data.get_attach());\n        auto detail_info = boost::get<uid_detail>(uid_info.get_data());\n        return detail_info.get_symbol();\n    }\n    return std::string(\"\");\n}\n\nstd::string output::get_uid_address() const // for validate_tx_engine.cpp to calculate uid transfer amount\n{\n    if (attach_data.get_type() == UID_TYPE)\n    {\n        auto uid_info = boost::get<uid>(attach_data.get_attach());\n        auto detail_info = boost::get<uid_detail>(uid_info.get_data());\n        return detail_info.get_address();\n    }\n    return std::string(\"\");\n}\n\nuid output::get_uid() const\n{\n    if (attach_data.get_type() == UID_TYPE)\n    {\n        return boost::get<uid>(attach_data.get_attach());\n    }\n    return uid();\n}\n\ntoken_transfer output::get_token_transfer() const\n{\n    if (attach_data.get_type() == UC_TOKEN_TYPE)\n    {\n        auto token_info = boost::get<token>(attach_data.get_attach());\n        if (token_info.get_status() == TOKEN_TRANSFERABLE_TYPE)\n        {\n            return boost::get<token_transfer>(token_info.get_data());\n        }\n    }\n    log::error(\"output::get_token_transfer\") << \"Token type is not token_transfer_TYPE.\";\n    return token_transfer();\n}\n\ntoken_detail output::get_token_detail() const\n{\n    if (attach_data.get_type() == UC_TOKEN_TYPE)\n    {\n        auto token_info = boost::get<token>(attach_data.get_attach());\n        if (token_info.get_status() == TOKEN_DETAIL_TYPE)\n        {\n            return boost::get<token_detail>(token_info.get_data());\n        }\n    }\n    log::error(\"output::get_token_detail\") << \"Token type is not TOKEN_DETAIL_TYPE.\";\n    return token_detail();\n}\n\nconst data_chunk &output::get_attenuation_model_param() const\n{\n    BITCOIN_ASSERT(operation::is_pay_key_hash_with_attenuation_model_pattern(script.operations));\n    return operation::get_model_param_from_pay_key_hash_with_attenuation_model(script.operations);\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/chain/point.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/chain/point.hpp>\n\n#include <cstdint>\n#include <sstream>\n#include <tuple>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/constants.hpp>\n#include <UChain/coin/formats/base_16.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n#include <UChain/coin/utility/serializer.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\npoint point::factory_from_data(const data_chunk &data)\n{\n    point instance;\n    instance.from_data(data);\n    return instance;\n}\n\npoint point::factory_from_data(std::istream &stream)\n{\n    point instance;\n    instance.from_data(stream);\n    return instance;\n}\n\npoint point::factory_from_data(reader &source)\n{\n    point instance;\n    instance.from_data(source);\n    return instance;\n}\n\nbool point::is_valid() const\n{\n    return (index != 0) || (hash != null_hash);\n}\n\nvoid point::reset()\n{\n    hash.fill(0);\n    index = 0;\n}\n\nbool point::from_data(const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(istream);\n}\n\nbool point::from_data(std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(source);\n}\n\nbool point::from_data(reader &source)\n{\n    reset();\n\n    hash = source.read_hash();\n    index = source.read_4_bytes_little_endian();\n    const auto result = static_cast<bool>(source);\n\n    if (!result)\n        reset();\n\n    return result;\n}\n\ndata_chunk point::to_data() const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size());\n    return data;\n}\n\nvoid point::to_data(std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(sink);\n}\n\nvoid point::to_data(writer &sink) const\n{\n    sink.write_hash(hash);\n    sink.write_4_bytes_little_endian(index);\n}\n\nuint64_t point::serialized_size() const\n{\n    return point::satoshi_fixed_size();\n}\n\nuint64_t point::satoshi_fixed_size()\n{\n    return hash_size + sizeof(uint32_t);\n}\n\npoint_iterator point::begin() const\n{\n    return point_iterator(*this);\n}\n\npoint_iterator point::end() const\n{\n    return point_iterator(*this, true);\n}\n\nstd::string point::to_string() const\n{\n    std::ostringstream value;\n    value << \"\\thash = \" << encode_hash(hash) << \"\\n\\tindex = \" << index;\n    return value.str();\n}\n\nbool point::is_null() const\n{\n    return index == max_uint32 && hash == null_hash;\n}\n// Changed in v3.0 and again in v3.1 (3.0 was unmasked, lots of collisions).\n// This is used with output_point identification within a set of history rows\n// of the same address. Collision will result in miscorrelation of points by\n// client callers. This is stored in database. This is NOT a bitcoin checksum.\nuint64_t point::checksum() const\n{\n    // Reserve 49 bits for the tx hash and 15 bits (32768) for the input index.\n    static constexpr uint64_t mask = 0xffffffffffff8000;\n\n    // Use an offset to the middle of the hash to avoid coincidental mining\n    // of values into the front or back of tx hash (not a security feature).\n    // Use most possible bits of tx hash to make intentional collision hard.\n    const auto tx = from_little_endian_unsafe<uint64_t>(hash.begin() + 12);\n    const auto tx_index = static_cast<uint64_t>(index);\n\n    const auto tx_upper_49_bits = tx & mask;\n    const auto index_lower_15_bits = tx_index & ~mask;\n    return tx_upper_49_bits | index_lower_15_bits;\n}\n#if 0 // old version checksum method\n// This is used with output_point identification within a set of history rows\n// of the same address. Collision will result in miscorrelation of points by\n// client callers. This is NOT a bitcoin checksum.\nuint64_t point::checksum() const\n{\n    static constexpr uint64_t divisor = uint64_t{ 1 } << 63;\n    static_assert(divisor == 9223372036854775808ull, \"Wrong divisor value.\");\n\n    // Write index onto a copy of the outpoint hash.\n    auto copy = hash;\n    auto serial = make_serializer(copy.begin());\n    serial.write_4_bytes_little_endian(index);\n    const auto hash_value = from_little_endian_unsafe<uint64_t>(copy.begin());\n\n    // x mod 2**n == x & (2**n - 1)\n    return hash_value & (divisor - 1);\n\n    // Above usually provides only 32 bits of entropy, so below is preferred.\n    // But this is stored in the database. Change requires server API change.\n    // return std::hash<point>()(*this);\n}\n#endif\nbool operator==(const point &left, const point &right)\n{\n    return left.hash == right.hash && left.index == right.index;\n}\n\nbool operator!=(const point &left, const point &right)\n{\n    return !(left == right);\n}\n\nbool operator<(const point &left, const point &right)\n{\n    typedef std::tuple<hash_digest, uint32_t> tupe_cmp;\n    return tupe_cmp(left.hash, left.index) < tupe_cmp(right.hash, right.index);\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/chain/point_iterator.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/chain/point_iterator.hpp>\n#include <UChain/coin/chain/point.hpp>\n#include <UChain/coin/utility/endian.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nstatic BC_CONSTEXPR uint8_t max_offset = hash_size + sizeof(uint32_t);\n\npoint_iterator::point_iterator(const point &value)\n    : point_(value), offset_(0)\n{\n}\n\npoint_iterator::point_iterator(const point &value, bool end)\n    : point_(value), offset_(end ? max_offset : 0)\n{\n}\n\npoint_iterator::point_iterator(const point &value, uint8_t offset)\n    : point_(value), offset_(offset)\n{\n}\n\npoint_iterator::operator bool() const\n{\n    return (offset_ < max_offset);\n}\n\npoint_iterator::reference point_iterator::operator*() const\n{\n    if (offset_ < hash_size)\n        return point_.hash[offset_];\n\n    // TODO: optimize by indexing directly into point_.index bytes.\n    if (offset_ - hash_size < sizeof(uint32_t))\n        return to_little_endian(point_.index)[offset_ - hash_size];\n\n    return 0;\n}\n\npoint_iterator::pointer point_iterator::operator->() const\n{\n    if (offset_ < hash_size)\n        return point_.hash[offset_];\n\n    // TODO: optimize by indexing directly into point_.index bytes.\n    if (offset_ - hash_size < sizeof(uint32_t))\n        return to_little_endian(point_.index)[offset_ - hash_size];\n\n    return 0;\n}\n\nbool point_iterator::operator==(const iterator &other) const\n{\n    return (point_ == other.point_) && (offset_ == other.offset_);\n}\n\nbool point_iterator::operator!=(const iterator &other) const\n{\n    return !(*this == other);\n}\n\npoint_iterator::iterator &point_iterator::operator++()\n{\n    increment();\n    return *this;\n}\n\npoint_iterator::iterator point_iterator::operator++(int)\n{\n    auto it = *this;\n    increment();\n    return it;\n}\n\npoint_iterator::iterator &point_iterator::operator--()\n{\n    decrement();\n    return *this;\n}\n\npoint_iterator::iterator point_iterator::operator--(int)\n{\n    auto it = *this;\n    decrement();\n    return it;\n}\n\nvoid point_iterator::increment()\n{\n    if (offset_ < max_offset)\n        offset_++;\n}\n\nvoid point_iterator::decrement()\n{\n    if (offset_ > 0)\n        offset_--;\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/chain/script/conditional_stack.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include \"conditional_stack.hpp\"\n\n#include <algorithm>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nbool conditional_stack::closed() const\n{\n    return stack_.empty();\n}\n\nbool conditional_stack::succeeded() const\n{\n    return std::count(stack_.begin(), stack_.end(), false) == 0;\n}\n\nvoid conditional_stack::clear()\n{\n    stack_.clear();\n}\n\nvoid conditional_stack::open(bool value)\n{\n    stack_.push_back(value);\n}\n\nvoid conditional_stack::else_()\n{\n    stack_.back() = !stack_.back();\n}\n\nvoid conditional_stack::close()\n{\n    stack_.pop_back();\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/chain/script/conditional_stack.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_CONDITIONAL_STACK_HPP\n#define UC_CHAIN_CONDITIONAL_STACK_HPP\n\n#include <vector>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nclass conditional_stack\n{\n  public:\n    bool closed() const;\n    bool succeeded() const;\n    void clear();\n    void open(bool value);\n    void else_();\n    void close();\n\n  private:\n    std::vector<bool> stack_;\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "src/UChain/coin/chain/script/evaluation_context.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include \"evaluation_context.hpp\"\n\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\ndata_chunk evaluation_context::pop_stack()\n{\n    const auto value = stack.back();\n    stack.pop_back();\n    return value;\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/chain/script/evaluation_context.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_CHAIN_EVALUATION_CONTEXT_HPP\n#define UC_CHAIN_EVALUATION_CONTEXT_HPP\n\n#include <algorithm>\n#include <cstdint>\n#include <UChain/coin/chain/script/operation.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include \"conditional_stack.hpp\"\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nclass evaluation_context\n{\n  public:\n    data_chunk pop_stack();\n\n    operation::stack::const_iterator code_begin;\n    uint64_t operation_counter;\n    data_stack stack;\n    data_stack alternate;\n    conditional_stack conditional;\n    uint32_t flags;\n};\n\n} // namespace chain\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "src/UChain/coin/chain/script/opcode.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/chain/script/opcode.hpp>\n\n#include <sstream>\n#include <UChain/coin/constants.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nstd::string opcode_to_string(opcode value, uint32_t flags)\n{\n    switch (value)\n    {\n    case opcode::zero:\n        return \"zero\";\n    case opcode::special:\n        return \"special\";\n    case opcode::pushdata1:\n        return \"pushdata1\";\n    case opcode::pushdata2:\n        return \"pushdata2\";\n    case opcode::pushdata4:\n        return \"pushdata4\";\n    case opcode::negative_1:\n        return \"-1\";\n    case opcode::reserved:\n        return \"reserved\";\n    case opcode::op_1:\n        return \"1\";\n    case opcode::op_2:\n        return \"2\";\n    case opcode::op_3:\n        return \"3\";\n    case opcode::op_4:\n        return \"4\";\n    case opcode::op_5:\n        return \"5\";\n    case opcode::op_6:\n        return \"6\";\n    case opcode::op_7:\n        return \"7\";\n    case opcode::op_8:\n        return \"8\";\n    case opcode::op_9:\n        return \"9\";\n    case opcode::op_10:\n        return \"10\";\n    case opcode::op_11:\n        return \"11\";\n    case opcode::op_12:\n        return \"12\";\n    case opcode::op_13:\n        return \"13\";\n    case opcode::op_14:\n        return \"14\";\n    case opcode::op_15:\n        return \"15\";\n    case opcode::op_16:\n        return \"16\";\n    case opcode::nop:\n        return \"nop\";\n    case opcode::ver:\n        return \"ver\";\n    case opcode::if_:\n        return \"if\";\n    case opcode::notif:\n        return \"notif\";\n    case opcode::verif:\n        return \"verif\";\n    case opcode::vernotif:\n        return \"vernotif\";\n    case opcode::else_:\n        return \"else\";\n    case opcode::endif:\n        return \"endif\";\n    case opcode::verify:\n        return \"verify\";\n    case opcode::return_:\n        return \"return\";\n    case opcode::toaltstack:\n        return \"toaltstack\";\n    case opcode::fromaltstack:\n        return \"fromaltstack\";\n    case opcode::op_2drop:\n        return \"2drop\";\n    case opcode::op_2dup:\n        return \"2dup\";\n    case opcode::op_3dup:\n        return \"3dup\";\n    case opcode::op_2over:\n        return \"2over\";\n    case opcode::op_2rot:\n        return \"2rot\";\n    case opcode::op_2swap:\n        return \"2swap\";\n    case opcode::ifdup:\n        return \"ifdup\";\n    case opcode::depth:\n        return \"depth\";\n    case opcode::drop:\n        return \"drop\";\n    case opcode::dup:\n        return \"dup\";\n    case opcode::nip:\n        return \"nip\";\n    case opcode::over:\n        return \"over\";\n    case opcode::pick:\n        return \"pick\";\n    case opcode::roll:\n        return \"roll\";\n    case opcode::rot:\n        return \"rot\";\n    case opcode::swap:\n        return \"swap\";\n    case opcode::tuck:\n        return \"tuck\";\n    case opcode::cat:\n        return \"cat\";\n    case opcode::substr:\n        return \"substr\";\n    case opcode::left:\n        return \"left\";\n    case opcode::right:\n        return \"right\";\n    case opcode::size:\n        return \"size\";\n    case opcode::invert:\n        return \"invert\";\n    case opcode::and_:\n        return \"and\";\n    case opcode::or_:\n        return \"or\";\n    case opcode::xor_:\n        return \"xor\";\n    case opcode::equal:\n        return \"equal\";\n    case opcode::equalverify:\n        return \"equalverify\";\n    case opcode::reserved1:\n        return \"reserved1\";\n    case opcode::reserved2:\n        return \"reserved2\";\n    case opcode::op_1add:\n        return \"1add\";\n    case opcode::op_1sub:\n        return \"1sub\";\n    case opcode::op_2mul:\n        return \"2mul\";\n    case opcode::op_2div:\n        return \"2div\";\n    case opcode::negate:\n        return \"negate\";\n    case opcode::abs:\n        return \"abs\";\n    case opcode::not_:\n        return \"not\";\n    case opcode::op_0notequal:\n        return \"0notequal\";\n    case opcode::add:\n        return \"add\";\n    case opcode::sub:\n        return \"sub\";\n    case opcode::mul:\n        return \"mul\";\n    case opcode::div:\n        return \"div\";\n    case opcode::mod:\n        return \"mod\";\n    case opcode::lshift:\n        return \"lshift\";\n    case opcode::rshift:\n        return \"rshift\";\n    case opcode::booland:\n        return \"booland\";\n    case opcode::boolor:\n        return \"boolor\";\n    case opcode::numequal:\n        return \"numequal\";\n    case opcode::numequalverify:\n        return \"numequalverify\";\n    case opcode::numnotequal:\n        return \"numnotequal\";\n    case opcode::lessthan:\n        return \"lessthan\";\n    case opcode::greaterthan:\n        return \"greaterthan\";\n    case opcode::lessthanorequal:\n        return \"lessthanorequal\";\n    case opcode::greaterthanorequal:\n        return \"greaterthanorequal\";\n    case opcode::min:\n        return \"min\";\n    case opcode::max:\n        return \"max\";\n    case opcode::within:\n        return \"within\";\n    case opcode::ripemd160:\n        return \"ripemd160\";\n    case opcode::sha1:\n        return \"sha1\";\n    case opcode::sha256:\n        return \"sha256\";\n    case opcode::hash160:\n        return \"hash160\";\n    case opcode::hash256:\n        return \"hash256\";\n    case opcode::codeseparator:\n        return \"codeseparator\";\n    case opcode::checksig:\n        return \"checksig\";\n    case opcode::checksigverify:\n        return \"checksigverify\";\n    case opcode::checkmultisig:\n        return \"checkmultisig\";\n    case opcode::checkmultisigverify:\n        return \"checkmultisigverify\";\n    case opcode::checklocktimeverify:\n        return \"checklocktimeverify\";\n    case opcode::checkattenuationverify:\n        return \"checkattenuationverify\";\n    case opcode::op_nop1:\n        return \"nop1\";\n    case opcode::op_nop4:\n        return \"nop4\";\n    case opcode::op_nop5:\n        return \"nop5\";\n    case opcode::op_nop6:\n        return \"nop6\";\n    case opcode::op_nop7:\n        return \"nop7\";\n    case opcode::op_nop8:\n        return \"nop8\";\n    case opcode::op_nop9:\n        return \"nop9\";\n    case opcode::op_nop10:\n        return \"nop10\";\n    case opcode::raw_data:\n        return \"raw_data\";\n    default:\n    {\n        std::ostringstream ss;\n        ss << \"<none \" << static_cast<int>(value) << \">\";\n        return ss.str();\n    }\n    }\n}\n\nopcode string_to_opcode(const std::string &value)\n{\n    if (value == \"zero\")\n        return opcode::zero;\n    else if (value == \"special\")\n        return opcode::special;\n    else if (value == \"pushdata1\")\n        return opcode::pushdata1;\n    else if (value == \"pushdata2\")\n        return opcode::pushdata2;\n    else if (value == \"pushdata4\")\n        return opcode::pushdata4;\n    else if (value == \"-1\")\n        return opcode::negative_1;\n    else if (value == \"reserved\")\n        return opcode::reserved;\n    else if (value == \"1\")\n        return opcode::op_1;\n    else if (value == \"2\")\n        return opcode::op_2;\n    else if (value == \"3\")\n        return opcode::op_3;\n    else if (value == \"4\")\n        return opcode::op_4;\n    else if (value == \"5\")\n        return opcode::op_5;\n    else if (value == \"6\")\n        return opcode::op_6;\n    else if (value == \"7\")\n        return opcode::op_7;\n    else if (value == \"8\")\n        return opcode::op_8;\n    else if (value == \"9\")\n        return opcode::op_9;\n    else if (value == \"10\")\n        return opcode::op_10;\n    else if (value == \"11\")\n        return opcode::op_11;\n    else if (value == \"12\")\n        return opcode::op_12;\n    else if (value == \"13\")\n        return opcode::op_13;\n    else if (value == \"14\")\n        return opcode::op_14;\n    else if (value == \"15\")\n        return opcode::op_15;\n    else if (value == \"16\")\n        return opcode::op_16;\n    else if (value == \"nop\")\n        return opcode::nop;\n    else if (value == \"ver\")\n        return opcode::ver;\n    else if (value == \"if\")\n        return opcode::if_;\n    else if (value == \"notif\")\n        return opcode::notif;\n    else if (value == \"verif\")\n        return opcode::verif;\n    else if (value == \"vernotif\")\n        return opcode::vernotif;\n    else if (value == \"else\")\n        return opcode::else_;\n    else if (value == \"endif\")\n        return opcode::endif;\n    else if (value == \"verify\")\n        return opcode::verify;\n    else if (value == \"return\")\n        return opcode::return_;\n    else if (value == \"toaltstack\")\n        return opcode::toaltstack;\n    else if (value == \"fromaltstack\")\n        return opcode::fromaltstack;\n    else if (value == \"2drop\")\n        return opcode::op_2drop;\n    else if (value == \"2dup\")\n        return opcode::op_2dup;\n    else if (value == \"3dup\")\n        return opcode::op_3dup;\n    else if (value == \"2over\")\n        return opcode::op_2over;\n    else if (value == \"2rot\")\n        return opcode::op_2rot;\n    else if (value == \"2swap\")\n        return opcode::op_2swap;\n    else if (value == \"ifdup\")\n        return opcode::ifdup;\n    else if (value == \"depth\")\n        return opcode::depth;\n    else if (value == \"drop\")\n        return opcode::drop;\n    else if (value == \"dup\")\n        return opcode::dup;\n    else if (value == \"nip\")\n        return opcode::nip;\n    else if (value == \"over\")\n        return opcode::over;\n    else if (value == \"pick\")\n        return opcode::pick;\n    else if (value == \"roll\")\n        return opcode::roll;\n    else if (value == \"rot\")\n        return opcode::rot;\n    else if (value == \"swap\")\n        return opcode::swap;\n    else if (value == \"tuck\")\n        return opcode::tuck;\n    else if (value == \"cat\")\n        return opcode::cat;\n    else if (value == \"substr\")\n        return opcode::substr;\n    else if (value == \"left\")\n        return opcode::left;\n    else if (value == \"right\")\n        return opcode::right;\n    else if (value == \"size\")\n        return opcode::size;\n    else if (value == \"invert\")\n        return opcode::invert;\n    else if (value == \"and\")\n        return opcode::and_;\n    else if (value == \"or\")\n        return opcode::or_;\n    else if (value == \"xor\")\n        return opcode::xor_;\n    else if (value == \"equal\")\n        return opcode::equal;\n    else if (value == \"equalverify\")\n        return opcode::equalverify;\n    else if (value == \"reserved1\")\n        return opcode::reserved1;\n    else if (value == \"reserved2\")\n        return opcode::reserved2;\n    else if (value == \"1add\")\n        return opcode::op_1add;\n    else if (value == \"1sub\")\n        return opcode::op_1sub;\n    else if (value == \"2mul\")\n        return opcode::op_2mul;\n    else if (value == \"2div\")\n        return opcode::op_2div;\n    else if (value == \"negate\")\n        return opcode::negate;\n    else if (value == \"abs\")\n        return opcode::abs;\n    else if (value == \"not\")\n        return opcode::not_;\n    else if (value == \"0notequal\")\n        return opcode::op_0notequal;\n    else if (value == \"add\")\n        return opcode::add;\n    else if (value == \"sub\")\n        return opcode::sub;\n    else if (value == \"mul\")\n        return opcode::mul;\n    else if (value == \"div\")\n        return opcode::div;\n    else if (value == \"mod\")\n        return opcode::mod;\n    else if (value == \"lshift\")\n        return opcode::lshift;\n    else if (value == \"rshift\")\n        return opcode::rshift;\n    else if (value == \"booland\")\n        return opcode::booland;\n    else if (value == \"boolor\")\n        return opcode::boolor;\n    else if (value == \"numequal\")\n        return opcode::numequal;\n    else if (value == \"numequalverify\")\n        return opcode::numequalverify;\n    else if (value == \"numnotequal\")\n        return opcode::numnotequal;\n    else if (value == \"lessthan\")\n        return opcode::lessthan;\n    else if (value == \"greaterthan\")\n        return opcode::greaterthan;\n    else if (value == \"lessthanorequal\")\n        return opcode::lessthanorequal;\n    else if (value == \"greaterthanorequal\")\n        return opcode::greaterthanorequal;\n    else if (value == \"min\")\n        return opcode::min;\n    else if (value == \"max\")\n        return opcode::max;\n    else if (value == \"within\")\n        return opcode::within;\n    else if (value == \"ripemd160\")\n        return opcode::ripemd160;\n    else if (value == \"sha1\")\n        return opcode::sha1;\n    else if (value == \"sha256\")\n        return opcode::sha256;\n    else if (value == \"hash160\")\n        return opcode::hash160;\n    else if (value == \"hash256\")\n        return opcode::hash256;\n    else if (value == \"codeseparator\")\n        return opcode::codeseparator;\n    else if (value == \"checksig\")\n        return opcode::checksig;\n    else if (value == \"checksigverify\")\n        return opcode::checksigverify;\n    else if (value == \"checkmultisig\")\n        return opcode::checkmultisig;\n    else if (value == \"checkmultisigverify\")\n        return opcode::checkmultisigverify;\n    // Replaces nop2 with BIP65 activation.\n    else if (value == \"nop2\" || value == \"checklocktimeverify\")\n        return opcode::checklocktimeverify;\n    // Replaces nop3 with attenuation, see MIP7 and MIP8.\n    else if (value == \"nop3\" || value == \"checkattenuationverify\")\n        return opcode::checkattenuationverify;\n    else if (value == \"nop1\")\n        return opcode::op_nop1;\n    else if (value == \"nop4\")\n        return opcode::op_nop4;\n    else if (value == \"nop5\")\n        return opcode::op_nop5;\n    else if (value == \"nop6\")\n        return opcode::op_nop6;\n    else if (value == \"nop7\")\n        return opcode::op_nop7;\n    else if (value == \"nop8\")\n        return opcode::op_nop8;\n    else if (value == \"nop9\")\n        return opcode::op_nop9;\n    else if (value == \"nop10\")\n        return opcode::op_nop10;\n    else if (value == \"raw_data\")\n        return opcode::raw_data;\n    // ERROR: unknown...\n    return opcode::bad_operation;\n}\n\nopcode data_to_opcode(const data_chunk &value)\n{\n    static constexpr size_t limit = 76;\n    opcode code;\n    if (value.size() < limit)\n        code = opcode::special;\n    else if (value.size() < max_uint8)\n        code = opcode::pushdata1;\n    else if (value.size() < max_uint16)\n        code = opcode::pushdata2;\n    else if (value.size() < max_uint32)\n        code = opcode::pushdata4;\n    else\n        code = opcode::bad_operation;\n    return code;\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/chain/script/operation.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <script/script.h>\n#include <UChain/coin/chain/script/operation.hpp>\n#include <algorithm>\n#include <sstream>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/chain/script/script.hpp>\n#include <UChain/coin/chain/point.hpp>\n#include <UChain/coin/formats/base_16.hpp>\n#include <UChain/coin/math/elliptic_curve.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nconst size_t operation::max_null_data_size = 80;\n\noperation operation::factory_from_data(const data_chunk &data)\n{\n    operation instance;\n    instance.from_data(data);\n    return instance;\n}\n\noperation operation::factory_from_data(std::istream &stream)\n{\n    operation instance;\n    instance.from_data(stream);\n    return instance;\n}\n\noperation operation::factory_from_data(reader &source)\n{\n    operation instance;\n    instance.from_data(source);\n    return instance;\n}\n\nbool operation::is_valid() const\n{\n    return (code == opcode::zero) && data.empty();\n}\n\nvoid operation::reset()\n{\n    code = opcode::zero;\n    data.clear();\n}\n\nbool operation::from_data(const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(istream);\n}\n\nbool operation::from_data(std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(source);\n}\n\nbool operation::from_data(reader &source)\n{\n    reset();\n\n    const auto byte = source.read_byte();\n    auto result = static_cast<bool>(source);\n    auto op_code = static_cast<opcode>(byte);\n\n    if (byte == 0 && op_code != opcode::zero)\n        return false;\n\n    code = ((0 < byte && byte <= 75) ? opcode::special : op_code);\n\n    if (operation::must_read_data(code))\n    {\n        uint32_t size = 0u;\n        read_opcode_data_size(size, code, byte, source);\n        data = source.read_data(size);\n        result = (source && (data.size() == size));\n    }\n\n    if (!result)\n        reset();\n\n    return result;\n}\n\ndata_chunk operation::to_data() const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size());\n    return data;\n}\n\nvoid operation::to_data(std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(sink);\n}\n\nvoid operation::to_data(writer &sink) const\n{\n    if (code != opcode::raw_data)\n    {\n        auto raw_byte = static_cast<uint8_t>(code);\n        if (code == opcode::special)\n            raw_byte = static_cast<uint8_t>(data.size());\n\n        sink.write_byte(raw_byte);\n\n        switch (code)\n        {\n        case opcode::pushdata1:\n            sink.write_byte(static_cast<uint8_t>(data.size()));\n            break;\n\n        case opcode::pushdata2:\n            sink.write_2_bytes_little_endian(\n                static_cast<uint16_t>(data.size()));\n            break;\n\n        case opcode::pushdata4:\n            sink.write_4_bytes_little_endian(\n                static_cast<uint32_t>(data.size()));\n            break;\n\n        default:\n            break;\n        }\n    }\n\n    sink.write_data(data);\n}\n\nuint64_t operation::serialized_size() const\n{\n    uint64_t size = 1 + data.size();\n\n    switch (code)\n    {\n    case opcode::pushdata1:\n        size += sizeof(uint8_t);\n        break;\n\n    case opcode::pushdata2:\n        size += sizeof(uint16_t);\n        break;\n\n    case opcode::pushdata4:\n        size += sizeof(uint32_t);\n        break;\n\n    case opcode::raw_data:\n        // remove padding for raw_data\n        size -= 1;\n        break;\n\n    default:\n        break;\n    }\n\n    return size;\n}\n\nstd::string operation::to_string(uint32_t flags) const\n{\n    std::ostringstream ss;\n\n    if (data.empty())\n        ss << opcode_to_string(code, flags);\n    else\n        ss << \"[ \" << encode_base16(data) << \" ]\";\n\n    return ss.str();\n}\n\nbool operation::read_opcode_data_size(uint32_t &count, opcode code,\n                                      uint8_t raw_byte, reader &source)\n{\n    switch (code)\n    {\n    case opcode::special:\n        count = raw_byte;\n        return true;\n    case opcode::pushdata1:\n        count = source.read_byte();\n        return true;\n    case opcode::pushdata2:\n        count = source.read_2_bytes_little_endian();\n        return true;\n    case opcode::pushdata4:\n        count = source.read_4_bytes_little_endian();\n        return true;\n    default:\n        return false;\n    }\n}\n\nuint64_t operation::count_non_push(const operation::stack &ops)\n{\n    const auto found = [](const operation &op) {\n        return !is_push(op.code);\n    };\n\n    return std::count_if(ops.begin(), ops.end(), found);\n}\n\nbool operation::must_read_data(opcode code)\n{\n    return code == opcode::special || code == opcode::pushdata1 || code == opcode::pushdata2 || code == opcode::pushdata4;\n}\n\nbool operation::is_push(const opcode code)\n{\n    return code == opcode::zero || code == opcode::special || code == opcode::pushdata1 || code == opcode::pushdata2 || code == opcode::pushdata4 || code == opcode::negative_1 || code == opcode::op_1 || code == opcode::op_2 || code == opcode::op_3 || code == opcode::op_4 || code == opcode::op_5 || code == opcode::op_6 || code == opcode::op_7 || code == opcode::op_8 || code == opcode::op_9 || code == opcode::op_10 || code == opcode::op_11 || code == opcode::op_12 || code == opcode::op_13 || code == opcode::op_14 || code == opcode::op_15 || code == opcode::op_16;\n}\n\nbool operation::is_push_only(const operation::stack &ops)\n{\n    return count_non_push(ops) == 0;\n}\n\n// pattern comparisons\n// ----------------------------------------------------------------------------\n\nbool operation::is_null_data_pattern(const operation::stack &ops)\n{\n    return ops.size() == 2 && ops[0].code == opcode::return_ && ops[1].code == opcode::special && ops[1].data.size() <= max_null_data_size;\n}\n\nbool operation::is_pay_multisig_pattern(const operation::stack &ops)\n{\n    static constexpr size_t op_1 = static_cast<uint8_t>(opcode::op_1);\n    static constexpr size_t op_16 = static_cast<uint8_t>(opcode::op_16);\n\n    const auto op_count = ops.size();\n\n    if (op_count < 4 || ops[op_count - 1].code != opcode::checkmultisig)\n        return false;\n\n    const auto op_m = static_cast<uint8_t>(ops[0].code);\n    const auto op_n = static_cast<uint8_t>(ops[op_count - 2].code);\n\n    if (op_m < op_1 || op_m > op_n || op_n < op_1 || op_n > op_16)\n        return false;\n\n    //const auto n = op_n - op_1;\n    const auto n = op_n - op_1 + 1u;\n    const auto points = op_count - 3u;\n\n    if (n != points)\n        return false;\n\n    for (auto op = ops.begin() + 1; op != ops.end() - 2; ++op)\n        if (!is_public_key(op->data))\n            return false;\n\n    return true;\n}\n\nbool operation::is_pay_public_key_pattern(const operation::stack &ops)\n{\n    return ops.size() == 2 && ops[0].code == opcode::special && is_public_key(ops[0].data) && ops[1].code == opcode::checksig;\n}\n\nbool operation::is_pay_key_hash_pattern(const operation::stack &ops)\n{\n    return ops.size() == 5 && ops[0].code == opcode::dup && ops[1].code == opcode::hash160 && ops[2].code == opcode::special && ops[2].data.size() == short_hash_size && ops[3].code == opcode::equalverify && ops[4].code == opcode::checksig;\n}\n\nbool operation::is_pay_key_hash_with_lock_height_pattern(const operation::stack &ops)\n{\n    return ops.size() == 7 && ops[0].code == opcode::special && ops[1].code == opcode::numequalverify && ops[2].code == opcode::dup && ops[3].code == opcode::hash160 && ops[4].code == opcode::special && ops[4].data.size() == short_hash_size && ops[5].code == opcode::equalverify && ops[6].code == opcode::checksig;\n}\n\nbool operation::is_pay_script_hash_pattern(const operation::stack &ops)\n{\n    return ops.size() == 3 && ops[0].code == opcode::hash160 && ops[1].code == opcode::special && ops[1].data.size() == short_hash_size && ops[2].code == opcode::equal;\n}\n\nbool operation::is_pay_blackhole_pattern(const operation::stack &ops)\n{\n    return ops.size() == 1 && ops[0].code == opcode::return_;\n}\n\nbool operation::is_pay_key_hash_with_attenuation_model_pattern(const operation::stack &ops)\n{\n    return ops.size() == 8 && ops[0].code == opcode::pushdata2 // model param\n           && ops[1].code == opcode::special                   // input point\n           && ops[2].code == opcode::checkattenuationverify && ops[3].code == opcode::dup && ops[4].code == opcode::hash160 && ops[5].code == opcode::special && ops[5].data.size() == short_hash_size && ops[6].code == opcode::equalverify && ops[7].code == opcode::checksig;\n}\n\nbool operation::is_sign_multisig_pattern(const operation::stack &ops)\n{\n    if (ops.size() < 2 || !is_push_only(ops))\n        return false;\n\n    if (ops.front().code != opcode::zero)\n        return false;\n\n    return true;\n}\n\nbool operation::is_sign_public_key_pattern(const operation::stack &ops)\n{\n    return ops.size() == 1 && is_push_only(ops);\n}\n\nbool operation::is_sign_key_hash_pattern(const operation::stack &ops)\n{\n    return ops.size() == 2 && is_push_only(ops) &&\n           is_public_key(ops.back().data);\n}\n\nuint64_t operation::get_lock_height_from_sign_key_hash_with_lock_height(const operation::stack &ops)\n{\n    CScriptNum num(ops[2].data, 1);\n    return num.getint();\n}\n\nuint64_t operation::get_lock_height_from_pay_key_hash_with_lock_height(const operation::stack &ops)\n{\n    CScriptNum num(ops[0].data, 1);\n    return num.getint();\n}\n\nbool operation::is_sign_key_hash_with_lock_height_pattern(const operation::stack &ops)\n{\n    return ops.size() == 3 && is_push_only(ops) &&\n           is_public_key((ops.begin() + 1)->data);\n}\n\nbool operation::is_sign_script_hash_pattern(const operation::stack &ops)\n{\n    if (ops.size() < 2 || !is_push_only(ops))\n        return false;\n\n    const auto &redeem_data = ops.back().data;\n\n    if (redeem_data.empty())\n        return false;\n\n    script redeem_script;\n\n    if (!redeem_script.from_data(redeem_data, false, script::parse_mode::strict))\n        return false;\n\n    // Is the redeem script a standard pay (output) script?\n    const auto redeem_script_pattern = redeem_script.pattern();\n    return redeem_script_pattern == script_pattern::pay_multisig || redeem_script_pattern == script_pattern::pay_public_key || redeem_script_pattern == script_pattern::pay_key_hash || redeem_script_pattern == script_pattern::pay_script_hash || redeem_script_pattern == script_pattern::null_data;\n}\n\nconst data_chunk &operation::get_model_param_from_pay_key_hash_with_attenuation_model(const operation::stack &ops)\n{\n    return ops[0].data;\n}\n\nconst data_chunk &operation::get_input_point_from_pay_key_hash_with_attenuation_model(const operation::stack &ops)\n{\n    return ops[1].data;\n}\n\n// pattern templates\n// ----------------------------------------------------------------------------\n\noperation::stack operation::to_null_data_pattern(data_slice data)\n{\n    if (data.size() > max_null_data_size)\n        return {};\n\n    return operation::stack{\n        {opcode::return_, {}},\n        {opcode::special, to_chunk(data)}};\n}\n\noperation::stack operation::to_pay_public_key_pattern(data_slice point)\n{\n    if (!is_public_key(point))\n        return {};\n\n    return operation::stack{\n        {opcode::special, to_chunk(point)},\n        {opcode::checksig, {}}};\n}\n\noperation::stack operation::to_pay_multisig_pattern(uint8_t signatures,\n                                                    const point_list &points)\n{\n    const auto conversion = [](const ec_compressed &point) {\n        return to_chunk(point);\n    };\n\n    data_stack chunks(points.size());\n    std::transform(points.begin(), points.end(), chunks.begin(), conversion);\n    return to_pay_multisig_pattern(signatures, chunks);\n}\n\noperation::stack operation::to_pay_multisig_pattern(uint8_t signatures,\n                                                    const data_stack &points)\n{\n    static constexpr size_t op_1 = static_cast<uint8_t>(opcode::op_1);\n    static constexpr size_t op_16 = static_cast<uint8_t>(opcode::op_16);\n    static constexpr size_t zero = op_1 - 1;\n    static constexpr size_t max = op_16 - zero;\n\n    const auto m = signatures;\n    const auto n = points.size();\n\n    if (m < 1 || m > n || n < 1 || n > max)\n        return operation::stack();\n\n    const auto op_m = static_cast<opcode>(m + zero);\n    const auto op_n = static_cast<opcode>(points.size() + zero);\n\n    operation::stack ops(points.size() + 3);\n    ops.push_back({op_m, {}});\n\n    for (const auto point : points)\n    {\n        if (!is_public_key(point))\n            return {};\n\n        ops.push_back({opcode::special, point});\n    }\n\n    ops.push_back({op_n, {}});\n    ops.push_back({opcode::checkmultisig, {}});\n    return ops;\n}\n\noperation::stack operation::to_pay_key_hash_pattern(const short_hash &hash)\n{\n    return operation::stack{\n        {opcode::dup, {}},\n        {opcode::hash160, {}},\n        {opcode::special, to_chunk(hash)},\n        {opcode::equalverify, {}},\n        {opcode::checksig, {}}};\n}\n\noperation::stack operation::to_pay_key_hash_with_lock_height_pattern(const short_hash &hash, uint32_t block_height)\n{\n    return operation::stack{\n        {opcode::special, CScriptNum::serialize(block_height)},\n        {opcode::numequalverify, {}},\n        {opcode::dup, {}},\n        {opcode::hash160, {}},\n        {opcode::special, to_chunk(hash)},\n        {opcode::equalverify, {}},\n        {opcode::checksig, {}}};\n}\n\noperation::stack operation::to_pay_script_hash_pattern(const short_hash &hash)\n{\n    return operation::stack{\n        {opcode::hash160, {}},\n        {opcode::special, to_chunk(hash)},\n        {opcode::equal, {}}};\n}\n\noperation::stack operation::to_pay_blackhole_pattern(const short_hash &)\n{\n    return operation::stack{\n        {opcode::return_, {}}};\n}\n\noperation::stack operation::to_pay_key_hash_with_attenuation_model_pattern(\n    const short_hash &hash, const std::string &model_param, const point &input_point)\n{\n    return operation::stack{\n        {opcode::pushdata2, to_chunk(model_param)},\n        {opcode::special, input_point.to_data()},\n        {opcode::checkattenuationverify, {}},\n        {opcode::dup, {}},\n        {opcode::hash160, {}},\n        {opcode::special, to_chunk(hash)},\n        {opcode::equalverify, {}},\n        {opcode::checksig, {}}};\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/chain/script/script.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/chain/script/script.hpp>\n\n#include <numeric>\n#include <sstream>\n#include <boost/algorithm/string.hpp>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/constants.hpp>\n#include <UChain/coin/chain/script/operation.hpp>\n#include <UChain/coin/chain/transaction.hpp>\n#include <UChainService/txs/token/attenuation_model.hpp>\n#include <UChain/coin/formats/base_16.hpp>\n#include <UChain/coin/math/elliptic_curve.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/math/script_number.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n#include <UChain/coin/utility/string.hpp>\n#include <UChain/coin/utility/variable_uint_size.hpp>\n#include \"conditional_stack.hpp\"\n#include \"evaluation_context.hpp\"\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\n// False is an empty stack.\nstatic const data_chunk stack_false_value;\nstatic const data_chunk stack_true_value{1};\nstatic constexpr uint64_t op_counter_limit = 201;\n\nenum class signature_parse_result\n{\n    valid,\n    invalid,\n    lax_encoding\n};\n\nscript script::factory_from_data(const data_chunk &data, bool prefix,\n                                 parse_mode mode)\n{\n    script instance;\n    instance.from_data(data, prefix, mode);\n    return instance;\n}\n\nscript script::factory_from_data(std::istream &stream, bool prefix,\n                                 parse_mode mode)\n{\n    script instance;\n    instance.from_data(stream, prefix, mode);\n    return instance;\n}\n\nscript script::factory_from_data(reader &source, bool prefix, parse_mode mode)\n{\n    script instance;\n    instance.from_data(source, prefix, mode);\n    return instance;\n}\n\nscript_pattern script::pattern() const\n{\n    if (operation::is_null_data_pattern(operations))\n        return script_pattern::null_data;\n\n    if (operation::is_pay_multisig_pattern(operations))\n        return script_pattern::pay_multisig;\n\n    if (operation::is_pay_public_key_pattern(operations))\n        return script_pattern::pay_public_key;\n\n    if (operation::is_pay_key_hash_pattern(operations))\n        return script_pattern::pay_key_hash;\n\n    if (operation::is_pay_key_hash_with_lock_height_pattern(operations))\n        return script_pattern::pay_key_hash_with_lock_height;\n\n    if (operation::is_pay_script_hash_pattern(operations))\n        return script_pattern::pay_script_hash;\n\n    if (operation::is_sign_multisig_pattern(operations))\n        return script_pattern::sign_multisig;\n\n    if (operation::is_sign_public_key_pattern(operations))\n        return script_pattern::sign_public_key;\n\n    if (operation::is_sign_key_hash_pattern(operations))\n        return script_pattern::sign_key_hash;\n\n    if (operation::is_sign_key_hash_with_lock_height_pattern(operations))\n        return script_pattern::sign_key_hash_with_lock_height;\n\n    if (operation::is_sign_script_hash_pattern(operations))\n        return script_pattern::sign_script_hash;\n\n    if (operation::is_pay_blackhole_pattern(operations))\n        return script_pattern::pay_blackhole_address;\n\n    if (operation::is_pay_key_hash_with_attenuation_model_pattern(operations))\n        return script_pattern::pay_key_hash_with_attenuation_model;\n\n    return script_pattern::non_standard;\n}\n\nbool script::is_raw_data() const\n{\n    return (operations.size() == 1) &&\n           (operations[0].code == opcode::raw_data);\n}\n\nbool script::is_valid() const\n{\n    return !operations.empty();\n}\n\nvoid script::reset()\n{\n    operations.clear();\n}\n\nbool script::from_data(const data_chunk &data, bool prefix, parse_mode mode)\n{\n    auto result = true;\n\n    if (prefix)\n    {\n        data_source istream(data);\n        result = from_data(istream, true, mode);\n    }\n    else\n    {\n        reset();\n        result = deserialize(data, mode);\n\n        if (!result)\n            reset();\n    }\n\n    return result;\n}\n\nbool script::from_data(std::istream &stream, bool prefix, parse_mode mode)\n{\n    istream_reader source(stream);\n    return from_data(source, prefix, mode);\n}\n\nbool script::from_data(reader &source, bool prefix, parse_mode mode)\n{\n    reset();\n\n    auto result = true;\n    data_chunk raw_script;\n\n    if (prefix)\n    {\n        const auto script_length = source.read_variable_uint_little_endian();\n        result = source;\n        BITCOIN_ASSERT(script_length <= max_uint32);\n\n        if (result)\n        {\n            auto script_length32 = static_cast<uint32_t>(script_length);\n            raw_script = source.read_data(script_length32);\n            result = source && (raw_script.size() == script_length32);\n        }\n    }\n    else\n    {\n        raw_script = source.read_data_to_eof();\n        result = source;\n    }\n\n    if (result)\n        result = deserialize(raw_script, mode);\n\n    if (!result)\n        reset();\n\n    return result;\n}\n\ndata_chunk script::to_data(bool prefix) const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream, prefix);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(prefix));\n    return data;\n}\n\nvoid script::to_data(std::ostream &stream, bool prefix) const\n{\n    ostream_writer sink(stream);\n    to_data(sink, prefix);\n}\n\nvoid script::to_data(writer &sink, bool prefix) const\n{\n    if (prefix)\n        sink.write_variable_uint_little_endian(satoshi_content_size());\n\n    if ((operations.size() > 0) && (operations[0].code == opcode::raw_data))\n        operations[0].to_data(sink);\n    else\n        for (const auto &op : operations)\n            op.to_data(sink);\n}\n\nuint64_t script::satoshi_content_size() const\n{\n    if (operations.size() > 0 && (operations[0].code == opcode::raw_data))\n    {\n        return operations[0].serialized_size();\n    }\n\n    const auto value = [](uint64_t total, const operation &op) {\n        return total + op.serialized_size();\n    };\n\n    return std::accumulate(operations.begin(), operations.end(), uint64_t(0),\n                           value);\n}\n\nuint64_t script::serialized_size(bool prefix) const\n{\n    auto size = satoshi_content_size();\n\n    if (prefix)\n        size += variable_uint_size(size);\n\n    return size;\n}\n\nbool script::from_string(const std::string &human_readable)\n{\n    // clear current contents\n    operations.clear();\n    const auto tokens = split(human_readable);\n    auto clear = false;\n\n    for (auto token = tokens.begin(); token != tokens.end(); ++token)\n    {\n        opcode code;\n        data_chunk data;\n\n        if (*token == \"[\")\n        {\n            data_chunk raw_data;\n            if (!decode_base16(raw_data, *++token))\n            {\n                clear = true;\n                break;\n            }\n\n            if (raw_data.empty() || *++token != \"]\")\n            {\n                clear = true;\n                break;\n            }\n\n            code = data_to_opcode(raw_data);\n            data = raw_data;\n        }\n        else\n        {\n            code = string_to_opcode(*token);\n        }\n\n        if (code == opcode::bad_operation)\n        {\n            clear = true;\n            break;\n        }\n\n        operations.push_back({code, data});\n    }\n\n    // empty invalid/failed parse content\n    if (clear)\n        operations.clear();\n\n    return !clear;\n}\n\nstd::string script::to_string(uint32_t flags) const\n{\n    std::ostringstream value;\n\n    for (auto it = operations.begin(); it != operations.end(); ++it)\n    {\n        if (it != operations.begin())\n            value << \" \";\n\n        value << it->to_string(flags);\n    }\n\n    return value.str();\n}\n\nbool script::deserialize(const data_chunk &raw_script, parse_mode mode)\n{\n    auto result = false;\n\n    if (mode != parse_mode::raw_data)\n        result = parse(raw_script);\n\n    if (!result && (mode != parse_mode::strict))\n    {\n        result = true;\n\n        // recognize as raw data\n        const auto op = operation{\n            opcode::raw_data,\n            to_chunk(raw_script)};\n\n        operations.clear();\n        operations.push_back(op);\n    }\n\n    return result;\n}\n\nbool script::parse(const data_chunk &raw_script)\n{\n    auto result = true;\n\n    if (raw_script.begin() != raw_script.end())\n    {\n        data_source istream(raw_script);\n\n        while (result && istream &&\n               (istream.peek() != std::istream::traits_type::eof()))\n        {\n            operations.emplace_back();\n            result = operations.back().from_data(istream);\n        }\n    }\n\n    return result;\n}\n\ninline hash_digest one_hash()\n{\n    return hash_digest{\n        {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};\n}\n\ninline void nullify_input_sequences(input::list &inputs,\n                                    uint32_t except_input)\n{\n    for (size_t index = 0; index < inputs.size(); ++index)\n        if (index != except_input)\n            inputs[index].sequence = 0;\n}\n\ninline uint8_t is_sighash_enum(uint8_t sighash_type,\n                               signature_hash_algorithm value)\n{\n    return (sighash_type & signature_hash_algorithm::mask) == value;\n}\n\ninline uint8_t is_sighash_flag(uint8_t sighash_type,\n                               signature_hash_algorithm value)\n{\n    return (sighash_type & value) != 0;\n}\n\nhash_digest script::generate_signature_hash(const transaction &parent_tx,\n                                            uint32_t input_index, const script &script_code, uint8_t sighash_type)\n{\n    // Copy the parent transaction.\n    transaction parent(parent_tx);\n\n    // This is NOT considered an error result and callers should not test\n    // for one_hash. This is a bitcoind bug we perpetuate.\n    if (input_index >= parent_tx.inputs.size())\n        return one_hash();\n\n    // FindAndDelete(OP_CODESEPARATOR) done in op_checksigverify(...)\n\n    // Blank all other inputs' signatures\n    for (auto &input : parent.inputs)\n        input.script.reset();\n\n    parent.inputs[input_index].script = script_code;\n\n    // The default sighash::all signs all outputs, and the current input.\n    // Transaction cannot be updated without resigning the input.\n    // (note the lack of nullify_input_sequences() call)\n\n    if (is_sighash_enum(sighash_type, signature_hash_algorithm::none))\n    {\n        // Sign no outputs, so they can be changed.\n        parent.outputs.clear();\n        nullify_input_sequences(parent.inputs, input_index);\n    }\n    else if (is_sighash_enum(sighash_type, signature_hash_algorithm::single))\n    {\n\n        // Sign the single output corresponding to our index.\n        // We don't care about additional inputs or outputs to the tx.\n        auto &outputs = parent.outputs;\n        uint32_t output_index = input_index;\n\n        // This is NOT considered an error result and callers should not test\n        // for one_hash. This is a bitcoind bug we perpetuate.\n        if (output_index >= outputs.size())\n            return one_hash();\n\n        outputs.resize(output_index + 1);\n\n        // Loop through outputs except the last one.\n        for (auto it = outputs.begin(); it != outputs.end() - 1; ++it)\n        {\n            it->value = std::numeric_limits<uint64_t>::max();\n            it->script.reset();\n        }\n\n        nullify_input_sequences(parent.inputs, input_index);\n    }\n\n    // Flag to ignore the other inputs except our own.\n    if (is_sighash_flag(sighash_type,\n                        signature_hash_algorithm::anyone_can_pay))\n    {\n        parent.inputs[0] = parent.inputs[input_index];\n        parent.inputs.resize(1);\n    }\n\n    return parent.hash(sighash_type);\n}\n\ninline bool cast_to_bool(const data_chunk &values)\n{\n    for (auto it = values.begin(); it != values.end(); ++it)\n    {\n        if (*it != 0)\n        {\n            // Can be negative zero\n            if (it == values.end() - 1 && *it == 0x80)\n                return false;\n\n            return true;\n        }\n    }\n\n    return false;\n}\n\ntemplate <typename DataStack>\nvoid stack_swap(DataStack &stack, size_t index_a, size_t index_b)\n{\n    std::swap(*(stack.end() - index_a), *(stack.end() - index_b));\n}\n\ntemplate <typename DataStack>\ndata_chunk pop_item(DataStack &stack)\n{\n    const auto value = stack.back();\n    stack.pop_back();\n    return value;\n}\n\n// Used by pick, roll and checkmultisig*\ntemplate <typename DataStack>\nbool read_value(DataStack &stack, int32_t &value)\n{\n    if (stack.empty())\n        return false;\n\n    script_number mid;\n    if (!mid.set_data(pop_item(stack)))\n        return false;\n\n    value = mid.int32();\n    return true;\n}\n\ntemplate <typename DataStack>\nbool pick_roll_impl(DataStack &stack, bool is_roll)\n{\n    if (stack.size() < 2)\n        return false;\n\n    int32_t value;\n\n    if (!read_value(stack, value))\n        return false;\n\n    const auto stack_size = static_cast<int32_t>(stack.size());\n\n    if (value < 0 || value >= stack_size)\n        return false;\n\n    auto slice_iterator = stack.end() - value - 1;\n    auto item = *slice_iterator;\n\n    if (is_roll)\n        stack.erase(slice_iterator);\n\n    stack.push_back(item);\n    return true;\n}\n\n// Used by add, sub, mul, div, mod, lshift, rshift, booland, boolor,\n// numequal, numequalverify, numnotequal, lessthan, greaterthan,\n// lessthanorequal, greaterthanorequal, min, max\ntemplate <typename DataStack>\nbool arithmetic_start_new(DataStack &stack, script_number &number_a,\n                          script_number &number_b)\n{\n    if (stack.size() < 2)\n        return false;\n\n    // The second number is at the top of the stack.\n    if (!number_b.set_data(pop_item(stack)))\n        return false;\n\n    // The first is at the second position.\n    if (!number_a.set_data(pop_item(stack)))\n        return false;\n\n    return true;\n}\n\n// Convert opcode to its actual numeric value.\ntemplate <typename OpCode>\nauto base_value(OpCode code) -> typename std::underlying_type<OpCode>::type\n{\n    return static_cast<typename std::underlying_type<OpCode>::type>(code);\n}\n\nbool is_condition_opcode(opcode code)\n{\n    return code == opcode::if_ || code == opcode::notif || code == opcode::else_ || code == opcode::endif;\n}\n\nbool greater_op_16(opcode code)\n{\n    return base_value(code) > base_value(opcode::op_16);\n}\n\nbool op_negative_1(evaluation_context &context)\n{\n    script_number neg1(-1);\n    context.stack.push_back(neg1.data());\n    return true;\n}\n\nbool op_x(evaluation_context &context, opcode code)\n{\n    const auto difference = static_cast<uint8_t>(code) -\n                            static_cast<uint8_t>(opcode::op_1) + 1;\n\n    script_number value(difference);\n    context.stack.push_back(value.data());\n    return true;\n}\n\nbool op_if(evaluation_context &context)\n{\n    auto value = false;\n    if (context.conditional.succeeded())\n    {\n        if (context.stack.size() < 1)\n            return false;\n\n        value = cast_to_bool(context.pop_stack());\n    }\n\n    context.conditional.open(value);\n    return true;\n}\n\nbool op_notif(evaluation_context &context)\n{\n    // A bit hackish...\n    // Open IF statement but then invert it to get NOTIF\n    if (!op_if(context))\n        return false;\n\n    context.conditional.else_();\n    return true;\n}\n\nbool op_else(evaluation_context &context)\n{\n    if (context.conditional.closed())\n        return false;\n\n    context.conditional.else_();\n    return true;\n}\n\nbool op_endif(evaluation_context &context)\n{\n    if (context.conditional.closed())\n        return false;\n\n    context.conditional.close();\n    return true;\n}\n\nbool op_verify(evaluation_context &context)\n{\n    if (context.stack.size() < 1)\n        return false;\n\n    if (!cast_to_bool(context.stack.back()))\n        return false;\n\n    context.pop_stack();\n    return true;\n}\n\nbool op_toaltstack(evaluation_context &context)\n{\n    if (context.stack.size() < 1)\n        return false;\n\n    const auto move_data = context.pop_stack();\n    context.alternate.push_back(move_data);\n    return true;\n}\n\nbool op_fromaltstack(evaluation_context &context)\n{\n    if (context.alternate.size() < 1)\n        return false;\n\n    context.stack.push_back(context.alternate.back());\n    context.alternate.pop_back();\n    return true;\n}\n\nbool op_2drop(evaluation_context &context)\n{\n    if (context.stack.size() < 2)\n        return false;\n\n    context.stack.pop_back();\n    context.stack.pop_back();\n    return true;\n}\n\nbool op_2dup(evaluation_context &context)\n{\n    if (context.stack.size() < 2)\n        return false;\n\n    const auto dup_first = *(context.stack.end() - 2);\n    const auto dup_second = *(context.stack.end() - 1);\n\n    context.stack.push_back(dup_first);\n    context.stack.push_back(dup_second);\n    return true;\n}\n\nbool op_3dup(evaluation_context &context)\n{\n    if (context.stack.size() < 3)\n        return false;\n\n    const auto dup_first = *(context.stack.end() - 3);\n    const auto dup_second = *(context.stack.end() - 2);\n    const auto dup_third = *(context.stack.end() - 1);\n\n    context.stack.push_back(dup_first);\n    context.stack.push_back(dup_second);\n    context.stack.push_back(dup_third);\n    return true;\n}\n\ntemplate <typename DataStack>\nvoid copy_item_over_stack(DataStack &stack, size_t index)\n{\n    stack.push_back(*(stack.end() - index));\n}\n\nbool op_2over(evaluation_context &context)\n{\n    if (context.stack.size() < 4)\n        return false;\n\n    copy_item_over_stack(context.stack, 4);\n\n    // Item -3 now becomes -4 because of last push\n    copy_item_over_stack(context.stack, 4);\n    return true;\n}\n\nbool op_2rot(evaluation_context &context)\n{\n    if (context.stack.size() < 6)\n        return false;\n\n    const auto first_position = context.stack.end() - 6;\n    const auto second_position = context.stack.end() - 5;\n    const auto third_position = context.stack.end() - 4;\n\n    const auto dup_first = *(first_position);\n    const auto dup_second = *(second_position);\n\n    context.stack.erase(first_position, third_position);\n    context.stack.push_back(dup_first);\n    context.stack.push_back(dup_second);\n    return true;\n}\n\nbool op_2swap(evaluation_context &context)\n{\n    if (context.stack.size() < 4)\n        return false;\n\n    // Before: x1 x2 x3 x4\n    // After:  x3 x4 x1 x2\n    stack_swap(context.stack, 4, 2);\n    stack_swap(context.stack, 3, 1);\n    return true;\n}\n\nbool op_ifdup(evaluation_context &context)\n{\n    if (context.stack.size() < 1)\n        return false;\n\n    if (cast_to_bool(context.stack.back()))\n        context.stack.push_back(context.stack.back());\n\n    return true;\n}\n\nbool op_depth(evaluation_context &context)\n{\n    script_number stack_size(context.stack.size());\n    context.stack.push_back(stack_size.data());\n    return true;\n}\n\nbool op_drop(evaluation_context &context)\n{\n    if (context.stack.size() < 1)\n        return false;\n\n    context.stack.pop_back();\n    return true;\n}\n\nbool op_dup(evaluation_context &context)\n{\n    if (context.stack.size() < 1)\n        return false;\n\n    context.stack.push_back(context.stack.back());\n    return true;\n}\n\nbool op_nip(evaluation_context &context)\n{\n    if (context.stack.size() < 2)\n        return false;\n\n    context.stack.erase(context.stack.end() - 2);\n    return true;\n}\n\nbool op_over(evaluation_context &context)\n{\n    if (context.stack.size() < 2)\n        return false;\n\n    copy_item_over_stack(context.stack, 2);\n    return true;\n}\n\nbool op_pick(evaluation_context &context)\n{\n    return pick_roll_impl(context.stack, false);\n}\n\nbool op_roll(evaluation_context &context)\n{\n    return pick_roll_impl(context.stack, true);\n}\n\nbool op_rot(evaluation_context &context)\n{\n    // Top 3 stack items are rotated to the left.\n    // Before: x1 x2 x3\n    // After:  x2 x3 x1\n    if (context.stack.size() < 3)\n        return false;\n\n    stack_swap(context.stack, 3, 2);\n    stack_swap(context.stack, 2, 1);\n    return true;\n}\n\nbool op_swap(evaluation_context &context)\n{\n    if (context.stack.size() < 2)\n        return false;\n\n    stack_swap(context.stack, 2, 1);\n    return true;\n}\n\nbool op_tuck(evaluation_context &context)\n{\n    if (context.stack.size() < 2)\n        return false;\n\n    const auto data = context.stack.back();\n    context.stack.insert(context.stack.end() - 2, data);\n    return true;\n}\n\nbool op_size(evaluation_context &context)\n{\n    if (context.stack.size() < 1)\n        return false;\n\n    const script_number top_item_size(context.stack.back().size());\n    context.stack.push_back(top_item_size.data());\n    return true;\n}\n\nbool op_equal(evaluation_context &context)\n{\n    if (context.stack.size() < 2)\n        return false;\n\n    if (context.pop_stack() == context.pop_stack())\n        context.stack.push_back(stack_true_value);\n    else\n        context.stack.push_back(stack_false_value);\n\n    return true;\n}\n\nbool op_equalverify(evaluation_context &context)\n{\n    if (context.stack.size() < 2)\n        return false;\n\n    return context.pop_stack() == context.pop_stack();\n}\n\nbool op_1add(evaluation_context &context)\n{\n    if (context.stack.size() < 1)\n        return false;\n\n    script_number number;\n    if (!number.set_data(context.pop_stack()))\n        return false;\n\n    const script_number one(1);\n    number += one;\n    context.stack.push_back(number.data());\n    return true;\n}\n\nbool op_1sub(evaluation_context &context)\n{\n    if (context.stack.size() < 1)\n        return false;\n\n    script_number number;\n    if (!number.set_data(context.pop_stack()))\n        return false;\n\n    const script_number one(1);\n    number -= one;\n    context.stack.push_back(number.data());\n    return true;\n}\n\nbool op_negate(evaluation_context &context)\n{\n    if (context.stack.size() < 1)\n        return false;\n\n    script_number number;\n    if (!number.set_data(context.pop_stack()))\n        return false;\n\n    number = -number;\n    context.stack.push_back(number.data());\n    return true;\n}\n\nbool op_abs(evaluation_context &context)\n{\n    if (context.stack.size() < 1)\n        return false;\n\n    script_number number;\n    if (!number.set_data(context.pop_stack()))\n        return false;\n\n    const script_number zero(0);\n    if (number < zero)\n        number = -number;\n\n    context.stack.push_back(number.data());\n    return true;\n}\n\nbool op_not(evaluation_context &context)\n{\n    if (context.stack.size() < 1)\n        return false;\n\n    script_number number;\n    if (!number.set_data(context.pop_stack()))\n        return false;\n\n    const script_number zero(0);\n    context.stack.push_back(script_number(number == zero).data());\n    return true;\n}\n\nbool op_0notequal(evaluation_context &context)\n{\n    if (context.stack.size() < 1)\n        return false;\n\n    script_number number;\n    if (!number.set_data(context.pop_stack()))\n        return false;\n\n    const script_number zero(0);\n    context.stack.push_back(script_number(number != zero).data());\n    return true;\n}\n\nbool op_add(evaluation_context &context)\n{\n    script_number number_a, number_b;\n    if (!arithmetic_start_new(context.stack, number_a, number_b))\n        return false;\n\n    const script_number result = number_a + number_b;\n    context.stack.push_back(result.data());\n    return true;\n}\n\nbool op_sub(evaluation_context &context)\n{\n    script_number number_a, number_b;\n    if (!arithmetic_start_new(context.stack, number_a, number_b))\n        return false;\n\n    const script_number result = number_a - number_b;\n    context.stack.push_back(result.data());\n    return true;\n}\n\nbool op_booland(evaluation_context &context)\n{\n    script_number number_a, number_b;\n    if (!arithmetic_start_new(context.stack, number_a, number_b))\n        return false;\n\n    const script_number zero(0);\n    const script_number result(number_a != zero && number_b != zero);\n    context.stack.push_back(result.data());\n    return true;\n}\n\nbool op_boolor(evaluation_context &context)\n{\n    script_number number_a, number_b;\n    if (!arithmetic_start_new(context.stack, number_a, number_b))\n        return false;\n\n    const script_number zero(0);\n    const script_number result(number_a != zero || number_b != zero);\n    context.stack.push_back(result.data());\n    return true;\n}\n\nbool op_numequal(evaluation_context &context)\n{\n    script_number number_a, number_b;\n    if (!arithmetic_start_new(context.stack, number_a, number_b))\n        return false;\n\n    const script_number result(number_a == number_b);\n    context.stack.push_back(result.data());\n    return true;\n}\n\nbool op_numequalverify(evaluation_context &context)\n{\n    script_number number_a, number_b;\n    if (!arithmetic_start_new(context.stack, number_a, number_b))\n        return false;\n\n    return number_a == number_b;\n}\n\nbool op_numnotequal(evaluation_context &context)\n{\n    script_number number_a, number_b;\n    if (!arithmetic_start_new(context.stack, number_a, number_b))\n        return false;\n\n    const script_number result(number_a != number_b);\n    context.stack.push_back(result.data());\n    return true;\n}\n\nbool op_lessthan(evaluation_context &context)\n{\n    script_number number_a, number_b;\n    if (!arithmetic_start_new(context.stack, number_a, number_b))\n        return false;\n\n    const script_number result(number_a < number_b);\n    context.stack.push_back(result.data());\n    return true;\n}\n\nbool op_greaterthan(evaluation_context &context)\n{\n    script_number number_a, number_b;\n    if (!arithmetic_start_new(context.stack, number_a, number_b))\n        return false;\n\n    const script_number result(number_a > number_b);\n    context.stack.push_back(result.data());\n    return true;\n}\n\nbool op_lessthanorequal(evaluation_context &context)\n{\n    script_number number_a, number_b;\n\n    if (!arithmetic_start_new(context.stack, number_a, number_b))\n        return false;\n\n    const script_number result(number_a <= number_b);\n    context.stack.push_back(result.data());\n\n    return true;\n}\n\nbool op_greaterthanorequal(evaluation_context &context)\n{\n    script_number number_a, number_b;\n    if (!arithmetic_start_new(context.stack, number_a, number_b))\n        return false;\n\n    const script_number result(number_a >= number_b);\n    context.stack.push_back(result.data());\n    return true;\n}\n\nbool op_min(evaluation_context &context)\n{\n    script_number number_a, number_b;\n    if (!arithmetic_start_new(context.stack, number_a, number_b))\n        return false;\n\n    if (number_a < number_b)\n        context.stack.push_back(number_a.data());\n    else\n        context.stack.push_back(number_b.data());\n\n    return true;\n}\n\nbool op_max(evaluation_context &context)\n{\n    script_number number_a, number_b;\n    if (!arithmetic_start_new(context.stack, number_a, number_b))\n        return false;\n\n    if (number_a < number_b)\n        context.stack.push_back(number_b.data());\n    else\n        context.stack.push_back(number_a.data());\n\n    return true;\n}\n\nbool op_within(evaluation_context &context)\n{\n    if (context.stack.size() < 3)\n        return false;\n\n    script_number upper;\n    if (!upper.set_data(context.pop_stack()))\n        return false;\n\n    script_number lower;\n    if (!lower.set_data(context.pop_stack()))\n        return false;\n\n    script_number value;\n    if (!value.set_data(context.pop_stack()))\n        return false;\n\n    if ((lower <= value) && (value < upper))\n        context.stack.push_back(stack_true_value);\n    else\n        context.stack.push_back(stack_false_value);\n\n    return true;\n}\n\nbool op_ripemd160(evaluation_context &context)\n{\n    if (context.stack.size() < 1)\n        return false;\n\n    const auto hash = ripemd160_hash(context.pop_stack());\n    context.stack.push_back(to_chunk(hash));\n    return true;\n}\n\nbool op_sha1(evaluation_context &context)\n{\n    if (context.stack.size() < 1)\n        return false;\n\n    const auto hash = sha1_hash(context.pop_stack());\n    context.stack.push_back(to_chunk(hash));\n    return true;\n}\n\nbool op_sha256(evaluation_context &context)\n{\n    if (context.stack.size() < 1)\n        return false;\n\n    const auto hash = sha256_hash(context.pop_stack());\n    context.stack.push_back(to_chunk(hash));\n    return true;\n}\n\nbool op_hash160(evaluation_context &context)\n{\n    if (context.stack.size() < 1)\n        return false;\n\n    const auto hash = bitcoin_short_hash(context.pop_stack());\n    context.stack.push_back(to_chunk(hash));\n    return true;\n}\n\nbool op_hash256(evaluation_context &context)\n{\n    if (context.stack.size() < 1)\n        return false;\n\n    const auto hash = bitcoin_hash(context.pop_stack());\n    context.stack.push_back(to_chunk(hash));\n    return true;\n}\n\nbool script::create_endorsement(endorsement &out, const ec_secret &secret,\n                                const script &prevout_script, const transaction &new_tx,\n                                uint32_t input_index, uint8_t sighash_type)\n{\n    // This always produces a valid signature hash.\n    const auto sighash = script::generate_signature_hash(new_tx, input_index,\n                                                         prevout_script, sighash_type);\n\n    // Create the EC signature and encode as DER.\n    ec_signature signature;\n    if (!sign(signature, secret, sighash) || !encode_signature(out, signature))\n        return false;\n\n    // Add the sighash type to the end of the DER signature -> endorsement.\n    out.push_back(sighash_type);\n    return true;\n}\n\nbool script::check_signature(const ec_signature &signature,\n                             uint8_t sighash_type, const data_chunk &public_key,\n                             const script &script_code, const transaction &parent_tx,\n                             uint32_t input_index)\n{\n    if (public_key.empty())\n        return false;\n\n    // This always produces a valid signature hash.\n    const auto sighash = script::generate_signature_hash(parent_tx, input_index,\n                                                         script_code, sighash_type);\n\n    // Validate the EC signature.\n    return verify_signature(public_key, sighash, signature);\n}\n\nsignature_parse_result op_checksigverify(evaluation_context &context,\n                                         const script &script, const transaction &parent_tx, uint32_t input_index,\n                                         bool strict)\n{\n    if (context.stack.size() < 2)\n        return signature_parse_result::invalid;\n\n    const auto pubkey = context.pop_stack();\n    auto endorsement = context.pop_stack();\n    const auto sighash_type = endorsement.back();\n    auto &distinguished = endorsement;\n    distinguished.pop_back();\n\n    ec_signature signature;\n\n    if (strict && !parse_signature(signature, distinguished, true))\n        return signature_parse_result::lax_encoding;\n\n    chain::script script_code;\n\n    for (auto it = context.code_begin; it != script.operations.end(); ++it)\n        if (it->data != endorsement && it->code != opcode::codeseparator)\n            script_code.operations.push_back(*it);\n\n    if (!strict && !parse_signature(signature, distinguished, false))\n        return signature_parse_result::invalid;\n\n    return script::check_signature(signature, sighash_type, pubkey,\n                                   script_code, parent_tx, input_index)\n               ? signature_parse_result::valid\n               : signature_parse_result::invalid;\n}\n\nbool op_checksig(evaluation_context &context, const script &script,\n                 const transaction &parent_tx, uint32_t input_index, bool strict)\n{\n    switch (op_checksigverify(context, script, parent_tx, input_index, strict))\n    {\n    case signature_parse_result::valid:\n        context.stack.push_back(stack_true_value);\n        break;\n    case signature_parse_result::invalid:\n        context.stack.push_back(stack_false_value);\n        break;\n    case signature_parse_result::lax_encoding:\n        return false;\n    }\n\n    return true;\n}\n\nbool read_section(evaluation_context &context, data_stack &section,\n                  size_t count)\n{\n    if (context.stack.size() < count)\n        return false;\n\n    for (size_t i = 0; i < count; ++i)\n        section.push_back(context.pop_stack());\n\n    return true;\n}\n\nsignature_parse_result op_checkmultisigverify(evaluation_context &context,\n                                              const script &script, const transaction &parent_tx,\n                                              uint32_t input_index, bool strict)\n{\n    int32_t pubkeys_count;\n\n    if (!read_value(context.stack, pubkeys_count))\n        return signature_parse_result::invalid;\n\n    if (pubkeys_count < 0 || pubkeys_count > 20)\n        return signature_parse_result::invalid;\n\n    context.operation_counter += pubkeys_count;\n\n    if (context.operation_counter > op_counter_limit)\n        return signature_parse_result::invalid;\n\n    data_stack pubkeys;\n\n    if (!read_section(context, pubkeys, pubkeys_count))\n        return signature_parse_result::invalid;\n\n    int32_t sigs_count;\n\n    if (!read_value(context.stack, sigs_count))\n        return signature_parse_result::invalid;\n\n    if (sigs_count < 0 || sigs_count > pubkeys_count)\n        return signature_parse_result::invalid;\n\n    data_stack endorsements;\n\n    if (!read_section(context, endorsements, sigs_count))\n        return signature_parse_result::invalid;\n\n    // Due to a bug in bitcoind, we need to read an extra null value which we\n    // discard later.\n    if (context.stack.empty())\n        return signature_parse_result::invalid;\n\n    context.stack.pop_back();\n    const auto is_endorsement = [&endorsements](const data_chunk &data) {\n        return std::find(endorsements.begin(), endorsements.end(), data) !=\n               endorsements.end();\n    };\n\n    chain::script script_code;\n\n    for (auto it = context.code_begin; it != script.operations.end(); ++it)\n        if (it->code != opcode::codeseparator && !is_endorsement(it->data))\n            script_code.operations.push_back(*it);\n\n    // The exact number of signatures are required and must be in order.\n    // One key can validate more than one script. So we always advance\n    // until we exhaust either pubkeys (fail) or signatures (pass).\n    auto pubkey_iterator = pubkeys.begin();\n\n    for (const auto &endorsement : endorsements)\n    {\n        const auto sighash_type = endorsement.back();\n        auto distinguished = endorsement;\n        distinguished.pop_back();\n\n        ec_signature signature;\n\n        if (!parse_signature(signature, distinguished, strict))\n            return strict ? signature_parse_result::lax_encoding : signature_parse_result::invalid;\n\n        while (true)\n        {\n            const auto &point = *pubkey_iterator;\n\n            if (script::check_signature(signature, sighash_type, point,\n                                        script_code, parent_tx, input_index))\n                break;\n\n            ++pubkey_iterator;\n\n            if (pubkey_iterator == pubkeys.end())\n                return signature_parse_result::invalid;\n        }\n    }\n\n    return signature_parse_result::valid;\n}\n\nbool op_checkmultisig(evaluation_context &context, const script &script,\n                      const transaction &parent_tx, uint32_t input_index, bool strict)\n{\n    switch (op_checkmultisigverify(context, script, parent_tx, input_index,\n                                   strict))\n    {\n    case signature_parse_result::valid:\n        context.stack.push_back(stack_true_value);\n        break;\n    case signature_parse_result::invalid:\n        context.stack.push_back(stack_false_value);\n        break;\n    case signature_parse_result::lax_encoding:\n        return false;\n    }\n\n    return true;\n}\n\nbool is_locktime_type_match(int64_t left, int64_t right)\n{\n    const auto threshold = static_cast<int64_t>(locktime_threshold);\n    return (left < threshold) == (right < threshold);\n}\n\nbool op_checklocktimeverify(evaluation_context &context, const script &script,\n                            const transaction &parent_tx, uint32_t input_index)\n{\n    if (input_index >= parent_tx.inputs.size())\n        return false;\n\n    // BIP65: the nSequence field of the txin is 0xffffffff.\n    if (parent_tx.inputs[input_index].is_final())\n        return false;\n\n    // BIP65: the stack is empty.\n    if (context.stack.empty())\n        return false;\n\n    // BIP65: We extend the (signed) CLTV script number range to 5 bytes in\n    // order to reach the domain of the (unsigned) tx.locktime field.\n    script_number number;\n    if (!number.set_data(context.pop_stack(), cltv_max_script_number_size))\n        return false;\n\n    // BIP65: the top item on the stack is less than 0.\n    if (number < 0)\n        return false;\n\n    // BIP65: the top stack item is greater than the tx's nLockTime.\n    const auto stack = number.int64();\n    const auto transaction = static_cast<int64_t>(parent_tx.locktime);\n\n    if (stack > transaction)\n        return false;\n\n    // BIP65: the stack lock-time type differs from that of tx nLockTime.\n    return is_locktime_type_match(stack, transaction);\n}\n\nbool op_checkattenuationverify(evaluation_context &context, const script &script,\n                               const transaction &parent_tx, uint32_t input_index)\n{\n    if (input_index >= parent_tx.inputs.size())\n        return false;\n\n    if (context.stack.empty())\n        return false;\n\n    auto model_param = context.pop_stack();\n    if (!attenuation_model::check_model_param_format(model_param))\n        return false;\n\n    return true;\n}\n\n// Test flags for a given context.\nbool script::is_active(uint32_t flags, script_context flag)\n{\n    return (flag & flags) != 0;\n}\n\nbool run_operation(const operation &op, const transaction &parent_tx,\n                   uint32_t input_index, const script &script, evaluation_context &context,\n                   uint32_t flags)\n{\n    switch (op.code)\n    {\n    case opcode::zero:\n    case opcode::special:\n    case opcode::pushdata1:\n    case opcode::pushdata2:\n    case opcode::pushdata4:\n        BITCOIN_ASSERT_MSG(false,\n                           \"Invalid push operation in run_operation\");\n        return true;\n\n    case opcode::negative_1:\n        return op_negative_1(context);\n\n    case opcode::reserved:\n        return false;\n\n    case opcode::op_1:\n    case opcode::op_2:\n    case opcode::op_3:\n    case opcode::op_4:\n    case opcode::op_5:\n    case opcode::op_6:\n    case opcode::op_7:\n    case opcode::op_8:\n    case opcode::op_9:\n    case opcode::op_10:\n    case opcode::op_11:\n    case opcode::op_12:\n    case opcode::op_13:\n    case opcode::op_14:\n    case opcode::op_15:\n    case opcode::op_16:\n        return op_x(context, op.code);\n\n    case opcode::nop:\n        return true;\n\n    case opcode::ver:\n        return false;\n\n    case opcode::if_:\n        return op_if(context);\n\n    case opcode::notif:\n        return op_notif(context);\n\n    case opcode::verif:\n    case opcode::vernotif:\n        BITCOIN_ASSERT_MSG(false,\n                           \"Disabled opcodes (verif/vernotif) in run_operation\");\n        return false;\n\n    case opcode::else_:\n        return op_else(context);\n\n    case opcode::endif:\n        return op_endif(context);\n\n    case opcode::verify:\n        return op_verify(context);\n\n    case opcode::return_:\n        return false;\n\n    case opcode::toaltstack:\n        return op_toaltstack(context);\n\n    case opcode::fromaltstack:\n        return op_fromaltstack(context);\n\n    case opcode::op_2drop:\n        return op_2drop(context);\n\n    case opcode::op_2dup:\n        return op_2dup(context);\n\n    case opcode::op_3dup:\n        return op_3dup(context);\n\n    case opcode::op_2over:\n        return op_2over(context);\n\n    case opcode::op_2rot:\n        return op_2rot(context);\n\n    case opcode::op_2swap:\n        return op_2swap(context);\n\n    case opcode::ifdup:\n        return op_ifdup(context);\n\n    case opcode::depth:\n        return op_depth(context);\n\n    case opcode::drop:\n        return op_drop(context);\n\n    case opcode::dup:\n        return op_dup(context);\n\n    case opcode::nip:\n        return op_nip(context);\n\n    case opcode::over:\n        return op_over(context);\n\n    case opcode::pick:\n        return op_pick(context);\n\n    case opcode::roll:\n        return op_roll(context);\n\n    case opcode::rot:\n        return op_rot(context);\n\n    case opcode::swap:\n        return op_swap(context);\n\n    case opcode::cat:\n    case opcode::substr:\n    case opcode::left:\n    case opcode::right:\n        BITCOIN_ASSERT_MSG(false,\n                           \"Disabled splice operations in run_operation\");\n        return false;\n\n    case opcode::tuck:\n        return op_tuck(context);\n\n    case opcode::size:\n        return op_size(context);\n\n    case opcode::invert:\n    case opcode::and_:\n    case opcode::or_:\n    case opcode::xor_:\n        BITCOIN_ASSERT_MSG(false,\n                           \"Disabled bit logic operations in run_operation\");\n        return false;\n\n    case opcode::equal:\n        return op_equal(context);\n\n    case opcode::equalverify:\n        return op_equalverify(context);\n\n    case opcode::reserved1:\n    case opcode::reserved2:\n        return false;\n\n    case opcode::op_1add:\n        return op_1add(context);\n\n    case opcode::op_1sub:\n        return op_1sub(context);\n\n    case opcode::op_2mul:\n    case opcode::op_2div:\n        BITCOIN_ASSERT_MSG(false,\n                           \"Disabled opcodes (2mul/2div) in run_operation\");\n        return false;\n\n    case opcode::negate:\n        return op_negate(context);\n\n    case opcode::abs:\n        return op_abs(context);\n\n    case opcode::not_:\n        return op_not(context);\n\n    case opcode::op_0notequal:\n        return op_0notequal(context);\n\n    case opcode::add:\n        return op_add(context);\n\n    case opcode::sub:\n        return op_sub(context);\n\n    case opcode::mul:\n    case opcode::div:\n    case opcode::mod:\n    case opcode::lshift:\n    case opcode::rshift:\n        BITCOIN_ASSERT_MSG(false,\n                           \"Disabled numeric operations in run_operation\");\n        return false;\n\n    case opcode::booland:\n        return op_booland(context);\n\n    case opcode::boolor:\n        return op_boolor(context);\n\n    case opcode::numequal:\n        return op_numequal(context);\n\n    case opcode::numequalverify:\n        return op_numequalverify(context);\n\n    case opcode::numnotequal:\n        return op_numnotequal(context);\n\n    case opcode::lessthan:\n        return op_lessthan(context);\n\n    case opcode::greaterthan:\n        return op_greaterthan(context);\n\n    case opcode::lessthanorequal:\n        return op_lessthanorequal(context);\n\n    case opcode::greaterthanorequal:\n        return op_greaterthanorequal(context);\n\n    case opcode::min:\n        return op_min(context);\n\n    case opcode::max:\n        return op_max(context);\n\n    case opcode::within:\n        return op_within(context);\n\n    case opcode::ripemd160:\n        return op_ripemd160(context);\n\n    case opcode::sha1:\n        return op_sha1(context);\n\n    case opcode::sha256:\n        return op_sha256(context);\n\n    case opcode::hash160:\n        return op_hash160(context);\n\n    case opcode::hash256:\n        return op_hash256(context);\n\n    case opcode::codeseparator:\n        // This is set in the main evaluate(...) loop\n        // code_begin is updated to the current position\n        BITCOIN_ASSERT_MSG(false,\n                           \"Invalid operation (codeseparator) in run_operation\");\n        return true;\n\n    case opcode::checksig:\n        return op_checksig(context, script, parent_tx, input_index,\n                           script::is_active(flags, script_context::bip66_enabled));\n\n    case opcode::checksigverify:\n        return op_checksigverify(context, script, parent_tx, input_index,\n                                 script::is_active(flags, script_context::bip66_enabled)) ==\n               signature_parse_result::valid;\n\n    case opcode::checkmultisig:\n        return op_checkmultisig(context, script, parent_tx, input_index,\n                                script::is_active(flags, script_context::bip66_enabled));\n\n    case opcode::checkmultisigverify:\n        return op_checkmultisigverify(context, script, parent_tx, input_index,\n                                      script::is_active(flags, script_context::bip66_enabled)) ==\n               signature_parse_result::valid;\n\n    case opcode::checklocktimeverify:\n        return script::is_active(context.flags, script_context::bip65_enabled) ? op_checklocktimeverify(context, script, parent_tx,\n                                                                                                        input_index)\n                                                                               : true;\n\n    case opcode::checkattenuationverify:\n        return script::is_active(context.flags, script_context::attenuation_enabled) ? op_checkattenuationverify(context, script, parent_tx, input_index) : true;\n\n    case opcode::op_nop1:\n    case opcode::op_nop4:\n    case opcode::op_nop5:\n    case opcode::op_nop6:\n    case opcode::op_nop7:\n    case opcode::op_nop8:\n    case opcode::op_nop9:\n    case opcode::op_nop10:\n        return true;\n\n    case opcode::raw_data:\n        return false;\n\n    default:\n        ////log::fatal(LOG_SCRIPT) << \"Unimplemented operation <none \"\n        ////    << static_cast<int>(op.code) << \">\";\n        return false;\n    }\n\n    return false;\n}\n\nbool increment_op_counter(opcode code, evaluation_context &context)\n{\n    if (greater_op_16(code))\n        ++context.operation_counter;\n\n    if (context.operation_counter > op_counter_limit)\n        return false;\n\n    return true;\n}\n\nbool opcode_is_disabled(opcode code)\n{\n    switch (code)\n    {\n    case opcode::cat:\n    case opcode::substr:\n    case opcode::left:\n    case opcode::right:\n    case opcode::invert:\n    case opcode::and_:\n    case opcode::or_:\n    case opcode::xor_:\n    case opcode::op_2mul:\n    case opcode::op_2div:\n    case opcode::mul:\n    case opcode::div:\n    case opcode::mod:\n    case opcode::lshift:\n    case opcode::rshift:\n        return true;\n\n    // These opcodes aren't in the main Satoshi EvalScript\n    // switch-case so the script loop always fails regardless of\n    // whether these are executed or not.\n    case opcode::verif:\n    case opcode::vernotif:\n        return true;\n\n    default:\n        return false;\n    }\n}\n\nbool opcode_is_empty_pusher(opcode code)\n{\n    switch (code)\n    {\n    // These operations may push empty data (opcode zero).\n    case opcode::special:\n    case opcode::pushdata1:\n    case opcode::pushdata2:\n    case opcode::pushdata4:\n        return true;\n\n    default:\n        return false;\n    }\n}\n\nbool next_step(const transaction &parent_tx, uint32_t input_index,\n               operation::stack::const_iterator it, const script &script,\n               evaluation_context &context, uint32_t flags)\n{\n    const auto &op = *it;\n\n    if (op.data.size() > 520)\n        return false;\n\n    if (!increment_op_counter(op.code, context))\n        return false;\n\n    if (opcode_is_disabled(op.code))\n        return false;\n\n    if (!context.conditional.succeeded() && !is_condition_opcode(op.code))\n        return true;\n\n    // push data to the stack\n    if (op.code == opcode::zero)\n    {\n        context.stack.push_back(data_chunk());\n    }\n    else if (op.code == opcode::codeseparator)\n    {\n        context.code_begin = it;\n    }\n    else if (opcode_is_empty_pusher(op.code))\n    {\n        context.stack.push_back(op.data);\n    }\n    else if (!run_operation(op, parent_tx, input_index, script, context,\n                            flags))\n    {\n        // opcodes above should assert inside run_operation\n        return false;\n    }\n\n    //log::debug() << \"--------------------\";\n    //log::debug() << \"Run: \" << opcode_to_string(op.code);\n    //log::debug() << \"Stack:\";\n    //for (auto s: context.stack)\n    //    log::debug() << \"[\" << encode_base16(s) << \"]\";\n\n    return (context.stack.size() + context.alternate.size() <= 1000);\n}\n\nbool evaluate(const transaction &parent_tx, uint32_t input_index,\n              const script &script, evaluation_context &context, uint32_t flags)\n{\n    if (script.satoshi_content_size() > 10000)\n        return false;\n\n    context.operation_counter = 0;\n    context.code_begin = script.operations.begin();\n\n    for (auto it = script.operations.begin(); it != script.operations.end(); ++it)\n        if (!next_step(parent_tx, input_index, it, script, context, flags))\n            return false;\n\n    return context.conditional.closed();\n}\n\nbool script::verify(const script &input_script, const script &output_script,\n                    const transaction &parent_tx, uint32_t input_index, uint32_t flags)\n{\n    evaluation_context input_context;\n    input_context.flags = flags;\n\n    if (!evaluate(parent_tx, input_index, input_script, input_context, flags))\n        return false;\n\n    evaluation_context output_context;\n    output_context.flags = flags;\n    output_context.stack = input_context.stack;\n\n    if (!evaluate(parent_tx, input_index, output_script, output_context,\n                  flags))\n        return false;\n\n    if (output_context.stack.empty() ||\n        !cast_to_bool(output_context.stack.back()))\n        return false;\n\n    // Additional validation for pay-to-script-hash transactions\n    if (is_active(flags, script_context::bip16_enabled) &&\n        (output_script.pattern() == script_pattern::pay_script_hash))\n    {\n        if (!operation::is_push_only(input_script.operations))\n            return false;\n\n        // Load last input_script stack item as a script\n        evaluation_context eval_context;\n        eval_context.flags = flags;\n        eval_context.stack = input_context.stack;\n\n        // TODO: shouldn't this be parse_mode::strict?\n        // Invalid script - parsable only as raw_data\n        script eval_script;\n\n        if (!eval_script.from_data(input_context.stack.back(), false,\n                                   parse_mode::raw_data_fallback))\n            return false;\n\n        // Pop last item and copy as starting stack to eval script\n        eval_context.stack.pop_back();\n\n        // Run script\n        if (!evaluate(parent_tx, input_index, eval_script, eval_context,\n                      flags))\n            return false;\n\n        if (eval_context.stack.empty())\n            return false;\n\n        return cast_to_bool(eval_context.stack.back());\n    }\n\n    return true;\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/chain/transaction.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/chain/transaction.hpp>\n\n#include <numeric>\n#include <sstream>\n#include <utility>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/chain/input.hpp>\n#include <UChain/coin/chain/output.hpp>\n#include <UChain/coin/constants.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\ntransaction transaction::factory_from_data(const data_chunk &data)\n{\n    transaction instance;\n    instance.from_data(data);\n    return instance;\n}\n\ntransaction transaction::factory_from_data(std::istream &stream)\n{\n    transaction instance;\n    instance.from_data(stream);\n    return instance;\n}\n\ntransaction transaction::factory_from_data(reader &source)\n{\n    transaction instance;\n    instance.from_data(source);\n    return instance;\n}\n\n// default constructors\n\ntransaction::transaction()\n    : version(0), locktime(0), hash_(nullptr)\n{\n}\n\ntransaction::transaction(const transaction &other)\n    : transaction(other.version, other.locktime, other.inputs, other.outputs)\n{\n}\n\ntransaction::transaction(uint32_t version, uint32_t locktime,\n                         const input::list &inputs, const output::list &outputs)\n    : version(version),\n      locktime(locktime),\n      inputs(inputs),\n      outputs(outputs),\n      hash_(nullptr)\n{\n}\n\ntransaction::transaction(transaction &&other)\n    : transaction(other.version, other.locktime,\n                  std::forward<input::list>(other.inputs),\n                  std::forward<output::list>(other.outputs))\n{\n}\n\ntransaction::transaction(uint32_t version, uint32_t locktime,\n                         input::list &&inputs, output::list &&outputs)\n    : version(version),\n      locktime(locktime),\n      inputs(std::forward<input::list>(inputs)),\n      outputs(std::forward<output::list>(outputs)),\n      hash_(nullptr)\n{\n}\n\ntransaction &transaction::operator=(transaction &&other)\n{\n    version = other.version;\n    locktime = other.locktime;\n    inputs = std::move(other.inputs);\n    outputs = std::move(other.outputs);\n    return *this;\n}\n\n// TODO: eliminate blockchain transaction copies and then delete this.\ntransaction &transaction::operator=(const transaction &other)\n{\n    version = other.version;\n    locktime = other.locktime;\n    inputs = other.inputs;\n    outputs = other.outputs;\n    return *this;\n}\n\nbool transaction::is_valid() const\n{\n    return (version != 0) || (locktime != 0) || !inputs.empty() ||\n           !outputs.empty();\n}\n\nvoid transaction::reset()\n{\n    version = 0;\n    locktime = 0;\n    inputs.clear();\n    inputs.shrink_to_fit();\n    outputs.clear();\n    outputs.shrink_to_fit();\n\n    mutex_.lock();\n    hash_.reset();\n    mutex_.unlock();\n}\n\nbool transaction::from_data(const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(istream);\n}\n\nbool transaction::from_data(std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(source);\n}\n\nbool transaction::from_data(reader &source)\n{\n    reset();\n    version = source.read_4_bytes_little_endian();\n    auto result = static_cast<bool>(source);\n\n    if (result)\n    {\n        const auto tx_in_count = source.read_variable_uint_little_endian();\n        result = source;\n\n        if (result)\n        {\n            inputs.resize(tx_in_count);\n\n            for (auto &input : inputs)\n            {\n                result = input.from_data(source);\n\n                if (!result)\n                    break;\n            }\n        }\n    }\n\n    if (result)\n    {\n        const auto tx_out_count = source.read_variable_uint_little_endian();\n        result = source;\n\n        if (result)\n        {\n            outputs.resize(tx_out_count);\n\n            for (auto &output : outputs)\n            {\n                result = output.from_data(source);\n\n                if (!result)\n                    break;\n            }\n        }\n    }\n\n    if (result)\n    {\n        locktime = source.read_4_bytes_little_endian();\n        result = source;\n    }\n\n    if (!result)\n        reset();\n\n    return result;\n}\n\ndata_chunk transaction::to_data() const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream);\n    ostream.flush();\n\n    BITCOIN_ASSERT(data.size() == serialized_size());\n\n    return data;\n}\n\nvoid transaction::to_data(std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(sink);\n}\n\nvoid transaction::to_data(writer &sink) const\n{\n    sink.write_4_bytes_little_endian(version);\n    sink.write_variable_uint_little_endian(inputs.size());\n\n    for (const auto &input : inputs)\n        input.to_data(sink);\n\n    sink.write_variable_uint_little_endian(outputs.size());\n\n    for (const auto &output : outputs)\n        output.to_data(sink);\n\n    sink.write_4_bytes_little_endian(locktime);\n}\n\nuint64_t transaction::serialized_size() const\n{\n    uint64_t tx_size = 8;\n    tx_size += variable_uint_size(inputs.size());\n    for (const auto &input : inputs)\n        tx_size += input.serialized_size();\n\n    tx_size += variable_uint_size(outputs.size());\n    for (const auto &output : outputs)\n        tx_size += output.serialized_size();\n\n    return tx_size;\n}\n\nstd::string transaction::to_string(uint32_t flags) const\n{\n    std::ostringstream value;\n    value << \"Transaction:\\n\"\n          << \"\\tversion = \" << version << \"\\n\"\n          << \"\\tlocktime = \" << locktime << \"\\n\"\n          << \"Inputs:\\n\";\n\n    for (const auto input : inputs)\n        value << input.to_string(flags);\n\n    value << \"Outputs:\\n\";\n    for (const auto output : outputs)\n        value << output.to_string(flags);\n\n    value << \"\\n\";\n    return value.str();\n}\n\nhash_digest transaction::hash() const\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    mutex_.lock_upgrade();\n\n    if (!hash_)\n    {\n        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n        mutex_.unlock_upgrade_and_lock();\n        hash_.reset(new hash_digest(bitcoin_hash(to_data())));\n        mutex_.unlock_and_lock_upgrade();\n        //---------------------------------------------------------------------\n    }\n\n    hash_digest hash = *hash_;\n    mutex_.unlock_upgrade();\n    ///////////////////////////////////////////////////////////////////////////\n\n    return hash;\n}\n\nhash_digest transaction::hash(uint32_t sighash_type) const\n{\n    auto serialized = to_data();\n    extend_data(serialized, to_little_endian(sighash_type));\n    return bitcoin_hash(serialized);\n}\n\nbool transaction::is_coinbase() const\n{\n    return is_strict_coinbase() || is_token_block_coinbase();\n}\n\nbool transaction::is_token_block_coinbase() const\n{\n    return inputs.size() == 1 && outputs.size() <= 2 && outputs[0].is_token_transfer() && outputs[0].get_token_transfer().get_symbol() == UC_BLOCK_TOKEN_SYMBOL;\n}\n\nbool transaction::is_strict_coinbase() const\n{\n    return (inputs.size() == 1) && inputs[0].previous_output.is_null();\n}\n\nbool transaction::is_final(uint64_t block_height, uint32_t block_time) const\n{\n    if (locktime == 0)\n        return true;\n\n    auto max_locktime = block_time;\n\n    if (locktime < locktime_threshold)\n        max_locktime = static_cast<uint32_t>(block_height);\n\n    if (locktime < max_locktime)\n        return true;\n\n    for (const auto &tx_input : inputs)\n        if (!tx_input.is_final())\n            return false;\n\n    return true;\n}\n\nbool transaction::is_locktime_conflict() const\n{\n    auto locktime_set = locktime != 0;\n\n    if (locktime_set)\n        for (const auto &input : inputs)\n            if (input.sequence < max_input_sequence)\n                return false;\n\n    return locktime_set;\n}\n\nuint64_t transaction::total_output_value() const\n{\n    const auto value = [](uint64_t total, const output &output) {\n        return total + output.value;\n    };\n\n    return std::accumulate(outputs.begin(), outputs.end(), uint64_t(0), value);\n}\n\nuint64_t transaction::total_output_transfer_amount() const\n{\n    const auto value = [](uint64_t total, const output &output) {\n        // token issue and token transfer can not co-exist in one transaction outputs.\n        // token secondary issue is from air, so not add its amount to pass amount check.\n        // vote specify to count again.\n        if (output.is_token_secondaryissue() || output.is_vote())\n        {\n            return total;\n        }\n        return total + output.get_token_amount();\n    };\n    return std::accumulate(outputs.begin(), outputs.end(), uint64_t(0), value);\n}\n\nuint64_t transaction::total_output_vote_amount() const\n{\n    const auto value = [](uint64_t total, const output &output) {\n        if (output.is_vote())\n        {\n            return total + output.get_token_amount();\n        }\n        return total;\n    };\n    return std::accumulate(outputs.begin(), outputs.end(), uint64_t(0), value);\n}\n\nbool transaction::has_token_issue() const\n{\n    for (auto &elem : outputs)\n    {\n        if (elem.is_token_issue())\n            return true;\n    }\n    return false;\n}\n\nbool transaction::has_token_secondary_issue() const\n{\n    for (auto &elem : outputs)\n    {\n        if (elem.is_token_secondaryissue())\n            return true;\n    }\n    return false;\n}\n\nbool transaction::has_token_transfer() const\n{\n    for (auto &elem : outputs)\n    {\n        if (elem.is_token_transfer() && elem.get_token_amount()) // block #810376 has 0 token transfer without input\n            return true;\n    }\n    return false;\n}\n\nbool transaction::has_token_vote() const\n{\n    for (auto &elem : outputs)\n    {\n        if (elem.is_vote()) // block #810376 has 0 token transfer without input\n            return true;\n    }\n    return false;\n}\n\nbool transaction::has_token_cert() const\n{\n    for (auto &elem : outputs)\n    {\n        if (elem.is_token_cert())\n            return true;\n    }\n    return false;\n}\n\nbool transaction::has_candidate_transfer() const\n{\n    for (auto &elem : outputs)\n    {\n        if (elem.is_candidate_transfer())\n            return true;\n    }\n    return false;\n}\n\nbool transaction::has_candidate_register() const\n{\n    for (auto &elem : outputs)\n    {\n        if (elem.is_candidate_register())\n            return true;\n    }\n    return false;\n}\n\nbool transaction::has_uid_register() const\n{\n    for (auto &elem : outputs)\n    {\n        if (elem.is_uid_register())\n            return true;\n    }\n    return false;\n}\n\nbool transaction::has_uid_transfer() const\n{\n    for (auto &elem : outputs)\n    {\n        if (elem.is_uid_transfer())\n            return true;\n    }\n    return false;\n}\n\nstd::string transaction::get_uid_transfer_old_address() const\n{\n    std::string newuidstr = \"\";\n    for (auto &elem : outputs)\n    {\n        if (elem.is_uid_transfer())\n        {\n            newuidstr = elem.get_script_address();\n        }\n    }\n\n    if (newuidstr.empty())\n    {\n        return newuidstr;\n    }\n\n    for (auto &elem : inputs)\n    {\n        if (elem.get_script_address() != newuidstr)\n        {\n            newuidstr = elem.get_script_address();\n            return newuidstr;\n        }\n    }\n\n    return newuidstr;\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/config/authority.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/config/authority.hpp>\n\n#include <sstream>\n#include <boost/algorithm/string.hpp>\n#include <boost/format.hpp>\n#include <boost/lexical_cast.hpp>\n#include <boost/program_options.hpp>\n#include <boost/regex.hpp>\n#include <UChain/coin/formats/base_16.hpp>\n#include <UChain/coin/utility/asio.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/string.hpp>\n\nnamespace libbitcoin\n{\nnamespace config\n{\n\nusing namespace boost;\nusing namespace boost::program_options;\n\n// host:    [2001:db8::2] or  2001:db8::2  or 1.2.240.1\n// returns: [2001:db8::2] or [2001:db8::2] or 1.2.240.1\nstatic std::string to_host_name(const std::string &host)\n{\n    if (host.find(\":\") == std::string::npos || host.find(\"[\") == 0)\n        return host;\n\n    const auto hostname = format(\"[%1%]\") % host;\n    return hostname.str();\n}\n\n// host: [2001:db8::2] or 2001:db8::2 or 1.2.240.1\nstatic std::string to_authority(const std::string &host, uint16_t port)\n{\n    std::stringstream authority;\n    authority << to_host_name(host);\n    if (port > 0)\n        authority << \":\" << port;\n\n    return authority.str();\n}\n\nstatic std::string to_ipv6(const std::string &ipv4_address)\n{\n    return std::string(\"::ffff:\") + ipv4_address;\n}\n\nstatic asio::ipv6 to_ipv6(const asio::ipv4 &ipv4_address)\n{\n    // Create an IPv6 mapped IPv4 address via serialization.\n    const auto ipv6 = to_ipv6(ipv4_address.to_string());\n    return asio::ipv6::from_string(ipv6);\n}\n\nstatic asio::ipv6 to_ipv6(const asio::address &ip_address)\n{\n    if (ip_address.is_v6())\n        return ip_address.to_v6();\n\n    BITCOIN_ASSERT_MSG(ip_address.is_v4(),\n                       \"The address must be either IPv4 or IPv6.\");\n\n    return to_ipv6(ip_address.to_v4());\n}\n\nstatic std::string to_ipv4_hostname(const asio::address &ip_address)\n{\n    // std::regex requires gcc 4.9, so we are using boost::regex for now.\n    static const regex regular(\"^::ffff:([0-9\\\\.]+)$\");\n\n    const auto address = ip_address.to_string();\n    sregex_iterator it(address.begin(), address.end(), regular), end;\n    if (it == end)\n        return \"\";\n\n    const auto &match = *it;\n    return match[1];\n}\n\nstatic std::string to_ipv6_hostname(const asio::address &ip_address)\n{\n    // IPv6 URLs use a bracketed IPv6 address, see rfc2732.\n    const auto hostname = format(\"[%1%]\") % to_ipv6(ip_address);\n    return hostname.str();\n}\n\nauthority::authority()\n    : port_(0)\n{\n}\n\nauthority::authority(const authority &other)\n    : authority(other.ip_, other.port_)\n{\n}\n\n// authority: [2001:db8::2]:port or 1.2.240.1:port\nauthority::authority(const std::string &authority)\n{\n    std::stringstream(authority) >> *this;\n}\n\n// This is the format returned from peers on the bitcoin network.\nauthority::authority(const message::network_address &address)\n    : authority(address.ip, address.port)\n{\n}\n\nstatic asio::ipv6 to_boost_address(const message::ip_address &in)\n{\n    asio::ipv6::bytes_type bytes;\n    BITCOIN_ASSERT(bytes.size() == in.size());\n    std::copy(in.begin(), in.end(), bytes.begin());\n    const asio::ipv6 out(bytes);\n    return out;\n}\n\nstatic message::ip_address to_bc_address(const asio::ipv6 &in)\n{\n    message::ip_address out;\n    const auto bytes = in.to_bytes();\n    BITCOIN_ASSERT(bytes.size() == out.size());\n    std::copy(bytes.begin(), bytes.end(), out.begin());\n    return out;\n}\n\nauthority::authority(const message::ip_address &ip, uint16_t port)\n    : ip_(to_boost_address(ip)), port_(port)\n{\n}\n\n// host: [2001:db8::2] or 2001:db8::2 or 1.2.240.1\nauthority::authority(const std::string &host, uint16_t port)\n    : authority(to_authority(host, port))\n{\n}\n\nauthority::authority(const asio::address &ip, uint16_t port)\n    : ip_(to_ipv6(ip)), port_(port)\n{\n}\n\nauthority::authority(const asio::endpoint &endpoint)\n    : authority(endpoint.address(), endpoint.port())\n{\n}\n\nmessage::ip_address authority::ip() const\n{\n    return to_bc_address(ip_);\n}\n\nuint16_t authority::port() const\n{\n    return port_;\n}\n\nstd::string authority::to_hostname() const\n{\n    auto ipv4_hostname = to_ipv4_hostname(ip_);\n    return ipv4_hostname.empty() ? to_ipv6_hostname(ip_) : ipv4_hostname;\n}\n\nmessage::network_address authority::to_network_address() const\n{\n    static constexpr uint32_t services = 0;\n    static constexpr uint64_t timestamp = 0;\n    const message::network_address network_address{\n        timestamp,\n        services,\n        ip(),\n        port(),\n    };\n\n    return network_address;\n}\n\nstd::string authority::to_string() const\n{\n    std::stringstream value;\n    value << *this;\n    return value.str();\n}\n\nbool authority::operator==(const authority &other) const\n{\n    return port() == other.port() && ip() == other.ip();\n}\n\nbool authority::operator!=(const authority &other) const\n{\n    return !(*this == other);\n}\n\nbool authority::operator<(const authority &other) const\n{\n    return ip() < other.ip() ? true : (ip() > other.ip() ? false : port() < other.port());\n}\n\nstd::istream &operator>>(std::istream &input, authority &argument)\n{\n    std::string value;\n    input >> value;\n\n    // std::regex requires gcc 4.9, so we are using boost::regex for now.\n    static const regex regular(\n        \"^(([0-9\\\\.]+)|\\\\[([0-9a-f:\\\\.]+)])(:([0-9]{1,5}))?$\");\n\n    sregex_iterator it(value.begin(), value.end(), regular), end;\n    if (it == end)\n    {\n        BOOST_THROW_EXCEPTION(invalid_option_value(value));\n    }\n\n    const auto &match = *it;\n    std::string port(match[5]);\n    std::string ip_address(match[3]);\n    if (ip_address.empty())\n        ip_address = to_ipv6(match[2]);\n\n    try\n    {\n        argument.ip_ = asio::ipv6::from_string(ip_address);\n        argument.port_ = port.empty() ? 0 : lexical_cast<uint16_t>(port);\n    }\n    catch (const boost::exception &)\n    {\n        BOOST_THROW_EXCEPTION(invalid_option_value(value));\n    }\n\n    return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const authority &argument)\n{\n    output << to_authority(argument.to_hostname(), argument.port());\n    return output;\n}\n\n} // namespace config\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/config/base16.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/config/base16.hpp>\n\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <boost/program_options.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/formats/base_16.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\nnamespace config\n{\n\nbase16::base16()\n{\n}\n\nbase16::base16(const std::string &hexcode)\n{\n    std::stringstream(hexcode) >> *this;\n}\n\nbase16::base16(const data_chunk &value)\n    : value_(value)\n{\n}\n\nbase16::base16(const base16 &other)\n    : base16(other.value_)\n{\n}\n\nbase16::operator const data_chunk &() const\n{\n    return value_;\n}\n\nbase16::operator data_slice() const\n{\n    return value_;\n}\n\nstd::istream &operator>>(std::istream &input, base16 &argument)\n{\n    std::string hexcode;\n    input >> hexcode;\n\n    if (!decode_base16(argument.value_, hexcode))\n    {\n        using namespace boost::program_options;\n        BOOST_THROW_EXCEPTION(invalid_option_value(hexcode));\n    }\n\n    return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const base16 &argument)\n{\n    output << encode_base16(argument.value_);\n    return output;\n}\n\n} // namespace config\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/config/base2.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/config/base2.hpp>\n\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <boost/program_options.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/binary.hpp>\n\nnamespace libbitcoin\n{\nnamespace config\n{\n\nbase2::base2()\n{\n}\n\nbase2::base2(const std::string &binary)\n{\n    std::stringstream(binary) >> *this;\n}\n\nbase2::base2(const binary &value)\n    : value_(value)\n{\n}\n\nbase2::base2(const base2 &other)\n    : base2(other.value_)\n{\n}\n\nsize_t base2::size() const\n{\n    return value_.size();\n}\n\nbase2::operator const binary &() const\n{\n    return value_;\n}\n\nstd::istream &operator>>(std::istream &input, base2 &argument)\n{\n    std::string binary;\n    input >> binary;\n\n    if (!binary::is_base2(binary))\n    {\n        using namespace boost::program_options;\n        BOOST_THROW_EXCEPTION(invalid_option_value(binary));\n    }\n\n    std::stringstream(binary) >> argument.value_;\n\n    return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const base2 &argument)\n{\n    output << argument.value_;\n    return output;\n}\n\n} // namespace config\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/config/base58.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/config/base58.hpp>\n\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <boost/program_options.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/formats/base_58.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\nnamespace config\n{\n\nbase58::base58()\n{\n}\n\nbase58::base58(const std::string &base58)\n{\n    std::stringstream(base58) >> *this;\n}\n\nbase58::base58(const data_chunk &value)\n    : value_(value)\n{\n}\n\nbase58::base58(const base58 &other)\n    : base58(other.value_)\n{\n}\n\nbase58::operator const data_chunk &() const\n{\n    return value_;\n}\n\nbase58::operator data_slice() const\n{\n    return value_;\n}\n\nstd::istream &operator>>(std::istream &input, base58 &argument)\n{\n    std::string base58;\n    input >> base58;\n\n    if (!decode_base58(argument.value_, base58))\n    {\n        using namespace boost::program_options;\n        BOOST_THROW_EXCEPTION(invalid_option_value(base58));\n    }\n\n    return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const base58 &argument)\n{\n    output << encode_base58(argument.value_);\n    return output;\n}\n\n} // namespace config\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/config/base64.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/config/base64.hpp>\n\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <boost/program_options.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/formats/base_64.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\nnamespace config\n{\n\nbase64::base64()\n{\n}\n\nbase64::base64(const std::string &base64)\n{\n    std::stringstream(base64) >> *this;\n}\n\nbase64::base64(const data_chunk &value)\n    : value_(value)\n{\n}\n\nbase64::base64(const base64 &other)\n    : base64(other.value_)\n{\n}\n\nbase64::operator const data_chunk &() const\n{\n    return value_;\n}\n\nbase64::operator data_slice() const\n{\n    return value_;\n}\n\nstd::istream &operator>>(std::istream &input, base64 &argument)\n{\n    std::string base64;\n    input >> base64;\n\n    if (!decode_base64(argument.value_, base64))\n    {\n        using namespace boost::program_options;\n        BOOST_THROW_EXCEPTION(invalid_option_value(base64));\n    }\n\n    return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const base64 &argument)\n{\n    output << encode_base64(argument.value_);\n    return output;\n}\n\n} // namespace config\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/config/checkpoint.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/config/checkpoint.hpp>\n\n#include <cstddef>\n#include <iostream>\n#include <regex>\n#include <string>\n#include <boost/lexical_cast.hpp>\n#include <boost/program_options.hpp>\n#include <boost/regex.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/formats/base_16.hpp>\n#include <UChain/coin/math/hash.hpp>\n\nnamespace libbitcoin\n{\nnamespace config\n{\n\nusing namespace boost;\nusing namespace boost::program_options;\n\ncheckpoint::checkpoint()\n    : height_(0), hash_(bc::null_hash)\n{\n}\n\ncheckpoint::checkpoint(const std::string &value)\n    : checkpoint()\n{\n    std::stringstream(value) >> *this;\n}\n\ncheckpoint::checkpoint(const checkpoint &other)\n    : hash_(other.hash()), height_(other.height())\n{\n}\n\n// This is intended for static initialization (i.e. of the internal defaults).\ncheckpoint::checkpoint(const std::string &hash, size_t height)\n    : height_(height)\n{\n    if (!decode_hash(hash_, hash))\n    {\n        BOOST_THROW_EXCEPTION(invalid_option_value(hash));\n    }\n}\n\ncheckpoint::checkpoint(const hash_digest &hash, size_t height)\n    : hash_(hash), height_(height)\n{\n}\n\n//-\nhash_digest checkpoint::hash() const\n{\n    return hash_;\n}\n\nsize_t checkpoint::height() const\n{\n    return height_;\n}\n\nstd::string checkpoint::to_string() const\n{\n    std::stringstream value;\n    value << *this;\n    return value.str();\n}\n\nconfig::checkpoint::list checkpoint::sort(const list &checks)\n{\n    const auto comparitor = [](const checkpoint &left, const checkpoint &right) {\n        return left.height() < right.height();\n    };\n\n    auto copy = checks;\n    std::sort(copy.begin(), copy.end(), comparitor);\n    return copy;\n}\n\nbool checkpoint::validate(const hash_digest &hash, size_t height,\n                          const list &checks)\n{\n    const auto match_invalid = [&height, &hash](const config::checkpoint &item) {\n        return height == item.height() && hash != item.hash();\n    };\n\n    const auto it = std::find_if(checks.begin(), checks.end(), match_invalid);\n    return it == checks.end();\n}\n\nbool checkpoint::operator==(const checkpoint &other) const\n{\n    return height_ == other.height_ && hash_ == other.hash_;\n}\n\nstd::istream &operator>>(std::istream &input, checkpoint &argument)\n{\n    std::string value;\n    input >> value;\n\n    // std::regex requires gcc 4.9, so we are using boost::regex for now.\n    static const regex regular(\"^([0-9a-f]{64})(:([0-9]{1,20}))?$\");\n\n    sregex_iterator it(value.begin(), value.end(), regular), end;\n    if (it == end)\n    {\n        BOOST_THROW_EXCEPTION(invalid_option_value(value));\n    }\n\n    const auto &match = *it;\n    if (!decode_hash(argument.hash_, match[1]))\n    {\n        BOOST_THROW_EXCEPTION(invalid_option_value(value));\n    }\n\n    try\n    {\n        argument.height_ = lexical_cast<size_t>(match[3]);\n    }\n    catch (const boost::exception &)\n    {\n        BOOST_THROW_EXCEPTION(invalid_option_value(value));\n    }\n\n    return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const checkpoint &argument)\n{\n    output << encode_hash(argument.hash()) << \":\" << argument.height();\n    return output;\n}\n\n} // namespace config\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/config/directory.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/config/directory.hpp>\n\n#include <string>\n#include <UChain/coin/unicode/unicode.hpp>\n\n#ifdef _MSC_VER\n#include <shlobj.h>\n#include <windows.h>\n#endif\n\nnamespace libbitcoin\n{\nnamespace config\n{\n\n// Returns empty string if unable to retrieve (including when not in Windows).\nstd::string windows_config_directory()\n{\n#ifdef _MSC_VER\n    wchar_t directory[MAX_PATH];\n    const auto result = SHGetFolderPathW(NULL, CSIDL_COMMON_APPDATA, NULL,\n                                         SHGFP_TYPE_CURRENT, directory);\n\n    if (SUCCEEDED(result))\n        return to_utf8(directory);\n#endif\n    return \"\";\n}\n\n} // namespace config\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/config/endpoint.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/config/endpoint.hpp>\n\n#include <cstdint>\n#include <iostream>\n#include <regex>\n#include <string>\n#include <boost/lexical_cast.hpp>\n#include <boost/program_options.hpp>\n#include <boost/regex.hpp>\n#include <UChain/coin/config/endpoint.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/formats/base_16.hpp>\n#include <UChain/coin/utility/asio.hpp>\n\nnamespace libbitcoin\n{\nnamespace config\n{\n\nusing namespace boost;\nusing namespace boost::program_options;\n\nendpoint::endpoint()\n    : endpoint(\"localhost\")\n{\n}\n\nendpoint::endpoint(const endpoint &other)\n    : scheme_(other.scheme()), host_(other.host()), port_(other.port())\n{\n}\n\nendpoint::endpoint(const std::string &value)\n{\n    std::stringstream(value) >> *this;\n}\n\nendpoint::endpoint(const authority &authority)\n    : endpoint(authority.to_string())\n{\n}\n\nendpoint::endpoint(const std::string &host, uint16_t port)\n    : host_(host), port_(port)\n{\n}\n\nendpoint::endpoint(const asio::endpoint &host)\n    : endpoint(host.address(), host.port())\n{\n}\n\nendpoint::endpoint(const asio::address &ip, uint16_t port)\n    : host_(ip.to_string()), port_(port)\n{\n}\n\nconst std::string &endpoint::scheme() const\n{\n    return scheme_;\n}\n\nconst std::string &endpoint::host() const\n{\n    return host_;\n}\n\nuint16_t endpoint::port() const\n{\n    return port_;\n}\n\nstd::string endpoint::to_string() const\n{\n    std::stringstream value;\n    value << *this;\n    return value.str();\n}\n\nendpoint::operator bool() const\n{\n    // Return true if initialized.\n    // TODO: this is a quick hack, along with http/https.\n    return !scheme_.empty();\n}\n\nbool endpoint::operator==(const endpoint &other) const\n{\n    return host_ == other.host_ && port_ == other.port_ &&\n           scheme_ == other.scheme_;\n}\n\nstd::istream &operator>>(std::istream &input, endpoint &argument)\n{\n    std::string value;\n    input >> value;\n\n    // std::regex requires gcc 4.9, so we are using boost::regex for now.\n    static const regex regular(\"^((tcp|udp|http|https|inproc):\\\\/\\\\/)?\"\n                               \"(\\\\[([0-9a-f:\\\\.]+)]|([^:]+))(:([0-9]{1,5}))?$\");\n\n    sregex_iterator it(value.begin(), value.end(), regular), end;\n    if (it == end)\n    {\n        BOOST_THROW_EXCEPTION(invalid_option_value(value));\n    }\n\n    const auto &match = *it;\n    argument.scheme_ = match[2];\n    argument.host_ = match[3];\n    std::string port(match[7]);\n\n    try\n    {\n        argument.port_ = port.empty() ? 0 : lexical_cast<uint16_t>(port);\n    }\n    catch (const boost::exception &)\n    {\n        BOOST_THROW_EXCEPTION(invalid_option_value(value));\n    }\n\n    return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const endpoint &argument)\n{\n    if (!argument.scheme().empty())\n        output << argument.scheme() << \"://\";\n\n    output << argument.host();\n\n    if (argument.port() != 0)\n        output << \":\" << argument.port();\n\n    return output;\n}\n\n} // namespace config\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/config/hash160.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/config/hash160.hpp>\n\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <boost/program_options.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/formats/base_16.hpp>\n#include <UChain/coin/math/hash.hpp>\n\nnamespace libbitcoin\n{\nnamespace config\n{\n\nhash160::hash160()\n    : value_(null_short_hash)\n{\n}\n\nhash160::hash160(const std::string &hexcode)\n{\n  std::stringstream(hexcode) >> *this;\n}\n\nhash160::hash160(const short_hash &value)\n    : value_(value)\n{\n}\n\nhash160::hash160(const hash160 &other)\n    : hash160(other.value_)\n{\n}\n\nhash160::operator const short_hash &() const\n{\n  return value_;\n}\n\nstd::istream &operator>>(std::istream &input, hash160 &argument)\n{\n  std::string hexcode;\n  input >> hexcode;\n\n  if (!decode_base16(argument.value_, hexcode))\n  {\n    using namespace boost::program_options;\n    BOOST_THROW_EXCEPTION(invalid_option_value(hexcode));\n  }\n\n  return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const hash160 &argument)\n{\n  output << encode_base16(argument.value_);\n  return output;\n}\n\n} // namespace config\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/config/hash256.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/config/hash256.hpp>\n\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <boost/program_options.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/formats/base_16.hpp>\n#include <UChain/coin/math/hash.hpp>\n\nnamespace libbitcoin\n{\nnamespace config\n{\n\nhash256::hash256()\n    : value_(null_hash)\n{\n}\n\nhash256::hash256(const std::string &hexcode)\n    : hash256()\n{\n  std::stringstream(hexcode) >> *this;\n}\n\nhash256::hash256(const hash_digest &value)\n    : value_(value)\n{\n}\n\nhash256::hash256(const hash256 &other)\n    : hash256(other.value_)\n{\n}\n\nstd::string hash256::to_string() const\n{\n  std::stringstream value;\n  value << *this;\n  return value.str();\n}\n\nhash256::operator const hash_digest &() const\n{\n  return value_;\n}\n\nstd::istream &operator>>(std::istream &input, hash256 &argument)\n{\n  std::string hexcode;\n  input >> hexcode;\n\n  if (!decode_hash(argument.value_, hexcode))\n  {\n    using namespace boost::program_options;\n    BOOST_THROW_EXCEPTION(invalid_option_value(hexcode));\n  }\n\n  return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const hash256 &argument)\n{\n  output << encode_hash(argument.value_);\n  return output;\n}\n\n} // namespace config\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/config/parameter.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/config/parameter.hpp>\n\n#include <iostream>\n#include <boost/algorithm/string.hpp>\n#include <boost/program_options.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/collection.hpp>\n#include <UChain/coin/utility/string.hpp>\n\nnamespace po = boost::program_options;\nusing namespace libbitcoin::config;\n\nconst int parameter::not_positional = -1;\nconst char parameter::no_short_name = 0x00;\nconst char parameter::option_prefix_char = '-';\n\n// 100% component coverage, common scenarios.\n// A required argument may only be preceeded by required arguments.\n// Requiredness may be in error if the metadata is inconsistent.\nvoid parameter::initialize(const po::option_description &option,\n                           const argument_list &arguments)\n{\n    set_position(position(option, arguments));\n    set_args_limit(arguments_limit(get_position(), option, arguments));\n    set_required(option.semantic()->is_required());\n    set_long_name(option.long_name());\n    set_short_name(short_name(option));\n    set_description(option.description());\n    set_format_name(option.format_name());\n    set_format_parameter(option.format_parameter());\n}\n\n// 100% component coverage, all three scenarios (long, short, both)\nint parameter::position(const po::option_description &option,\n                        const argument_list &arguments) const\n{\n    return find_pair_position(arguments, option.long_name());\n}\n\n// 100% unit coverage, all three scenarios (long, short, both)\nchar parameter::short_name(const po::option_description &option) const\n{\n    // This call requires boost 1.50, don't use it.\n    //auto name = option.canonical_display_name(\n    //    search_options::dashed_short_prefer_short);\n\n    // This is a substitute that allows us to use boost 1.49 for libbitcoin.\n    const auto name = split(option.format_name()).front();\n    auto is_short_name = name[0] == option_prefix_char &&\n                         name[1] != option_prefix_char;\n\n    return is_short_name ? name[1] : no_short_name;\n}\n\n// 100% component coverage\nunsigned parameter::arguments_limit(int position,\n                                    const po::option_description &option, const argument_list &arguments) const\n{\n    if (position == parameter::not_positional)\n        return option.semantic()->max_tokens();\n\n    return arguments[position].second;\n}\n"
  },
  {
    "path": "src/UChain/coin/config/parser.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/config/parser.hpp>\n\n#include <string>\n#include <sstream>\n#include <boost/algorithm/string.hpp>\n#include <boost/filesystem/path.hpp>\n#include <boost/program_options.hpp>\n#include <boost/throw_exception.hpp>\n#include <UChain/coin/unicode/ifstream.hpp>\n#include <UChainService/txs/utility/path.hpp>\n\nnamespace libbitcoin\n{\nnamespace config\n{\n\nusing namespace boost::filesystem;\nusing namespace boost::program_options;\nusing namespace boost::system;\n\n// The error is obtained from boost, which circumvents our localization.\n// English-only hack to patch missing arg name in boost exception message.\nstd::string parser::format_invalid_parameter(const std::string &message)\n{\n    std::string clean_message(message);\n    boost::replace_all(clean_message, \"for option is invalid\", \"is invalid\");\n    return \"{\\\"error\\\":\\\"parser \" + clean_message + \"\\\"}\";\n}\n\npath parser::get_config_option(variables_map &variables,\n                               const std::string &name)\n{\n    // read config from the map so we don't require an early notify\n    const auto &config = variables[name];\n\n    // prevent exception in the case where the config variable is not set\n    if (config.empty())\n        return path();\n\n    return config.as<path>();\n}\n\nbool parser::get_option(variables_map &variables, const std::string &name)\n{\n    // Read settings from the map so we don't require an early notify call.\n    const auto &variable = variables[name];\n\n    // prevent exception in the case where the settings variable is not set.\n    if (variable.empty())\n        return false;\n\n    return variable.as<bool>();\n}\n\nvoid parser::load_command_variables(variables_map &variables, int argc,\n                                    const char *argv[])\n{\n    const auto options = load_options();\n    const auto arguments = load_arguments();\n    auto command_parser = command_line_parser(argc, argv).options(options)\n                              /*.allow_unregistered()*/.positional(arguments);\n    store(command_parser.run(), variables);\n}\n\nvoid parser::load_environment_variables(variables_map &variables,\n                                        const std::string &prefix)\n{\n    const auto &environment_variables = load_environment();\n    const auto environment = parse_environment(environment_variables, prefix);\n    store(environment, variables);\n}\n\nbool parser::load_configuration_variables(variables_map &variables,\n                                          const std::string &option_name)\n{\n    const auto config_settings = load_settings();\n    auto config_path = get_config_option(variables, option_name) == \"uc.conf\"\n                           ? default_data_path() / get_config_option(variables, option_name)\n                           : get_config_option(variables, option_name);\n\n    // If the existence test errors out we pretend there's no file :/.\n    error_code code;\n    if (!config_path.empty() && exists(config_path, code))\n    {\n        const auto &path = config_path.string();\n        bc::ifstream file(path);\n\n        if (!file.good())\n        {\n            BOOST_THROW_EXCEPTION(reading_file(path.c_str()));\n        }\n\n        const auto config = parse_config_file(file, config_settings);\n        store(config, variables);\n        return true;\n    }\n\n    // Loading from an empty stream causes the defaults to populate.\n    std::stringstream stream;\n    const auto config = parse_config_file(stream, config_settings);\n    store(config, variables);\n    return false;\n}\n\n} // namespace config\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/config/printer.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/config/printer.hpp>\n\n#include <algorithm>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <boost/algorithm/string.hpp>\n#include <boost/format.hpp>\n#include <boost/program_options.hpp>\n#include <UChain/coin/config/parameter.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/collection.hpp>\n#include <UChain/coin/utility/string.hpp>\n\n// We built this because po::options_description.print() sucks.\n\n// TODO: parameterize these localized values.\n// Various shared localizable strings.\n#define BC_PRINTER_ARGUMENT_TABLE_HEADER \"Arguments (positional):\"\n#define BC_PRINTER_DESCRIPTION_FORMAT \"Info: %1%\"\n#define BC_PRINTER_OPTION_TABLE_HEADER \"Options (named):\"\n#define BC_PRINTER_USAGE_FORMAT \"Usage: %1% %2% %3%\"\n#define BC_PRINTER_SETTINGS_TABLE_HEADER \"Configuration Settings:\"\n#define BC_PRINTER_VALUE_TEXT \"value\"\n\n// Not localizable formatters.\n#define BC_PRINTER_USAGE_OPTION_MULTIPLE_FORMAT \" [--%1% %2%]...\"\n#define BC_PRINTER_USAGE_OPTION_OPTIONAL_FORMAT \" [--%1% %2%]\"\n#define BC_PRINTER_USAGE_OPTION_REQUIRED_FORMAT \" --%1% %2%\"\n#define BC_PRINTER_USAGE_OPTION_TOGGLE_SHORT_FORMAT \" [-%1%]\"\n#define BC_PRINTER_USAGE_OPTION_TOGGLE_LONG_FORMAT \" [--%1%]\"\n\n#define BC_PRINTER_USAGE_ARGUMENT_MULTIPLE_FORMAT \" [%1%]...\"\n#define BC_PRINTER_USAGE_ARGUMENT_OPTIONAL_FORMAT \" [%1%]\"\n#define BC_PRINTER_USAGE_ARGUMENT_REQUIRED_FORMAT \" %1%\"\n\n#define BC_PRINTER_TABLE_OPTION_FORMAT \"-%1% [--%2%]\"\n#define BC_PRINTER_TABLE_OPTION_LONG_FORMAT \"--%1%\"\n#define BC_PRINTER_TABLE_OPTION_SHORT_FORMAT \"-%1%\"\n\n#define BC_PRINTER_TABLE_ARGUMENT_FORMAT \"%1%\"\n\n#define BC_PRINTER_SETTING_SECTION_FORMAT \"[%1%]\\n\"\n#define BC_PRINTER_SETTING_COMMENT_FORMAT \"# %1%\\n\"\n#define BC_PRINTER_SETTING_MULTIPLE_FORMAT \"%1% = <%2%>\\n%1% = <%2%>\\n...\\n\"\n#define BC_PRINTER_SETTING_OPTIONAL_FORMAT \"%1% = <%2%>\\n\"\n#define BC_PRINTER_SETTING_REQUIRED_FORMAT \"%1% = %2%\\n\"\n\nnamespace po = boost::program_options;\nusing namespace libbitcoin;\nusing namespace libbitcoin::config;\nusing boost::format;\n\nconst int printer::max_arguments = 256;\n\nprinter::printer(const po::options_description &options,\n                 const po::positional_options_description &arguments,\n                 const std::string &application, const std::string &description,\n                 const std::string &command)\n    : options_(options), arguments_(arguments), application_(application),\n      description_(description), command_(command)\n{\n}\n\nprinter::printer(const po::options_description &settings,\n                 const std::string &application, const std::string &description)\n    : options_(settings), application_(application), description_(description)\n{\n}\n\n/* Formatters */\n\n// 100% component tested.\nstatic void enqueue_fragment(std::string &fragment,\n                             std::vector<std::string> &column)\n{\n    if (!fragment.empty())\n        column.push_back(fragment);\n}\n\n// 100% component tested.\nstd::vector<std::string> printer::columnize(const std::string &paragraph,\n                                            size_t width)\n{\n    const auto words = split(paragraph, \" \", false);\n\n    std::string fragment;\n    std::vector<std::string> column;\n\n    for (const auto &word : words)\n    {\n        if (!fragment.empty() && (word.length() + fragment.length() < width))\n        {\n            fragment += BC_SENTENCE_DELIMITER + word;\n            continue;\n        }\n\n        enqueue_fragment(fragment, column);\n        fragment = word;\n    }\n\n    enqueue_fragment(fragment, column);\n    return column;\n}\n\n// 100% component tested.\nstatic std::string format_row_name(const parameter &value)\n{\n    // We hack in upper case for all positional args because of a bug in\n    // boost that requires environment variable options to be lower case\n    // in order to match any case environment variable, at least on Windows.\n    // This is a problem when composing with a command-line argument that\n    // wants to be upper case but must match in case with the env var option.\n\n    if (value.get_position() != parameter::not_positional)\n        return (format(BC_PRINTER_TABLE_ARGUMENT_FORMAT) %\n                boost::to_upper_copy(value.get_long_name()))\n            .str();\n    else if (value.get_short_name() == parameter::no_short_name)\n        return (format(BC_PRINTER_TABLE_OPTION_LONG_FORMAT) %\n                value.get_long_name())\n            .str();\n    else if (value.get_long_name().empty())\n        return (format(BC_PRINTER_TABLE_OPTION_SHORT_FORMAT) %\n                value.get_short_name())\n            .str();\n    else\n        return (format(BC_PRINTER_TABLE_OPTION_FORMAT) %\n                value.get_short_name() % value.get_long_name())\n            .str();\n}\n\n// 100% component tested.\nstatic bool match_positional(bool positional, const parameter &value)\n{\n    auto positioned = value.get_position() != parameter::not_positional;\n    return positioned == positional;\n}\n\n// 100% component tested.\n// This formats to 73 char width as: [ 20 | ' ' | 52 | '\\n' ]\n// GitHub code examples start horizontal scroll after 73 characters.\nstd::string printer::format_parameters_table(bool positional)\n{\n    std::stringstream output;\n    const auto &parameters = get_parameters();\n    format table_format(\"%-20s %-52s\\n\");\n\n    for (const auto &parameter : parameters)\n    {\n        // Skip positional arguments if not positional.\n        if (!match_positional(positional, parameter))\n            continue;\n\n        // Get the formatted parameter name.\n        auto name = format_row_name(parameter);\n\n        // Build a column for the description.\n        const auto rows = columnize(parameter.get_description(), 52);\n\n        // If there is no description the command is not output!\n        for (const auto &row : rows)\n        {\n            output << table_format % name % row;\n\n            // The name is only set in the first row.\n            name.clear();\n        }\n    }\n\n    return output.str();\n}\n\n// This formats to 73 char width: [ 73 | '\\n' ]\n// GitHub code examples start horizontal scroll after 73 characters.\nstd::string printer::format_paragraph(const std::string &paragraph)\n{\n    std::stringstream output;\n    format paragraph_format(\"%-73s\\n\");\n\n    const auto lines = columnize(paragraph, 73);\n\n    for (const auto &line : lines)\n        output << paragraph_format % line;\n\n    return output.str();\n}\n\nstatic std::string format_setting(const parameter &value,\n                                  const std::string &name)\n{\n    // A required argument may only be preceeded by required arguments.\n    // Requiredness may be in error if the metadata is inconsistent.\n    auto required = value.get_required();\n\n    // In terms of formatting we also treat multivalued as not required.\n    auto optional = value.get_args_limit() == 1;\n\n    std::string formatter;\n    if (required)\n        formatter = BC_PRINTER_SETTING_REQUIRED_FORMAT;\n    else if (optional)\n        formatter = BC_PRINTER_SETTING_OPTIONAL_FORMAT;\n    else\n        formatter = BC_PRINTER_SETTING_MULTIPLE_FORMAT;\n\n    return (format(formatter) % name % BC_PRINTER_VALUE_TEXT).str();\n}\n\n// Requires a single period in each setting (i.e. no unnamed sections).\nstatic void split_setting_name(const parameter &value, std::string &name,\n                               std::string &section)\n{\n    const auto tokens = split(value.get_long_name(), \".\");\n    if (tokens.size() != 2)\n    {\n        section.clear();\n        name.clear();\n        return;\n    }\n\n    section = tokens[0];\n    name = tokens[1];\n}\n\nstd::string printer::format_settings_table()\n{\n    std::string name;\n    std::string section;\n    std::stringstream output;\n    std::string preceding_section;\n\n    const auto &parameters = get_parameters();\n    for (const auto &parameter : parameters)\n    {\n        split_setting_name(parameter, name, section);\n        if (section.empty())\n        {\n            BITCOIN_ASSERT_MSG(false, \"Invalid config setting metadata.\");\n            continue;\n        }\n\n        if (section != preceding_section)\n        {\n            output << std::endl;\n            if (!section.empty())\n            {\n                output << format(BC_PRINTER_SETTING_SECTION_FORMAT) % section;\n                preceding_section = section;\n            }\n        }\n\n        output << format(BC_PRINTER_SETTING_COMMENT_FORMAT) %\n                      parameter.get_description();\n        output << format_setting(parameter, name);\n    }\n\n    return output.str();\n}\n\nstd::string printer::format_usage()\n{\n    // USAGE: bx COMMAND [-hvt] -n VALUE [-m VALUE] [-w VALUE]... REQUIRED\n    // [OPTIONAL] [MULTIPLE]...\n    auto usage = format(BC_PRINTER_USAGE_FORMAT) % get_application() %\n                 get_command() % format_usage_parameters();\n\n    return format_paragraph(usage.str());\n}\n\nstd::string printer::format_description()\n{\n    // Info: %1%\n    auto description = format(BC_PRINTER_DESCRIPTION_FORMAT) %\n                       get_description();\n    return format_paragraph(description.str());\n}\n\n// 100% component tested.\nstd::string printer::format_usage_parameters()\n{\n    std::string toggle_short_options;\n    std::vector<std::string> toggle_long_options;\n    std::vector<std::string> required_options;\n    std::vector<std::string> optional_options;\n    std::vector<std::string> multiple_options;\n    std::vector<std::string> required_arguments;\n    std::vector<std::string> optional_arguments;\n    std::vector<std::string> multiple_arguments;\n\n    const auto &parameters = get_parameters();\n\n    for (const auto &parameter : parameters)\n    {\n        // A required argument may only be preceeded by required arguments.\n        // Requiredness may be in error if the metadata is inconsistent.\n        auto required = parameter.get_required();\n\n        // Options are named and args are positional.\n        auto option = parameter.get_position() == parameter::not_positional;\n\n        // In terms of formatting we also treat multivalued as not required.\n        auto optional = parameter.get_args_limit() == 1;\n\n        // This will capture only options set to zero_tokens().\n        auto toggle = parameter.get_args_limit() == 0;\n\n        // A toggle with a short name gets mashed up in group.\n        auto is_short = parameter.get_short_name() != parameter::no_short_name;\n\n        const auto &long_name = parameter.get_long_name();\n\n        if (toggle)\n        {\n            if (is_short)\n                toggle_short_options.push_back(parameter.get_short_name());\n            else\n                toggle_long_options.push_back(long_name);\n        }\n        else if (option)\n        {\n            if (required)\n                required_options.push_back(long_name);\n            else if (optional)\n                optional_options.push_back(long_name);\n            else\n                multiple_options.push_back(long_name);\n        }\n        else\n        {\n            // to_upper_copy is a hack for boost bug, see format_row_name.\n            if (required)\n                required_arguments.push_back(boost::to_upper_copy(long_name));\n            else if (optional)\n                optional_arguments.push_back(boost::to_upper_copy(long_name));\n            else\n                multiple_arguments.push_back(boost::to_upper_copy(long_name));\n        }\n    }\n\n    std::stringstream usage;\n\n    if (!toggle_short_options.empty())\n        usage << format(BC_PRINTER_USAGE_OPTION_TOGGLE_SHORT_FORMAT) %\n                     toggle_short_options;\n\n    for (const auto &required_option : required_options)\n        usage << format(BC_PRINTER_USAGE_OPTION_REQUIRED_FORMAT) %\n                     required_option % BC_PRINTER_VALUE_TEXT;\n\n    for (const auto &toggle_long_option : toggle_long_options)\n        usage << format(BC_PRINTER_USAGE_OPTION_TOGGLE_LONG_FORMAT) %\n                     toggle_long_option;\n\n    for (const auto &optional_option : optional_options)\n        usage << format(BC_PRINTER_USAGE_OPTION_OPTIONAL_FORMAT) %\n                     optional_option % BC_PRINTER_VALUE_TEXT;\n\n    for (const auto &multiple_option : multiple_options)\n        usage << format(BC_PRINTER_USAGE_OPTION_MULTIPLE_FORMAT) %\n                     multiple_option % BC_PRINTER_VALUE_TEXT;\n\n    for (const auto &required_argument : required_arguments)\n        usage << format(BC_PRINTER_USAGE_ARGUMENT_REQUIRED_FORMAT) %\n                     required_argument;\n\n    for (const auto &optional_argument : optional_arguments)\n        usage << format(BC_PRINTER_USAGE_ARGUMENT_OPTIONAL_FORMAT) %\n                     optional_argument;\n\n    for (const auto &multiple_argument : multiple_arguments)\n        usage << format(BC_PRINTER_USAGE_ARGUMENT_MULTIPLE_FORMAT) %\n                     multiple_argument;\n\n    return boost::trim_copy(usage.str());\n}\n\n/* Initialization */\n\n// 100% component tested.\nstatic void enqueue_name(int count, std::string &name, argument_list &names)\n{\n    if (count <= 0)\n        return;\n\n    if (count > printer::max_arguments)\n        count = -1;\n\n    names.push_back(argument_pair(name, count));\n}\n\n// 100% component tested.\n// This method just gives us a copy of arguments_metadata private state.\n// It would be nice if instead that state was public.\nvoid printer::generate_argument_names()\n{\n    // Member values\n    const auto &arguments = get_arguments();\n    auto &argument_names = get_argument_names();\n\n    argument_names.clear();\n    const auto max_total_arguments = arguments.max_total_count();\n\n    // Temporary values\n    std::string argument_name;\n    std::string previous_argument_name;\n    int max_previous_argument = 0;\n\n    // We must enumerate all arguments to get the full set of names and counts.\n    for (unsigned int position = 0; position < max_total_arguments &&\n                                    max_previous_argument <= max_arguments;\n         ++position)\n    {\n        argument_name = arguments.name_for_position(position);\n\n        // Initialize the first name as having a zeroth instance.\n        if (max_previous_argument == 0)\n            previous_argument_name = argument_name;\n\n        // This is a duplicate of the previous name, so increment the count.\n        if (argument_name == previous_argument_name)\n        {\n            ++max_previous_argument;\n            continue;\n        }\n\n        enqueue_name(max_previous_argument, previous_argument_name,\n                     argument_names);\n        previous_argument_name = argument_name;\n        max_previous_argument = 1;\n    }\n\n    // Save the previous name (if there is one).\n    enqueue_name(max_previous_argument, previous_argument_name,\n                 argument_names);\n}\n\n// 100% component tested.\nstatic bool compare_parameters(const parameter left, const parameter right)\n{\n    return left.get_format_name() < right.get_format_name();\n}\n\n// 100% component tested.\nvoid printer::generate_parameters()\n{\n    const auto &argument_names = get_argument_names();\n    const auto &options = get_options();\n    auto &parameters = get_parameters();\n\n    parameters.clear();\n\n    parameter param;\n    for (auto option_ptr : options.options())\n    {\n        param.initialize(*option_ptr, argument_names);\n\n        // Sort non-positonal parameters (i.e. options).\n        if (param.get_position() == parameter::not_positional)\n            insert_sorted(parameters, param, compare_parameters);\n        else\n            parameters.push_back(param);\n    }\n}\n\n// 100% component tested.\nvoid printer::initialize()\n{\n    generate_argument_names();\n    generate_parameters();\n}\n\n/* Printers */\n\nvoid printer::commandline(std::ostream &output)\n{\n    const auto &option_table = format_parameters_table(false);\n    const auto &argument_table = format_parameters_table(true);\n\n    // Don't write a header if a table is empty.\n    std::string option_table_header(option_table.empty() ? \"\" : BC_PRINTER_OPTION_TABLE_HEADER \"\\n\");\n    std::string argument_table_header(argument_table.empty() ? \"\" : BC_PRINTER_ARGUMENT_TABLE_HEADER \"\\n\");\n\n    output\n        << std::endl\n        << format_usage()\n        << std::endl\n        << format_description()\n        << std::endl\n        << option_table_header\n        << std::endl\n        << option_table\n        << std::endl\n        << argument_table_header\n        << std::endl\n        << argument_table;\n}\n\nvoid printer::settings(std::ostream &output)\n{\n    const auto &setting_table = format_settings_table();\n    const auto &setting_table_header = BC_PRINTER_SETTINGS_TABLE_HEADER;\n\n    output\n        << std::endl\n        << setting_table_header\n        << std::endl\n        << setting_table;\n}\n"
  },
  {
    "path": "src/UChain/coin/config/sodium.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/config/sodium.hpp>\n\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <boost/program_options.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/formats/base_85.hpp>\n#include <UChain/coin/math/hash.hpp>\n\nnamespace libbitcoin\n{\nnamespace config\n{\n\nsodium::sodium()\n    : value_(null_hash)\n{\n}\n\nsodium::sodium(const std::string &base85)\n{\n    std::stringstream(base85) >> *this;\n}\n\nsodium::sodium(const hash_digest &value)\n    : value_(value)\n{\n}\n\nsodium::sodium(const sodium &other)\n    : sodium(other.value_)\n{\n}\n\nsodium::operator hash_digest() const\n{\n    return value_;\n}\n\nsodium::operator data_slice() const\n{\n    return value_;\n}\n\nsodium::operator bool() const\n{\n    return value_ != null_hash;\n}\n\nstd::string sodium::to_string() const\n{\n    std::stringstream value;\n    value << *this;\n    return value.str();\n}\n\nstd::istream &operator>>(std::istream &input, sodium &argument)\n{\n    std::string base85;\n    input >> base85;\n\n    data_chunk out_value;\n    if (!decode_base85(out_value, base85) || out_value.size() != hash_size)\n    {\n        using namespace boost::program_options;\n        BOOST_THROW_EXCEPTION(invalid_option_value(base85));\n    }\n\n    std::copy(out_value.begin(), out_value.end(), argument.value_.begin());\n    return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const sodium &argument)\n{\n    std::string decoded;\n\n    // Z85 requires four byte alignment (hash_digest is 32).\n    /* bool */ encode_base85(decoded, argument.value_);\n\n    output << decoded;\n    return output;\n}\n\n} // namespace config\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/constants.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/constants.hpp>\n\nnamespace libbitcoin\n{\nuint32_t coinbase_maturity = 1;\n\nhash_number max_target()\n{\n    hash_number max_target;\n    max_target.set_compact(max_work_bits);\n    return max_target;\n}\n\nstd::string get_developer_community_address(bool is_testnet)\n{\n    std::string address(\"UNKAn2fsG5CPeP4s9mxTvJKSjmqqdwu3Tq\"); // developers address for mainnet\n    if (is_testnet)\n    {\n        address = \"tJNo92g6DavpaCZbYjrH45iQ8eAKnLqmms\"; // developers address for testnet\n    }\n    return address;\n}\n\nstd::string get_foundation_address(bool is_testnet)\n{\n    std::string address(\"UNfrtAxhJRi83PjTPjV3yNPKnjLYR22Bhx\"); // foundation address for mainnet\n    if (is_testnet)\n    {\n        address = \"tFzJJnso5tKDdwTiztMq1qMg1uHfqbbpq6\"; // foundation address for testnet\n    }\n    return address;\n}\n\nstd::string get_reward_pool_address(bool is_testnet)\n{\n    std::string address(\"UkwAarnHiVUoBi4mHupZ3GyLcVLDxPe9eo\"); // foundation address for mainnet\n    if (is_testnet)\n    {\n        address = \"tFzJJnso5tKDdwTiztMq1qMg1uHfqbbpq6\"; // foundation address for testnet\n    }\n    return address;\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/error.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/error.hpp>\n\n#include <boost/asio.hpp>\n#include <boost/system/error_code.hpp>\n#include <UChain/coin/compat.hpp>\n#include <UChain/coin/utility/log.hpp>\n\nusing namespace bc;\n\nclass error_category_impl\n    : public std::error_category\n{\n  public:\n    virtual const char *name() const BC_NOEXCEPT;\n    virtual std::string message(int ev) const BC_NOEXCEPT;\n    virtual std::error_condition default_error_condition(int ev)\n        const BC_NOEXCEPT;\n};\n\nstatic const error_category_impl &get_error_category_instance()\n{\n    static error_category_impl instance;\n    return instance;\n}\n\nconst char *error_category_impl::name() const BC_NOEXCEPT\n{\n    return \"bitcoin\";\n}\n\nstd::string error_category_impl::message(int ev) const BC_NOEXCEPT\n{\n    // TODO: use a static map (hash table)\n    // This text mapping may change without notice.\n    switch (ev)\n    {\n    case error::success:\n        return \"success\";\n\n    // network errors\n    case error::service_stopped:\n        return \"service is stopped\";\n    case error::operation_failed:\n        return \"operation failed\";\n\n    // blockchain errors\n    case error::not_found:\n        return \"object does not exist\";\n    case error::duplicate:\n        return \"matching previous object found\";\n    case error::unspent_output:\n        return \"unspent output\";\n    case error::unsupported_script_pattern:\n        return \"unsupport script pattern\";\n\n    // network errors (more)\n    case error::resolve_failed:\n        return \"resolving hostname failed\";\n    case error::network_unreachable:\n        return \"unable to reach remote host\";\n    case error::address_in_use:\n        return \"address already in use\";\n    case error::listen_failed:\n        return \"incoming connection failed\";\n    case error::accept_failed:\n        return \"connection acceptance failed\";\n    case error::bad_stream:\n        return \"bad data stream\";\n    case error::channel_timeout:\n        return \"connection timed out\";\n\n    // transaction pool\n    case error::blockchain_reorganized:\n        return \"transactions invalidated by blockchain reorganization\";\n    case error::pool_filled:\n        return \"forced removal of old transaction from pool overflow\";\n\n    // validate tx\n    case error::coinbase_transaction:\n        return \"coinbase transaction disallowed in memory pool\";\n    case error::is_not_standard:\n        return \"transaction is not standard\";\n    case error::invalid_input_script_lock_height:\n        return \"get coinage reward transaction input script lock heigh value error\";\n    case error::invalid_output_script_lock_height:\n        return \"get coinage reward transaction output script lock heigh value error\";\n    case error::double_spend:\n        return \"double spend of input\";\n    case error::input_not_found:\n        return \"input not found\";\n    case error::script_not_standard:\n        return \"script not standard\";\n    case error::transaction_version_error:\n        return \"transaction version error\";\n\n    // check_transaction()\n    case error::empty_transaction:\n        return \"transaction inputs or outputs are empty\";\n    case error::output_value_overflow:\n        return \"output value outside valid range\";\n    case error::invalid_coinbase_script_size:\n        return \"coinbase script is too small or large\";\n    case error::previous_output_null:\n        return \"non-coinbase transaction has input with null previous output\";\n\n    // validate block\n    case error::previous_block_invalid:\n        return \"previous block failed to validate\";\n\n    // check_block()\n    case error::size_limits:\n        return \"size limits failed\";\n    case error::proof_of_work:\n        return \"proof of work failed\";\n    case error::futuristic_timestamp:\n        return \"timestamp too far in the future\";\n    case error::first_not_coinbase:\n        return \"first transaction is not a coinbase\";\n    case error::extra_coinbases:\n        return \"more than one coinbase\";\n    case error::too_many_sigs:\n        return \"too many script signatures\";\n    case error::merkle_mismatch:\n        return \"merkle root mismatch\";\n\n    // accept_block()\n    case error::incorrect_proof_of_work:\n        return \"proof of work does not match bits field\";\n    case error::timestamp_too_early:\n        return \"block timestamp is too early\";\n    case error::non_final_transaction:\n        return \"block contains a non-final transaction\";\n    case error::checkpoints_failed:\n        return \"block hash rejected by checkpoint\";\n    case error::old_version_block:\n        return \"block version rejected at current height\";\n    case error::coinbase_height_mismatch:\n        return \"block height mismatch in coinbase\";\n\n    // connect_block()\n    case error::duplicate_or_spent:\n        return \"duplicate transaction with unspent outputs\";\n    case error::validate_inputs_failed:\n        return \"validation of inputs failed\";\n    case error::fees_out_of_range:\n        return \"fees are out of range\";\n    case error::coinbase_too_large:\n        return \"coinbase value is too large\";\n    case error::invalid_coinage_reward_coinbase:\n        return \"coinage reward coinbase value is wrong\";\n\n    // file system errors\n    case error::file_system:\n        return \"file system error\";\n\n    // network errors\n    case error::address_blocked:\n        return \"address is blocked by policy\";\n    case error::channel_stopped:\n        return \"channel is stopped\";\n    case error::not_satisfied:\n        return \"not satisfied\";\n\n    // token errors\n    case error::token_amount_overflow:\n        return \"token amount overflow\";\n    case error::token_amount_not_equal:\n        return \"token amount not equal\";\n    case error::token_symbol_not_match:\n        return \"token symbol not match\";\n    case error::token_symbol_invalid:\n        return \"token symbol invalid\";\n    case error::token_address_not_match:\n        return \"token asset address must be equal with output address\";\n    case error::token_exist:\n        return \"token exist\";\n    case error::token_not_exist:\n        return \"token not exist\";\n    case error::token_issue_error:\n        return \"issue token error\";\n    case error::token_secondaryissue_error:\n        return \"secondary issue token error\";\n    case error::token_secondaryissue_share_not_enough:\n        return \"user token share is not enought to secondary issue token \";\n    case error::token_secondaryissue_threshold_invalid:\n        return \"token secondaryissue tokenshare threshold value invalid\";\n\n    // uid errors\n    case error::uid_symbol_not_match:\n        return \"uid symbol not match\";\n    case error::uid_symbol_invalid:\n        return \"uid symbol invalid\";\n    case error::uid_exist:\n        return \"uid exist\";\n    case error::address_registered_uid:\n        return \"address already registered uid\";\n    case error::uid_func_not_actived:\n        return \"uid function has not been actived until block height is larger than 1130000\";\n    case error::uid_address_not_match:\n        return \"attach uid address must equal with output address\";\n    case error::uid_address_needed:\n        return \"uid address is needed but not supplied\";\n    case error::uid_not_exist:\n        return \"uid does not exist\";\n    case error::uid_input_error:\n        return \"uid input error\";\n    case error::uid_in_candidate:\n        return \"cannot transfer uid in candidates\";\n    case error::uid_multi_type_exist:\n        return \"uid attchment type can not be with some others\";\n    case error::attenuation_model_param_error:\n        return \"attenuation model parameter is wrong\";\n\n    // cert errors\n    case error::token_cert_error:\n        return \"token cert error\";\n    case error::token_cert_exist:\n        return \"token cert already exists\";\n    case error::token_cert_not_exist:\n        return \"token cert does not exist\";\n    case error::token_cert_not_provided:\n        return \"token cert is not provided\";\n    case error::token_cert_not_owned:\n        return \"token cert is not owned\";\n    case error::token_cert_issue_error:\n        return \"token cert issue error\";\n\n    case error::token_uid_registerr_not_match:\n        return \"attach touid must equal with token issuer or cert owner\";\n\n    case error::asset_invalid:\n        return \"asset is invalid\";\n    case error::uid_feature_not_activated:\n        return \"uid feature is not activated, it will be activated when block height is larger than 1270000\";\n\n    // candidate errors\n    case error::candidate_error:\n        return \"candidate token error\";\n    case error::candidate_exist:\n        return \"candidate token already exists\";\n    case error::candidate_register_error:\n        return \"candidate token register error\";\n    case error::candidate_symbol_invalid:\n        return \"candidate symbol invalid\";\n\n    //block ext\n    case error::first_coinbase_index_error:\n        return \"coinbase is not in the right turn\";\n\n    // unknown errors\n    case error::unknown:\n    default:\n        return \"unknown error\";\n    }\n}\n\n// We are not currently using this.\nstd::error_condition error_category_impl::default_error_condition(int ev)\n    const BC_NOEXCEPT\n{\n    return std::error_condition(ev, *this);\n}\n\nnamespace libbitcoin\n{\nnamespace error\n{\n\ncode make_error_code(error_code_t e)\n{\n    return code(e, get_error_category_instance());\n}\n\nstd::error_condition make_error_condition(error_condition_t e)\n{\n    return std::error_condition(e, get_error_category_instance());\n}\n\nerror_code_t boost_to_error_code(const boost_code &ec)\n{\n    namespace boost_error = boost::system::errc;\n\n#ifdef _MSC_VER\n    // TODO: is there a means to map ASIO errors to boost errors?\n    // ASIO codes are unique on Windows but not on Linux.\n    namespace asio_error = boost::asio::error;\n#endif\n    // TODO: use a static map (hash table)\n    switch (ec.value())\n    {\n        // There should be no boost mapping to the shutdown sentinel.\n        //    return error::service_stopped;\n\n    case boost_error::success:\n        return error::success;\n\n        // network errors\n#ifdef _MSC_VER\n    case asio_error::connection_aborted:\n    case asio_error::connection_reset:\n    case asio_error::operation_aborted:\n    case asio_error::operation_not_supported:\n#endif\n    case boost_error::connection_aborted:\n    case boost_error::connection_refused:\n    case boost_error::connection_reset:\n    case boost_error::not_connected:\n    case boost_error::operation_canceled:\n    case boost_error::operation_not_permitted:\n    case boost_error::operation_not_supported:\n    case boost_error::owner_dead:\n    case boost_error::permission_denied:\n        return error::operation_failed;\n\n#ifdef _MSC_VER\n    case asio_error::address_family_not_supported:\n#endif\n    case boost_error::address_family_not_supported:\n    case boost_error::address_not_available:\n    case boost_error::bad_address:\n    case boost_error::destination_address_required:\n        return error::resolve_failed;\n\n#ifdef _MSC_VER\n    case asio_error::connection_refused:\n#endif\n    case boost_error::broken_pipe:\n    case boost_error::host_unreachable:\n    case boost_error::network_down:\n    case boost_error::network_reset:\n    case boost_error::network_unreachable:\n    case boost_error::no_link:\n    case boost_error::no_protocol_option:\n    case boost_error::no_such_file_or_directory:\n    case boost_error::not_a_socket:\n    case boost_error::protocol_not_supported:\n    case boost_error::wrong_protocol_type:\n        return error::network_unreachable;\n\n    case boost_error::address_in_use:\n    case boost_error::already_connected:\n    case boost_error::connection_already_in_progress:\n    case boost_error::operation_in_progress:\n        return error::address_in_use;\n\n    case boost_error::bad_message:\n    case boost_error::illegal_byte_sequence:\n    case boost_error::io_error:\n    case boost_error::message_size:\n    case boost_error::no_message_available:\n    case boost_error::no_message:\n    case boost_error::no_stream_resources:\n    case boost_error::not_a_stream:\n    case boost_error::protocol_error:\n        return error::bad_stream;\n\n#ifdef _MSC_VER\n    case asio_error::timed_out:\n#endif\n    case boost_error::stream_timeout:\n    case boost_error::timed_out:\n        return error::channel_timeout;\n\n    // file system errors\n    case boost_error::cross_device_link:\n    case boost_error::bad_file_descriptor:\n    case boost_error::device_or_resource_busy:\n    case boost_error::directory_not_empty:\n    case boost_error::executable_format_error:\n    case boost_error::file_exists:\n    case boost_error::file_too_large:\n    case boost_error::filename_too_long:\n    case boost_error::invalid_seek:\n    case boost_error::is_a_directory:\n    case boost_error::no_space_on_device:\n    case boost_error::no_such_device:\n    case boost_error::no_such_device_or_address:\n    case boost_error::read_only_file_system:\n    // same as operation_would_block on non-windows\n    //case boost_error::resource_unavailable_try_again:\n    case boost_error::text_file_busy:\n    case boost_error::too_many_files_open:\n    case boost_error::too_many_files_open_in_system:\n    case boost_error::too_many_links:\n    case boost_error::too_many_symbolic_link_levels:\n        return error::file_system;\n\n    // unknown errors\n    case boost_error::argument_list_too_long:\n    case boost_error::argument_out_of_domain:\n    case boost_error::function_not_supported:\n    case boost_error::identifier_removed:\n    case boost_error::inappropriate_io_control_operation:\n    case boost_error::interrupted:\n    case boost_error::invalid_argument:\n    case boost_error::no_buffer_space:\n    case boost_error::no_child_process:\n    case boost_error::no_lock_available:\n    case boost_error::no_such_process:\n    case boost_error::not_a_directory:\n    case boost_error::not_enough_memory:\n    case boost_error::operation_would_block:\n    case boost_error::resource_deadlock_would_occur:\n    case boost_error::result_out_of_range:\n    case boost_error::state_not_recoverable:\n    case boost_error::value_too_large:\n    default:\n        return error::unknown;\n    }\n}\n\n} // namespace error\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/formats/base_10.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/formats/base_10.hpp>\n\n#include <iomanip>\n#include <sstream>\n#include <boost/algorithm/string.hpp>\n#include <UChain/coin/constants.hpp>\n\nnamespace libbitcoin\n{\n\n/**\n * Returns true if a character is one of `[0-9]`.\n *\n * The C standard library function `isdigit` depends on the current locale,\n * and doesn't necessarily correspond to the valid base10 encoding digits.\n * The Microsoft `isdigit` includes superscript characters like '²'\n * in some locales, for example.\n */\nstatic bool is_digit(const char c)\n{\n    return '0' <= c && c <= '9';\n}\n\ntemplate <char C>\nbool char_is(const char c)\n{\n    return c == C;\n}\n\nbool decode_base10(uint64_t &out, const std::string &amount,\n                   uint8_t decimal_places, bool strict)\n{\n    std::string value(amount);\n\n    // Get rid of the decimal point:\n    auto point = std::find(value.begin(), value.end(), '.');\n    if (point != value.end())\n        point = value.erase(point);\n\n    // Only digits should remain:\n    if (!std::all_of(value.begin(), value.end(), is_digit))\n        return false;\n\n    // Add digits to the end if there are too few:\n    auto actual_places = value.end() - point;\n    if (actual_places < decimal_places)\n        value.append(decimal_places - actual_places, '0');\n\n    // Remove digits from the end if there are too many:\n    bool round = false;\n    if (actual_places > decimal_places)\n    {\n        auto end = point + decimal_places;\n        round = !std::all_of(end, value.end(), char_is<'0'>);\n        value.erase(end, value.end());\n    }\n    if (strict && round)\n        return false;\n\n    // Convert to an integer:\n    std::istringstream stream(value);\n    uint64_t number = 0;\n    if (value.size() && !(stream >> number))\n        return false;\n\n    // Round and return:\n    if (round && number == max_uint64)\n        return false;\n    out = number + round;\n    return true;\n}\n\nstd::string encode_base10(uint64_t amount, uint8_t decimal_places)\n{\n    std::ostringstream stream;\n    stream << std::setfill('0') << std::setw(1 + decimal_places) << amount;\n\n    auto string = stream.str();\n    string.insert(string.size() - decimal_places, 1, '.');\n    boost::algorithm::trim_right_if(string, char_is<'0'>);\n    boost::algorithm::trim_right_if(string, char_is<'.'>);\n    return string;\n}\n\nbool btc_to_satoshi(uint64_t &satoshi, const std::string &btc)\n{\n    return decode_base10(satoshi, btc, btc_decimal_places);\n}\n\nstd::string satoshi_to_btc(uint64_t satoshi)\n{\n    return encode_base10(satoshi, btc_decimal_places);\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/formats/base_16.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/formats/base_16.hpp>\n\n#include <algorithm>\n#include <iomanip>\n#include <sstream>\n#include <boost/algorithm/string.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\n\nstd::string encode_base16(data_slice data)\n{\n    std::stringstream ss;\n    ss << std::hex << std::setfill('0');\n    for (int val : data)\n        ss << std::setw(2) << val;\n    return ss.str();\n}\n\nbool is_base16(const char c)\n{\n    return ('0' <= c && c <= '9') ||\n           ('A' <= c && c <= 'F') ||\n           ('a' <= c && c <= 'f');\n}\n\nstatic unsigned from_hex(const char c)\n{\n    if ('A' <= c && c <= 'F')\n        return 10 + c - 'A';\n    if ('a' <= c && c <= 'f')\n        return 10 + c - 'a';\n    return c - '0';\n}\n\nbool decode_base16(data_chunk &out, const std::string &in)\n{\n    // This prevents a last odd character from being ignored:\n    if (in.size() % 2 != 0)\n        return false;\n\n    data_chunk result(in.size() / 2);\n    if (!decode_base16_private(result.data(), result.size(), in.data()))\n        return false;\n\n    out = result;\n    return true;\n}\n\n// Bitcoin hash format (these are all reversed):\nstd::string encode_hash(hash_digest hash)\n{\n    std::reverse(hash.begin(), hash.end());\n    return encode_base16(hash);\n}\n\nbool decode_hash(hash_digest &out, const std::string &in)\n{\n    if (in.size() != 2 * hash_size)\n        return false;\n\n    hash_digest result;\n    if (!decode_base16_private(result.data(), result.size(), in.data()))\n        return false;\n\n    // Reverse:\n    std::reverse_copy(result.begin(), result.end(), out.begin());\n    return true;\n}\n\nhash_digest hash_literal(const char (&string)[2 * hash_size + 1])\n{\n    hash_digest out;\n    DEBUG_ONLY(const auto success =)\n    decode_base16_private(out.data(),\n                          out.size(), string);\n    BITCOIN_ASSERT(success);\n    std::reverse(out.begin(), out.end());\n    return out;\n}\n\n// For support of template implementation only, do not call directly.\nbool decode_base16_private(uint8_t *out, size_t out_size, const char *in)\n{\n    if (!std::all_of(in, in + 2 * out_size, is_base16))\n        return false;\n\n    for (size_t i = 0; i < out_size; ++i)\n    {\n        out[i] = (from_hex(in[0]) << 4) + from_hex(in[1]);\n        in += 2;\n    }\n\n    return true;\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/formats/base_58.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/formats/base_58.hpp>\n\n#include <boost/algorithm/string.hpp>\n#include <UChain/coin/utility/assert.hpp>\n\nnamespace libbitcoin\n{\n\nconst std::string base58_chars =\n    \"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz\";\n\nbool is_base58(const char ch)\n{\n    // This works because the base58 characters happen to be in sorted order\n    return std::binary_search(base58_chars.begin(), base58_chars.end(), ch);\n}\n\nbool is_base58(const std::string &text)\n{\n    const auto test = [](const char ch) {\n        return is_base58(ch);\n    };\n\n    return std::all_of(text.begin(), text.end(), test);\n}\n\ntemplate <typename Data>\nauto search_first_nonzero(const Data &data) -> decltype(data.cbegin())\n{\n    auto first_nonzero = data.cbegin();\n    while (first_nonzero != data.end() && *first_nonzero == 0)\n        ++first_nonzero;\n\n    return first_nonzero;\n}\n\nsize_t count_leading_zeros(data_slice unencoded)\n{\n    // Skip and count leading '1's.\n    size_t leading_zeros = 0;\n    for (const uint8_t byte : unencoded)\n    {\n        if (byte != 0)\n            break;\n\n        ++leading_zeros;\n    }\n\n    return leading_zeros;\n}\n\nvoid pack_value(data_chunk &indexes, size_t carry)\n{\n    // Apply \"b58 = b58 * 256 + ch\".\n    for (auto it = indexes.rbegin(); it != indexes.rend(); ++it)\n    {\n        carry += 256 * (*it);\n        *it = carry % 58;\n        carry /= 58;\n    }\n\n    BITCOIN_ASSERT(carry == 0);\n}\n\nstd::string encode_base58(data_slice unencoded)\n{\n    size_t leading_zeros = count_leading_zeros(unencoded);\n\n    // size = log(256) / log(58), rounded up.\n    const size_t number_nonzero = unencoded.size() - leading_zeros;\n    const size_t indexes_size = number_nonzero * 138 / 100 + 1;\n\n    // Allocate enough space in big-endian base58 representation.\n    data_chunk indexes(indexes_size);\n\n    // Process the bytes.\n    for (auto it = unencoded.begin() + leading_zeros;\n         it != unencoded.end(); ++it)\n    {\n        pack_value(indexes, *it);\n    }\n\n    // Skip leading zeroes in base58 result.\n    auto first_nonzero = search_first_nonzero(indexes);\n\n    // Translate the result into a string.\n    std::string encoded;\n    const size_t estimated_size = leading_zeros +\n                                  (indexes.end() - first_nonzero);\n    encoded.reserve(estimated_size);\n    encoded.assign(leading_zeros, '1');\n\n    // Set actual main bytes.\n    for (auto it = first_nonzero; it != indexes.end(); ++it)\n    {\n        const size_t index = *it;\n        encoded += base58_chars[index];\n    }\n\n    return encoded;\n}\n\nsize_t count_leading_zeros(const std::string &encoded)\n{\n    // Skip and count leading '1's.\n    size_t leading_zeros = 0;\n    for (const uint8_t digit : encoded)\n    {\n        if (digit != base58_chars[0])\n            break;\n\n        ++leading_zeros;\n    }\n\n    return leading_zeros;\n}\n\nvoid unpack_char(data_chunk &data, size_t carry)\n{\n    for (auto it = data.rbegin(); it != data.rend(); it++)\n    {\n        carry += 58 * (*it);\n        *it = carry % 256;\n        carry /= 256;\n    }\n\n    BITCOIN_ASSERT(carry == 0);\n}\n\nbool decode_base58(data_chunk &out, const std::string &in)\n{\n    // Trim spaces and newlines around the string.\n    const auto leading_zeros = count_leading_zeros(in);\n\n    // log(58) / log(256), rounded up.\n    const size_t data_size = in.size() * 733 / 1000 + 1;\n\n    // Allocate enough space in big-endian base256 representation.\n    data_chunk data(data_size);\n\n    // Process the characters.\n    for (auto it = in.begin() + leading_zeros; it != in.end(); ++it)\n    {\n        const auto carry = base58_chars.find(*it);\n        if (carry == std::string::npos)\n            return false;\n\n        unpack_char(data, carry);\n    }\n\n    // Skip leading zeroes in data.\n    auto first_nonzero = search_first_nonzero(data);\n\n    // Copy result into output vector.\n    data_chunk decoded;\n    const size_t estimated_size = leading_zeros + (data.end() - first_nonzero);\n    decoded.reserve(estimated_size);\n    decoded.assign(leading_zeros, 0x00);\n    decoded.insert(decoded.end(), first_nonzero, data.cend());\n\n    out = decoded;\n    return true;\n}\n\n// For support of template implementation only, do not call directly.\nbool decode_base58_private(uint8_t *out, size_t out_size, const char *in)\n{\n    data_chunk buffer;\n    if (!decode_base58(buffer, in) || buffer.size() != out_size)\n        return false;\n\n    for (size_t i = 0; i < out_size; ++i)\n        out[i] = buffer[i];\n\n    return true;\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/formats/base_64.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/formats/base_64.hpp>\n\n#include <cstdint>\n#include <string>\n#include <UChain/coin/utility/data.hpp>\n\n// This implementation derived from public domain:\n// en.wikibooks.org/wiki/Algorithm_Implementation/Miscellaneous/Base64\n\nnamespace libbitcoin\n{\n\nconst static char pad = '=';\n\nconst static char table[] =\n    \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\nstd::string encode_base64(data_slice unencoded)\n{\n    std::string encoded;\n    const auto size = unencoded.size();\n    encoded.reserve(((size / 3) + (size % 3 > 0)) * 4);\n\n    uint32_t value;\n    auto cursor = unencoded.begin();\n    for (size_t position = 0; position < size / 3; position++)\n    {\n        // Convert to big endian.\n        value = (*cursor++) << 16;\n\n        value += (*cursor++) << 8;\n        value += (*cursor++);\n        encoded.append(1, table[(value & 0x00FC0000) >> 18]);\n        encoded.append(1, table[(value & 0x0003F000) >> 12]);\n        encoded.append(1, table[(value & 0x00000FC0) >> 6]);\n        encoded.append(1, table[(value & 0x0000003F) >> 0]);\n    }\n\n    switch (size % 3)\n    {\n    case 1:\n        // Convert to big endian.\n        value = (*cursor++) << 16;\n\n        encoded.append(1, table[(value & 0x00FC0000) >> 18]);\n        encoded.append(1, table[(value & 0x0003F000) >> 12]);\n        encoded.append(2, pad);\n        break;\n    case 2:\n        // Convert to big endian.\n        value = (*cursor++) << 16;\n\n        value += (*cursor++) << 8;\n        encoded.append(1, table[(value & 0x00FC0000) >> 18]);\n        encoded.append(1, table[(value & 0x0003F000) >> 12]);\n        encoded.append(1, table[(value & 0x00000FC0) >> 6]);\n        encoded.append(1, pad);\n        break;\n    }\n\n    return encoded;\n}\n\nbool decode_base64(data_chunk &out, const std::string &in)\n{\n    const static uint32_t mask = 0x000000FF;\n\n    const auto length = in.length();\n    if ((length % 4) != 0)\n        return false;\n\n    size_t padding = 0;\n    if (length > 0)\n    {\n        if (in[length - 1] == pad)\n            padding++;\n        if (in[length - 2] == pad)\n            padding++;\n    }\n\n    data_chunk decoded;\n    decoded.reserve(((length / 4) * 3) - padding);\n\n    uint32_t value = 0;\n    for (auto cursor = in.begin(); cursor < in.end();)\n    {\n        for (size_t position = 0; position < 4; position++)\n        {\n            value <<= 6;\n            if (*cursor >= 0x41 && *cursor <= 0x5A)\n                value |= *cursor - 0x41;\n            else if (*cursor >= 0x61 && *cursor <= 0x7A)\n                value |= *cursor - 0x47;\n            else if (*cursor >= 0x30 && *cursor <= 0x39)\n                value |= *cursor + 0x04;\n            else if (*cursor == 0x2B)\n                value |= 0x3E;\n            else if (*cursor == 0x2F)\n                value |= 0x3F;\n            else if (*cursor == pad)\n            {\n                // Handle 1 or 2 pad characters.\n                switch (in.end() - cursor)\n                {\n                case 1:\n                    decoded.push_back((value >> 16) & mask);\n                    decoded.push_back((value >> 8) & mask);\n                    out = decoded;\n                    return true;\n                case 2:\n                    decoded.push_back((value >> 10) & mask);\n                    out = decoded;\n                    return true;\n                default:\n                    return false;\n                }\n            }\n            else\n                return false;\n\n            cursor++;\n        }\n\n        decoded.push_back((value >> 16) & mask);\n        decoded.push_back((value >> 8) & mask);\n        decoded.push_back((value >> 0) & mask);\n    }\n\n    out = decoded;\n    return true;\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/formats/base_85.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n// This implementation is based on:\n//  --------------------------------------------------------------------------\n//  Reference implementation for rfc.zeromq.org/spec:32/Z85\n//\n//  This implementation provides a Z85 codec as an easy-to-reuse C class\n//  designed to be easy to port into other languages.\n\n//  --------------------------------------------------------------------------\n//  Copyright (c) 2010-2013 iMatix Corporation and Contributors\n//\n//  Permission is hereby granted, free of charge, to any person obtaining a\n//  copy of this software and associated documentation files (the \"Software\"),\n//  to deal in the Software without restriction, including without limitation\n//  the rights to use, copy, modify, merge, publish, distribute, sublicense,\n//  and/or sell copies of the Software, and to permit persons to whom the\n//  Software is furnished to do so, subject to the following conditions:\n//\n//  The above copyright notice and this permission notice shall be included in\n//  all copies or substantial portions of the Software.\n//\n//  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n//  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n//  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n//  DEALINGS IN THE SOFTWARE.\n//  --------------------------------------------------------------------------\n\n#include <UChain/coin/formats/base_85.hpp>\n\n#include <cstddef>\n#include <cstdint>\n#include <string>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\n\n// Maps binary to base 85.\nstatic char encoder[85 + 1] =\n    {\n        \"0123456789\"\n        \"abcdefghij\"\n        \"klmnopqrst\"\n        \"uvwxyzABCD\"\n        \"EFGHIJKLMN\"\n        \"OPQRSTUVWX\"\n        \"YZ.-:+=^!/\"\n        \"*?&<>()[]{\"\n        \"}@%$#\"};\n\n// Maps base 85 to binary.\nstatic uint8_t decoder[96] =\n    {\n        0x00, 0x44, 0x00, 0x54, 0x53, 0x52, 0x48, 0x00,\n        0x4B, 0x4C, 0x46, 0x41, 0x00, 0x3F, 0x3E, 0x45,\n        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,\n        0x08, 0x09, 0x40, 0x00, 0x49, 0x42, 0x4A, 0x47,\n        0x51, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A,\n        0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32,\n        0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,\n        0x3B, 0x3C, 0x3D, 0x4D, 0x00, 0x4E, 0x43, 0x00,\n        0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,\n        0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,\n        0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,\n        0x21, 0x22, 0x23, 0x4F, 0x00, 0x50, 0x00, 0x00};\n\n// Accepts only byte arrays bounded to 4 bytes.\nbool encode_base85(std::string &out, data_slice in)\n{\n    const size_t size = in.size();\n    if (size % 4 != 0)\n        return false;\n\n    const size_t encoded_size = size * 5 / 4;\n    std::string encoded;\n    encoded.reserve(encoded_size + 1);\n    size_t byte_index = 0;\n    uint32_t accumulator = 0;\n\n    for (const uint8_t unencoded_byte : in)\n    {\n        accumulator = accumulator * 256 + unencoded_byte;\n        if (++byte_index % 4 == 0)\n        {\n            for (uint32_t divise = 85 * 85 * 85 * 85; divise > 0; divise /= 85)\n                encoded.push_back(encoder[accumulator / divise % 85]);\n\n            accumulator = 0;\n        }\n    }\n\n    out.assign(encoded.begin(), encoded.end());\n    BITCOIN_ASSERT(out.size() == encoded_size);\n    return true;\n}\n\n// Accepts only strings bounded to 5 characters.\nbool decode_base85(data_chunk &out, const std::string &in)\n{\n    const size_t length = in.size();\n    if (length % 5 != 0)\n        return false;\n\n    const size_t decoded_size = length * 4 / 5;\n    data_chunk decoded;\n    decoded.reserve(decoded_size);\n    size_t char_index = 0;\n    uint32_t accumulator = 0;\n\n    for (const uint8_t encoded_character : in)\n    {\n        const auto position = encoded_character - 32;\n        if (position < 0 || position > 96)\n            return false;\n\n        accumulator = accumulator * 85 + decoder[position];\n        if (++char_index % 5 == 0)\n        {\n            for (uint32_t divise = 256 * 256 * 256; divise > 0; divise /= 256)\n                decoded.push_back(accumulator / divise % 256);\n\n            accumulator = 0;\n        }\n    }\n\n    out.assign(decoded.begin(), decoded.end());\n    BITCOIN_ASSERT(out.size() == decoded_size);\n    return true;\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/math/checksum.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/math/checksum.hpp>\n\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/utility/endian.hpp>\n#include <UChain/coin/utility/deserializer.hpp>\n\nnamespace libbitcoin\n{\n\nvoid append_checksum(data_chunk &data)\n{\n    const auto checksum = bitcoin_checksum(data);\n    extend_data(data, to_little_endian(checksum));\n}\n\nuint32_t bitcoin_checksum(data_slice data)\n{\n    const auto hash = bitcoin_hash(data);\n    return from_little_endian_unsafe<uint32_t>(hash.begin());\n}\n\nbool verify_checksum(data_slice data)\n{\n    if (data.size() < checksum_size)\n        return false;\n\n    data_slice body(data.begin(), data.end() - checksum_size);\n    auto checksum = from_little_endian_unsafe<uint32_t>(data.end() - checksum_size);\n    return bitcoin_checksum(body) == checksum;\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/math/crypto.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/math/crypto.hpp>\n\n#include <UChain/coin/math/elliptic_curve.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include \"external/aes256.h\"\n\nnamespace libbitcoin\n{\n\nvoid aes256_encrypt(const aes_secret &key, aes_block &block)\n{\n    aes256_context context;\n    aes256_init(&context, key.data());\n    aes256_encrypt_ecb(&context, block.data());\n    aes256_done(&context);\n}\n\nvoid aes256_decrypt(const aes_secret &key, aes_block &block)\n{\n    aes256_context context;\n    aes256_init(&context, key.data());\n    aes256_decrypt_ecb(&context, block.data());\n    aes256_done(&context);\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/math/elliptic_curve.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/math/elliptic_curve.hpp>\n\n#include <algorithm>\n#include <secp256k1.h>\n#include <secp256k1_recovery.h>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include \"external/lax_der_parsing.h\"\n#include \"secp256k1_initializer.hpp\"\n\nnamespace libbitcoin\n{\n\nstatic constexpr uint8_t compressed_even = 0x02;\nstatic constexpr uint8_t compressed_odd = 0x03;\nstatic constexpr uint8_t uncompressed = 0x04;\n\nBC_CONSTFUNC int to_flags(bool compressed)\n{\n    return compressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED;\n}\n\n// Helper templates\n// ----------------------------------------------------------------------------\n// These allow strong typing of private keys without redundant code.\n\ntemplate <size_t Size>\nbool parse(const secp256k1_context *context, secp256k1_pubkey &out,\n           const byte_array<Size> &point)\n{\n    return secp256k1_ec_pubkey_parse(context, &out, point.data(), Size) == 1;\n}\n\ntemplate <size_t Size>\nbool serialize(const secp256k1_context *context, byte_array<Size> &out,\n               const secp256k1_pubkey point)\n{\n    auto size = Size;\n    const auto flags = to_flags(Size == ec_compressed_size);\n    secp256k1_ec_pubkey_serialize(context, out.data(), &size, &point, flags);\n    return size == Size;\n}\n\ntemplate <size_t Size>\nbool ec_add(const secp256k1_context *context, byte_array<Size> &in_out,\n            const ec_secret &secret)\n{\n    secp256k1_pubkey pubkey;\n    return parse(context, pubkey, in_out) &&\n           secp256k1_ec_pubkey_tweak_add(context, &pubkey, secret.data()) == 1 &&\n           serialize(context, in_out, pubkey);\n}\n\ntemplate <size_t Size>\nbool ec_multiply(const secp256k1_context *context, byte_array<Size> &in_out,\n                 const ec_secret &secret)\n{\n    secp256k1_pubkey pubkey;\n    return parse(context, pubkey, in_out) &&\n           secp256k1_ec_pubkey_tweak_mul(context, &pubkey, secret.data()) == 1 &&\n           serialize(context, in_out, pubkey);\n}\n\ntemplate <size_t Size>\nbool secret_to_public(const secp256k1_context *context, byte_array<Size> &out,\n                      const ec_secret &secret)\n{\n    secp256k1_pubkey pubkey;\n    return secp256k1_ec_pubkey_create(context, &pubkey, secret.data()) == 1 &&\n           serialize(context, out, pubkey);\n}\n\ntemplate <size_t Size>\nbool recover_public(const secp256k1_context *context, byte_array<Size> &out,\n                    const recoverable_signature &recoverable, const hash_digest &hash)\n{\n    secp256k1_pubkey pubkey;\n    secp256k1_ecdsa_recoverable_signature sign;\n    const auto recovery_id = static_cast<int>(recoverable.recovery_id);\n    return secp256k1_ecdsa_recoverable_signature_parse_compact(context,\n                                                               &sign, recoverable.signature.data(), recovery_id) == 1 &&\n           secp256k1_ecdsa_recover(context, &pubkey, &sign, hash.data()) == 1 &&\n           serialize(context, out, pubkey);\n}\n\nbool verify_signature(const secp256k1_context *context,\n                      const secp256k1_pubkey point, const hash_digest &hash,\n                      const ec_signature &signature)\n{\n    // Copy to avoid exposing external types.\n    secp256k1_ecdsa_signature parsed;\n    std::copy(signature.begin(), signature.end(), std::begin(parsed.data));\n\n    // secp256k1_ecdsa_verify rejects non-normalized (low-s) signatures, but\n    // bitcoin does not have such a limitation, so we always normalize.\n    secp256k1_ecdsa_signature normal;\n    secp256k1_ecdsa_signature_normalize(context, &normal, &parsed);\n    return secp256k1_ecdsa_verify(context, &normal, hash.data(), &point) == 1;\n}\n\n// Add and multiply EC values\n// ----------------------------------------------------------------------------\n\nbool ec_add(ec_compressed &point, const ec_secret &secret)\n{\n    const auto context = verification.context();\n    return ec_add(context, point, secret);\n}\n\nbool ec_add(ec_uncompressed &point, const ec_secret &secret)\n{\n    const auto context = verification.context();\n    return ec_add(context, point, secret);\n}\n\nbool ec_add(ec_secret &left, const ec_secret &right)\n{\n    const auto context = verification.context();\n    return secp256k1_ec_privkey_tweak_add(context, left.data(),\n                                          right.data()) == 1;\n}\n\nbool ec_multiply(ec_compressed &point, const ec_secret &secret)\n{\n    const auto context = verification.context();\n    return ec_multiply(context, point, secret);\n}\n\nbool ec_multiply(ec_uncompressed &point, const ec_secret &secret)\n{\n    const auto context = verification.context();\n    return ec_multiply(context, point, secret);\n}\n\nbool ec_multiply(ec_secret &left, const ec_secret &right)\n{\n    const auto context = verification.context();\n    return secp256k1_ec_privkey_tweak_mul(context, left.data(),\n                                          right.data()) == 1;\n}\n\n// Convert keys\n// ----------------------------------------------------------------------------\n\nbool compress(ec_compressed &out, const ec_uncompressed &point)\n{\n    secp256k1_pubkey pubkey;\n    const auto context = verification.context();\n    return parse(context, pubkey, point) && serialize(context, out, pubkey);\n}\n\nbool decompress(ec_uncompressed &out, const ec_compressed &point)\n{\n    secp256k1_pubkey pubkey;\n    const auto context = verification.context();\n    return parse(context, pubkey, point) && serialize(context, out, pubkey);\n}\n\nbool secret_to_public(ec_compressed &out, const ec_secret &secret)\n{\n    const auto context = signing.context();\n    return secret_to_public(context, out, secret);\n}\n\nbool secret_to_public(ec_uncompressed &out, const ec_secret &secret)\n{\n    const auto context = signing.context();\n    return secret_to_public(context, out, secret);\n}\n\n// Verify keys\n// ----------------------------------------------------------------------------\n\nbool verify(const ec_secret &secret)\n{\n    const auto context = verification.context();\n    return secp256k1_ec_seckey_verify(context, secret.data()) == 1;\n}\n\nbool verify(const ec_compressed &point)\n{\n    secp256k1_pubkey pubkey;\n    const auto context = verification.context();\n    return parse(context, pubkey, point);\n}\n\nbool verify(const ec_uncompressed &point)\n{\n    secp256k1_pubkey pubkey;\n    const auto context = verification.context();\n    return parse(context, pubkey, point);\n}\n\n// Detect public keys\n// ----------------------------------------------------------------------------\n\nbool is_compressed_key(data_slice point)\n{\n    const auto size = point.size();\n    if (size != ec_compressed_size)\n        return false;\n\n    const auto first = point.data()[0];\n    return first == compressed_even || first == compressed_odd;\n}\n\nbool is_uncompressed_key(data_slice point)\n{\n    const auto size = point.size();\n    if (size != ec_uncompressed_size)\n        return false;\n\n    const auto first = point.data()[0];\n    return first == uncompressed;\n}\n\nbool is_public_key(data_slice point)\n{\n    return is_compressed_key(point) || is_uncompressed_key(point);\n}\n\n// DER parse/encode\n// ----------------------------------------------------------------------------\n\nbool parse_signature(ec_signature &out, const der_signature &der_signature,\n                     bool strict)\n{\n    if (der_signature.empty())\n        return false;\n\n    bool valid;\n    secp256k1_ecdsa_signature parsed;\n    const auto context = verification.context();\n\n    if (strict)\n        valid = secp256k1_ecdsa_signature_parse_der(context, &parsed,\n                                                    der_signature.data(), der_signature.size()) == 1;\n    else\n        valid = ecdsa_signature_parse_der_lax(context, &parsed,\n                                              der_signature.data(), der_signature.size()) == 1;\n\n    if (valid)\n        std::copy(std::begin(parsed.data), std::end(parsed.data), out.begin());\n\n    return valid;\n}\n\nbool encode_signature(der_signature &out, const ec_signature &signature)\n{\n    // Copy to avoid exposing external types.\n    secp256k1_ecdsa_signature sign;\n    std::copy(signature.begin(), signature.end(), std::begin(sign.data));\n\n    const auto context = signing.context();\n    auto size = max_der_signature_size;\n    out.resize(size);\n\n    if (secp256k1_ecdsa_signature_serialize_der(context, out.data(), &size,\n                                                &sign) != 1)\n        return false;\n\n    out.resize(size);\n    return true;\n}\n\n// EC sign/verify\n// ----------------------------------------------------------------------------\n\nbool sign(ec_signature &out, const ec_secret &secret, const hash_digest &hash)\n{\n    secp256k1_ecdsa_signature signature;\n    const auto context = signing.context();\n\n    if (secp256k1_ecdsa_sign(context, &signature, hash.data(), secret.data(),\n                             secp256k1_nonce_function_rfc6979, nullptr) != 1)\n        return false;\n\n    std::copy_n(std::begin(signature.data), out.size(), out.begin());\n    return true;\n}\n\nbool verify_signature(const ec_compressed &point, const hash_digest &hash,\n                      const ec_signature &signature)\n{\n    secp256k1_pubkey pubkey;\n    const auto context = verification.context();\n    return parse(context, pubkey, point) &&\n           verify_signature(context, pubkey, hash, signature);\n}\n\nbool verify_signature(const ec_uncompressed &point, const hash_digest &hash,\n                      const ec_signature &signature)\n{\n    secp256k1_pubkey pubkey;\n    const auto context = verification.context();\n    return parse(context, pubkey, point) &&\n           verify_signature(context, pubkey, hash, signature);\n}\n\nbool verify_signature(data_slice point, const hash_digest &hash,\n                      const ec_signature &signature)\n{\n    // Copy to avoid exposing external types.\n    secp256k1_ecdsa_signature parsed;\n    std::copy(signature.begin(), signature.end(), std::begin(parsed.data));\n\n    // secp256k1_ecdsa_verify rejects non-normalized (low-s) signatures, but\n    // bitcoin does not have such a limitation, so we always normalize.\n    secp256k1_ecdsa_signature normal;\n    const auto context = verification.context();\n    secp256k1_ecdsa_signature_normalize(context, &normal, &parsed);\n\n    // This uses a data slice and calls secp256k1_ec_pubkey_parse() in place of\n    // parse() so that we can support the der_verify data_chunk optimization.\n    secp256k1_pubkey pubkey;\n    const auto size = point.size();\n    return secp256k1_ec_pubkey_parse(context, &pubkey, point.data(), size) == 1 &&\n           secp256k1_ecdsa_verify(context, &normal, hash.data(), &pubkey) == 1;\n}\n\n// Recoverable sign/recover\n// ----------------------------------------------------------------------------\n\nbool sign_recoverable(recoverable_signature &out, const ec_secret &secret,\n                      const hash_digest &hash)\n{\n    int recovery_id;\n    const auto context = signing.context();\n    secp256k1_ecdsa_recoverable_signature signature;\n\n    const auto result =\n        secp256k1_ecdsa_sign_recoverable(context, &signature, hash.data(),\n                                         secret.data(), secp256k1_nonce_function_rfc6979, nullptr) == 1 &&\n        secp256k1_ecdsa_recoverable_signature_serialize_compact(context,\n                                                                out.signature.data(), &recovery_id, &signature) == 1;\n\n    BITCOIN_ASSERT(recovery_id >= 0 && recovery_id <= 3);\n    out.recovery_id = static_cast<uint8_t>(recovery_id);\n    return result;\n}\n\nbool recover_public(ec_compressed &out,\n                    const recoverable_signature &recoverable, const hash_digest &hash)\n{\n    const auto context = verification.context();\n    return recover_public(context, out, recoverable, hash);\n}\n\nbool recover_public(ec_uncompressed &out,\n                    const recoverable_signature &recoverable, const hash_digest &hash)\n{\n    const auto context = verification.context();\n    return recover_public(context, out, recoverable, hash);\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/math/external/CMakeLists.txt",
    "content": "FILE(GLOB bitcoinmath_SOURCES \"*.c\")\n\nSET(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} -fno-strict-aliasing\")\n\nADD_LIBRARY(bitcoinmath_static STATIC ${bitcoinmath_SOURCES})\nSET_TARGET_PROPERTIES(bitcoinmath_static PROPERTIES OUTPUT_NAME uc_bitcoinmath)\nTARGET_LINK_LIBRARIES(bitcoinmath_static)\nINSTALL(TARGETS bitcoinmath_static DESTINATION lib)\n\nIF(ENABLE_SHARED_LIBS)\n  ADD_LIBRARY(bitcoinmath_shared SHARED ${bitcoinmath_SOURCES})\n  SET_TARGET_PROPERTIES(bitcoinmath_shared PROPERTIES OUTPUT_NAME uc_bitcoinmath)\n  TARGET_LINK_LIBRARIES(bitcoinmath_shared)\n  INSTALL(TARGETS bitcoinmath_shared DESTINATION lib)\nENDIF()\n"
  },
  {
    "path": "src/UChain/coin/math/external/aes256.c",
    "content": "/**\n *   Byte-oriented AES-256 implementation.\n *   All lookup tables replaced with 'on the fly' calculations.\n *\n *   Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com\n *   Other contributors: Hal Finney\n *\n *   Permission to use, copy, modify, and distribute this software for any\n *   purpose with or without fee is hereby granted, provided that the above\n *   copyright notice and this permission notice appear in all copies.\n *\n *   THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n *   WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n *   MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n *   ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n *   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n *   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n *   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n#include \"aes256.h\"\n\n#include <errno.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n\n#define F(x) (((x) << 1) ^ ((((x) >> 7) & 1) * 0x1b))\n#define FD(x) (((x) >> 1) ^ (((x)&1) ? 0x8d : 0))\n\n#ifdef BACK_TO_TABLES\n\nconst uint8_t sbox[256] = {\n    0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,\n    0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,\n    0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,\n    0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,\n    0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,\n    0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,\n    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,\n    0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,\n    0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,\n    0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,\n    0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,\n    0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,\n    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,\n    0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,\n    0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,\n    0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,\n    0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,\n    0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,\n    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,\n    0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,\n    0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,\n    0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,\n    0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,\n    0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,\n    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,\n    0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,\n    0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,\n    0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,\n    0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,\n    0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,\n    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,\n    0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16};\nconst uint8_t sboxinv[256] = {\n    0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,\n    0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,\n    0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,\n    0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,\n    0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,\n    0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,\n    0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,\n    0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,\n    0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,\n    0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,\n    0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,\n    0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,\n    0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,\n    0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,\n    0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,\n    0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,\n    0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,\n    0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,\n    0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,\n    0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,\n    0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,\n    0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,\n    0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,\n    0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,\n    0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,\n    0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,\n    0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,\n    0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,\n    0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,\n    0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,\n    0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,\n    0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d};\n\n#define rj_sbox(x) sbox[(x)]\n#define rj_sbox_inv(x) sboxinv[(x)]\n\n#else /* tableless subroutines */\n\n/* -------------------------------------------------------------------------- */\nuint8_t gf_alog(uint8_t x) /* calculate anti-logarithm gen 3 */\n{\n    uint8_t atb = 1, z;\n\n    while (x--)\n    {\n        z = atb;\n        atb <<= 1;\n        if (z & 0x80)\n            atb ^= 0x1b;\n        atb ^= z;\n    }\n\n    return atb;\n} /* gf_alog */\n\n/* -------------------------------------------------------------------------- */\nuint8_t gf_log(uint8_t x) /* calculate logarithm gen 3 */\n{\n    uint8_t atb = 1, i = 0, z;\n\n    do\n    {\n        if (atb == x)\n            break;\n        z = atb;\n        atb <<= 1;\n        if (z & 0x80)\n            atb ^= 0x1b;\n        atb ^= z;\n    } while (++i > 0);\n\n    return i;\n} /* gf_log */\n\n/* -------------------------------------------------------------------------- */\nuint8_t gf_mulinv(uint8_t x) /* calculate multiplicative inverse */\n{\n    return (x) ? gf_alog(255 - gf_log(x)) : 0;\n} /* gf_mulinv */\n\n/* -------------------------------------------------------------------------- */\nuint8_t rj_sbox(uint8_t x)\n{\n    uint8_t y, sb;\n\n    sb = y = gf_mulinv(x);\n    y = (y << 1) | (y >> 7);\n    sb ^= y;\n    y = (y << 1) | (y >> 7);\n    sb ^= y;\n    y = (y << 1) | (y >> 7);\n    sb ^= y;\n    y = (y << 1) | (y >> 7);\n    sb ^= y;\n\n    return (sb ^ 0x63);\n} /* rj_sbox */\n\n/* -------------------------------------------------------------------------- */\nuint8_t rj_sbox_inv(uint8_t x)\n{\n    uint8_t y, sb;\n\n    y = x ^ 0x63;\n    sb = y = (y << 1) | (y >> 7);\n    y = (y << 2) | (y >> 6);\n    sb ^= y;\n    y = (y << 3) | (y >> 5);\n    sb ^= y;\n\n    return gf_mulinv(sb);\n} /* rj_sbox_inv */\n\n#endif\n\n/* -------------------------------------------------------------------------- */\nuint8_t rj_xtime(uint8_t x)\n{\n    return (x & 0x80) ? ((x << 1) ^ 0x1b) : (x << 1);\n} /* rj_xtime */\n\n/* -------------------------------------------------------------------------- */\nvoid aes_subBytes(uint8_t *buf)\n{\n    register uint8_t i = 16;\n\n    while (i--)\n        buf[i] = rj_sbox(buf[i]);\n} /* aes_subBytes */\n\n/* -------------------------------------------------------------------------- */\nvoid aes_subBytes_inv(uint8_t *buf)\n{\n    register uint8_t i = 16;\n\n    while (i--)\n        buf[i] = rj_sbox_inv(buf[i]);\n} /* aes_subBytes_inv */\n\n/* -------------------------------------------------------------------------- */\nvoid aes_addRoundKey(uint8_t *buf, uint8_t *key)\n{\n    register uint8_t i = 16;\n\n    while (i--)\n        buf[i] ^= key[i];\n} /* aes_addRoundKey */\n\n/* -------------------------------------------------------------------------- */\nvoid aes_addRoundKey_cpy(uint8_t *buf, uint8_t *key, uint8_t *cpk)\n{\n    register uint8_t i = 16;\n\n    while (i--)\n        buf[i] ^= (cpk[i] = key[i]), cpk[16 + i] = key[16 + i];\n} /* aes_addRoundKey_cpy */\n\n/* -------------------------------------------------------------------------- */\nvoid aes_shiftRows(uint8_t *buf)\n{\n    register uint8_t i, j; /* to make it potentially parallelable :) */\n\n    i = buf[1];\n    buf[1] = buf[5];\n    buf[5] = buf[9];\n    buf[9] = buf[13];\n    buf[13] = i;\n    i = buf[10];\n    buf[10] = buf[2];\n    buf[2] = i;\n    j = buf[3];\n    buf[3] = buf[15];\n    buf[15] = buf[11];\n    buf[11] = buf[7];\n    buf[7] = j;\n    j = buf[14];\n    buf[14] = buf[6];\n    buf[6] = j;\n\n} /* aes_shiftRows */\n\n/* -------------------------------------------------------------------------- */\nvoid aes_shiftRows_inv(uint8_t *buf)\n{\n    register uint8_t i, j; /* same as above :) */\n\n    i = buf[1];\n    buf[1] = buf[13];\n    buf[13] = buf[9];\n    buf[9] = buf[5];\n    buf[5] = i;\n    i = buf[2];\n    buf[2] = buf[10];\n    buf[10] = i;\n    j = buf[3];\n    buf[3] = buf[7];\n    buf[7] = buf[11];\n    buf[11] = buf[15];\n    buf[15] = j;\n    j = buf[6];\n    buf[6] = buf[14];\n    buf[14] = j;\n\n} /* aes_shiftRows_inv */\n\n/* -------------------------------------------------------------------------- */\nvoid aes_mixColumns(uint8_t *buf)\n{\n    register uint8_t i, a, b, c, d, e;\n\n    for (i = 0; i < 16; i += 4)\n    {\n        a = buf[i];\n        b = buf[i + 1];\n        c = buf[i + 2];\n        d = buf[i + 3];\n        e = a ^ b ^ c ^ d;\n        buf[i] ^= e ^ rj_xtime(a ^ b);\n        buf[i + 1] ^= e ^ rj_xtime(b ^ c);\n        buf[i + 2] ^= e ^ rj_xtime(c ^ d);\n        buf[i + 3] ^= e ^ rj_xtime(d ^ a);\n    }\n} /* aes_mixColumns */\n\n/* -------------------------------------------------------------------------- */\nvoid aes_mixColumns_inv(uint8_t *buf)\n{\n    register uint8_t i, a, b, c, d, e, x, y, z;\n\n    for (i = 0; i < 16; i += 4)\n    {\n        a = buf[i];\n        b = buf[i + 1];\n        c = buf[i + 2];\n        d = buf[i + 3];\n        e = a ^ b ^ c ^ d;\n        z = rj_xtime(e);\n        x = e ^ rj_xtime(rj_xtime(z ^ a ^ c));\n        y = e ^ rj_xtime(rj_xtime(z ^ b ^ d));\n        buf[i] ^= x ^ rj_xtime(a ^ b);\n        buf[i + 1] ^= y ^ rj_xtime(b ^ c);\n        buf[i + 2] ^= x ^ rj_xtime(c ^ d);\n        buf[i + 3] ^= y ^ rj_xtime(d ^ a);\n    }\n} /* aes_mixColumns_inv */\n\n/* -------------------------------------------------------------------------- */\nvoid aes_expandEncKey(uint8_t *k, uint8_t *rc)\n{\n    register uint8_t i;\n\n    k[0] ^= rj_sbox(k[29]) ^ (*rc);\n    k[1] ^= rj_sbox(k[30]);\n    k[2] ^= rj_sbox(k[31]);\n    k[3] ^= rj_sbox(k[28]);\n    *rc = F(*rc);\n\n    for (i = 4; i < 16; i += 4)\n        k[i] ^= k[i - 4], k[i + 1] ^= k[i - 3],\n            k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1];\n    k[16] ^= rj_sbox(k[12]);\n    k[17] ^= rj_sbox(k[13]);\n    k[18] ^= rj_sbox(k[14]);\n    k[19] ^= rj_sbox(k[15]);\n\n    for (i = 20; i < 32; i += 4)\n        k[i] ^= k[i - 4], k[i + 1] ^= k[i - 3],\n            k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1];\n\n} /* aes_expandEncKey */\n\n/* -------------------------------------------------------------------------- */\nvoid aes_expandDecKey(uint8_t *k, uint8_t *rc)\n{\n    uint8_t i;\n\n    for (i = 28; i > 16; i -= 4)\n        k[i + 0] ^= k[i - 4], k[i + 1] ^= k[i - 3],\n            k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1];\n\n    k[16] ^= rj_sbox(k[12]);\n    k[17] ^= rj_sbox(k[13]);\n    k[18] ^= rj_sbox(k[14]);\n    k[19] ^= rj_sbox(k[15]);\n\n    for (i = 12; i > 0; i -= 4)\n        k[i + 0] ^= k[i - 4], k[i + 1] ^= k[i - 3],\n            k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1];\n\n    *rc = FD(*rc);\n    k[0] ^= rj_sbox(k[29]) ^ (*rc);\n    k[1] ^= rj_sbox(k[30]);\n    k[2] ^= rj_sbox(k[31]);\n    k[3] ^= rj_sbox(k[28]);\n} /* aes_expandDecKey */\n\n/* -------------------------------------------------------------------------- */\nvoid aes256_init(aes256_context *context, const uint8_t *key)\n{\n    uint8_t rcon = 1;\n    register uint8_t i;\n\n    for (i = 0; i < sizeof(context->key); i++)\n        context->enckey[i] = context->deckey[i] = key[i];\n    for (i = 8; --i;)\n        aes_expandEncKey(context->deckey, &rcon);\n} /* aes256_init */\n\n/* -------------------------------------------------------------------------- */\nvoid aes256_done(aes256_context *context)\n{\n    register uint8_t i;\n\n    for (i = 0; i < sizeof(context->key); i++)\n        context->key[i] = context->enckey[i] = context->deckey[i] = 0;\n} /* aes256_done */\n\n/* -------------------------------------------------------------------------- */\nvoid aes256_encrypt_ecb(aes256_context *context, uint8_t *buf)\n{\n    uint8_t i, rcon;\n\n    aes_addRoundKey_cpy(buf, context->enckey, context->key);\n    for (i = 1, rcon = 1; i < 14; ++i)\n    {\n        aes_subBytes(buf);\n        aes_shiftRows(buf);\n        aes_mixColumns(buf);\n        if (i & 1)\n            aes_addRoundKey(buf, &context->key[16]);\n        else\n            aes_expandEncKey(context->key, &rcon), aes_addRoundKey(buf, context->key);\n    }\n    aes_subBytes(buf);\n    aes_shiftRows(buf);\n    aes_expandEncKey(context->key, &rcon);\n    aes_addRoundKey(buf, context->key);\n} /* aes256_encrypt */\n\n/* -------------------------------------------------------------------------- */\nvoid aes256_decrypt_ecb(aes256_context *context, uint8_t *buf)\n{\n    uint8_t i, rcon;\n\n    aes_addRoundKey_cpy(buf, context->deckey, context->key);\n    aes_shiftRows_inv(buf);\n    aes_subBytes_inv(buf);\n\n    for (i = 14, rcon = 0x80; --i;)\n    {\n        if ((i & 1))\n        {\n            aes_expandDecKey(context->key, &rcon);\n            aes_addRoundKey(buf, &context->key[16]);\n        }\n        else\n            aes_addRoundKey(buf, context->key);\n        aes_mixColumns_inv(buf);\n        aes_shiftRows_inv(buf);\n        aes_subBytes_inv(buf);\n    }\n    aes_addRoundKey(buf, context->key);\n} /* aes256_decrypt */\n"
  },
  {
    "path": "src/UChain/coin/math/external/aes256.h",
    "content": "/**\n *   Byte-oriented AES-256 implementation.\n *   All lookup tables replaced with 'on the fly' calculations.\n *\n *   Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com\n *   Other contributors: Hal Finney\n *\n *   Permission to use, copy, modify, and distribute this software for any\n *   purpose with or without fee is hereby granted, provided that the above\n *   copyright notice and this permission notice appear in all copies.\n *\n *   THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n *   WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n *   MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n *   ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n *   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n *   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n *   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n#ifndef UC_AES256_H\n#define UC_AES256_H\n\n#include <stdint.h>\n#include <stdlib.h>\n\n#define AES256_KEY_LENGTH 32U\n#define AES256_BLOCK_LENGTH 16U\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n    typedef struct\n    {\n        uint8_t key[AES256_KEY_LENGTH];\n        uint8_t enckey[AES256_KEY_LENGTH];\n        uint8_t deckey[AES256_KEY_LENGTH];\n    } aes256_context;\n\n    void aes256_init(aes256_context *context,\n                     const uint8_t key[AES256_KEY_LENGTH]);\n\n    void aes256_done(aes256_context *context);\n\n    void aes256_encrypt_ecb(aes256_context *context,\n                            uint8_t plain_text[AES256_BLOCK_LENGTH]);\n\n    void aes256_decrypt_ecb(aes256_context *context,\n                            uint8_t cypher_text[AES256_BLOCK_LENGTH]);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "src/UChain/coin/math/external/crypto_scrypt.c",
    "content": "/**\n * Copyright 2009 Colin Percival\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n * This file was originally written by Colin Percival as part of the Tarsnap\n * online backup system.\n */\n#include \"crypto_scrypt.h\"\n\n#include <errno.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n#include <UChain/coin/compat.h>\n#include \"pbkdf2_sha256.h\"\n\nstatic void blkcpy(uint8_t *, uint8_t *, size_t);\nstatic void blkxor(uint8_t *, uint8_t *, size_t);\nstatic void salsa20_8(uint8_t[64]);\nstatic void blockmix_salsa8(uint8_t *, uint8_t *, size_t);\nstatic uint64_t integerify(uint8_t *, size_t);\nstatic void smix(uint8_t *, size_t, uint64_t, uint8_t *, uint8_t *);\n\nstatic BC_C_INLINE uint32_t le32dec(const void *pp)\n{\n    const uint8_t *p = (uint8_t const *)pp;\n    return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) +\n            ((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24));\n}\n\nstatic BC_C_INLINE void le32enc(void *pp, uint32_t x)\n{\n    uint8_t *p = (uint8_t *)pp;\n    p[0] = x & 0xff;\n    p[1] = (x >> 8) & 0xff;\n    p[2] = (x >> 16) & 0xff;\n    p[3] = (x >> 24) & 0xff;\n}\n\nstatic BC_C_INLINE uint64_t le64dec(const void *pp)\n{\n    const uint8_t *p = (uint8_t const *)pp;\n\n    return ((uint64_t)(p[0]) + ((uint64_t)(p[1]) << 8) +\n            ((uint64_t)(p[2]) << 16) + ((uint64_t)(p[3]) << 24) +\n            ((uint64_t)(p[4]) << 32) + ((uint64_t)(p[5]) << 40) +\n            ((uint64_t)(p[6]) << 48) + ((uint64_t)(p[7]) << 56));\n}\n\nstatic void blkcpy(uint8_t *dest, uint8_t *src, size_t len)\n{\n    size_t i;\n\n    for (i = 0; i < len; i++)\n        dest[i] = src[i];\n}\n\nstatic void blkxor(uint8_t *dest, uint8_t *src, size_t len)\n{\n    size_t i;\n\n    for (i = 0; i < len; i++)\n        dest[i] ^= src[i];\n}\n\n/**\n * salsa20_8(B):\n * Apply the salsa20/8 core to the provided block.\n */\nstatic void salsa20_8(uint8_t B[64])\n{\n    uint32_t B32[16];\n    uint32_t x[16];\n    size_t i;\n\n    /* Convert little-endian values in. */\n    for (i = 0; i < 16; i++)\n        B32[i] = le32dec(&B[i * 4]);\n\n    /* Compute x = doubleround^4(B32). */\n    for (i = 0; i < 16; i++)\n        x[i] = B32[i];\n    for (i = 0; i < 8; i += 2)\n    {\n#define R(a, b) (((a) << (b)) | ((a) >> (32 - (b))))\n        /* Operate on columns. */\n        x[4] ^= R(x[0] + x[12], 7);\n        x[8] ^= R(x[4] + x[0], 9);\n        x[12] ^= R(x[8] + x[4], 13);\n        x[0] ^= R(x[12] + x[8], 18);\n\n        x[9] ^= R(x[5] + x[1], 7);\n        x[13] ^= R(x[9] + x[5], 9);\n        x[1] ^= R(x[13] + x[9], 13);\n        x[5] ^= R(x[1] + x[13], 18);\n\n        x[14] ^= R(x[10] + x[6], 7);\n        x[2] ^= R(x[14] + x[10], 9);\n        x[6] ^= R(x[2] + x[14], 13);\n        x[10] ^= R(x[6] + x[2], 18);\n\n        x[3] ^= R(x[15] + x[11], 7);\n        x[7] ^= R(x[3] + x[15], 9);\n        x[11] ^= R(x[7] + x[3], 13);\n        x[15] ^= R(x[11] + x[7], 18);\n\n        /* Operate on rows. */\n        x[1] ^= R(x[0] + x[3], 7);\n        x[2] ^= R(x[1] + x[0], 9);\n        x[3] ^= R(x[2] + x[1], 13);\n        x[0] ^= R(x[3] + x[2], 18);\n\n        x[6] ^= R(x[5] + x[4], 7);\n        x[7] ^= R(x[6] + x[5], 9);\n        x[4] ^= R(x[7] + x[6], 13);\n        x[5] ^= R(x[4] + x[7], 18);\n\n        x[11] ^= R(x[10] + x[9], 7);\n        x[8] ^= R(x[11] + x[10], 9);\n        x[9] ^= R(x[8] + x[11], 13);\n        x[10] ^= R(x[9] + x[8], 18);\n\n        x[12] ^= R(x[15] + x[14], 7);\n        x[13] ^= R(x[12] + x[15], 9);\n        x[14] ^= R(x[13] + x[12], 13);\n        x[15] ^= R(x[14] + x[13], 18);\n#undef R\n    }\n\n    /* Compute B32 = B32 + x. */\n    for (i = 0; i < 16; i++)\n        B32[i] += x[i];\n\n    /* Convert little-endian values out. */\n    for (i = 0; i < 16; i++)\n        le32enc(&B[4 * i], B32[i]);\n}\n\n/**\n * blockmix_salsa8(B, Y, r):\n * Compute B = BlockMix_{salsa20/8, r}(B).  The input B must be 128r bytes in\n * length; the temporary space Y must also be the same size.\n */\nstatic void blockmix_salsa8(uint8_t *B, uint8_t *Y, size_t r)\n{\n    uint8_t X[64];\n    size_t i;\n\n    /* 1: X <-- B_{2r - 1} */\n    blkcpy(X, &B[(2 * r - 1) * 64], 64);\n\n    /* 2: for i = 0 to 2r - 1 do */\n    for (i = 0; i < 2 * r; i++)\n    {\n        /* 3: X <-- H(X \\xor B_i) */\n        blkxor(X, &B[i * 64], 64);\n        salsa20_8(X);\n\n        /* 4: Y_i <-- X */\n        blkcpy(&Y[i * 64], X, 64);\n    }\n\n    /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */\n    for (i = 0; i < r; i++)\n        blkcpy(&B[i * 64], &Y[(i * 2) * 64], 64);\n    for (i = 0; i < r; i++)\n        blkcpy(&B[(i + r) * 64], &Y[(i * 2 + 1) * 64], 64);\n}\n\n/**\n * integerify(B, r):\n * Return the result of parsing B_{2r-1} as a little-endian integer.\n */\nstatic uint64_t integerify(uint8_t *B, size_t r)\n{\n    uint8_t *X = &B[(2 * r - 1) * 64];\n\n    return (le64dec(X));\n}\n\n/**\n * smix(B, r, N, V, XY):\n * Compute B = SMix_r(B, N).  The input B must be 128r bytes in length; the\n * temporary storage V must be 128rN bytes in length; the temporary storage\n * XY must be 256r bytes in length.  The value N must be a power of 2.\n */\nstatic void smix(uint8_t *B, size_t r,\n                 uint64_t N, uint8_t *V, uint8_t *XY)\n{\n    uint8_t *X = XY;\n    uint8_t *Y = &XY[128 * r];\n    uint64_t i;\n    uint64_t j;\n\n    /* 1: X <-- B */\n    blkcpy(X, B, 128 * r);\n\n    /* 2: for i = 0 to N - 1 do */\n    for (i = 0; i < N; i++)\n    {\n        /* 3: V_i <-- X */\n        blkcpy(&V[i * (128 * r)], X, 128 * r);\n\n        /* 4: X <-- H(X) */\n        blockmix_salsa8(X, Y, r);\n    }\n\n    /* 6: for i = 0 to N - 1 do */\n    for (i = 0; i < N; i++)\n    {\n        /* 7: j <-- Integerify(X) mod N */\n        j = integerify(X, r) & (N - 1);\n\n        /* 8: X <-- H(X \\xor V_j) */\n        blkxor(X, &V[j * (128 * r)], 128 * r);\n        blockmix_salsa8(X, Y, r);\n    }\n\n    /* 10: B' <-- X */\n    blkcpy(B, X, 128 * r);\n}\n\n/**\n * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):\n * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,\n * p, buflen) and write the result into buf.  The parameters r, p, and buflen\n * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32.  The parameter N\n * must be a power of 2.\n *\n * Return 0 on success; or -1 on error.\n */\nint crypto_scrypt(const uint8_t *passphrase, size_t passphrase_length,\n                  const uint8_t *salt, size_t salt_length, uint64_t N,\n                  uint32_t r, uint32_t p, uint8_t *buf, size_t buf_length)\n{\n    uint8_t *B;\n    uint8_t *V;\n    uint8_t *XY;\n    uint32_t i;\n\n    /* Sanity-check parameters. */\n#if SIZE_MAX > UINT32_MAX\n    if (buf_length > (((uint64_t)(1) << 32) - 1) * 32)\n    {\n        errno = EFBIG;\n        goto err0;\n    }\n#endif\n    if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30))\n    {\n        errno = EFBIG;\n        goto err0;\n    }\n    if (((N & (N - 1)) != 0) || (N == 0))\n    {\n        errno = EINVAL;\n        goto err0;\n    }\n    if ((r > SIZE_MAX / 128 / p) ||\n#if SIZE_MAX / 256 <= UINT32_MAX\n        (r > SIZE_MAX / 256) ||\n#endif\n        (N > SIZE_MAX / 128 / r))\n    {\n        errno = ENOMEM;\n        goto err0;\n    }\n\n    /* Allocate memory. */\n    if ((B = malloc(128 * r * p)) == NULL)\n        goto err0;\n    if ((XY = malloc(256 * r)) == NULL)\n        goto err1;\n    if ((V = malloc(128 * r * (size_t)N)) == NULL)\n        goto err2;\n\n    /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */\n    pbkdf2_sha256(passphrase, passphrase_length,\n                  salt, salt_length, 1, B, p * 128 * r);\n\n    /* 2: for i = 0 to p - 1 do */\n    for (i = 0; i < p; i++)\n    {\n        /* 3: B_i <-- MF(B_i, N) */\n        smix(&B[i * 128 * r], r, N, V, XY);\n    }\n\n    /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */\n    pbkdf2_sha256(passphrase, passphrase_length,\n                  B, p * 128 * r, 1, buf, buf_length);\n\n    /* Free memory. */\n    free(V);\n    free(XY);\n    free(B);\n\n    /* Success! */\n    return (0);\n\nerr2:\n    free(XY);\nerr1:\n    free(B);\nerr0:\n    /* Failure! */\n    return (-1);\n}\n"
  },
  {
    "path": "src/UChain/coin/math/external/crypto_scrypt.h",
    "content": "/**\n * Copyright 2009 Colin Percival\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n * This file was originally written by Colin Percival as part of the Tarsnap\n * online backup system.\n */\n#ifndef UC_SCRYPT_H\n#define UC_SCRYPT_H\n\n#include <stdint.h>\n#include <stdlib.h>\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n    /**\n * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):\n * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,\n * p, buflen) and write the result into buf.  The parameters r, p, and buflen\n * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32.  The parameter N\n * must be a power of 2 greater than 1.\n *\n * Return 0 on success; or -1 on error.\n */\n    int crypto_scrypt(const uint8_t *passphrase, size_t passphrase_length,\n                      const uint8_t *salt, size_t salt_length, uint64_t N, uint32_t r,\n                      uint32_t p, uint8_t *buf, size_t buf_length);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* !_CRYPTO_SCRYPT_H_ */\n"
  },
  {
    "path": "src/UChain/coin/math/external/hmac_sha256.c",
    "content": "/* libsodium: hmac_hmacsha256.c, v0.4.5 2014/04/16 */\n/**\n * Copyright 2005,2007,2009 Colin Percival. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#include \"hmac_sha256.h\"\n\n#include <stdint.h>\n#include <string.h>\n#include \"sha256.h\"\n#include \"zeroize.h\"\n\nvoid HMACSHA256(const uint8_t *input, size_t length, const uint8_t *key,\n                size_t key_length, uint8_t digest[HMACSHA256_DIGEST_LENGTH])\n{\n    HMACSHA256CTX context;\n    HMACSHA256Init(&context, key, key_length);\n    HMACSHA256Update(&context, input, length);\n    HMACSHA256Final(&context, digest);\n}\n\nvoid HMACSHA256Final(HMACSHA256CTX *context,\n                     uint8_t digest[HMACSHA256_DIGEST_LENGTH])\n{\n    uint8_t hash[HMACSHA256_DIGEST_LENGTH];\n\n    SHA256Final(&context->ictx, hash);\n    SHA256Update(&context->octx, hash, HMACSHA256_DIGEST_LENGTH);\n    SHA256Final(&context->octx, digest);\n\n    zeroize((void *)hash, sizeof hash);\n}\n\nvoid HMACSHA256Init(HMACSHA256CTX *context, const uint8_t *key,\n                    size_t key_length)\n{\n    size_t i;\n    uint8_t pad[SHA256_BLOCK_LENGTH];\n    uint8_t key_hash[SHA256_DIGEST_LENGTH];\n\n    if (key_length > SHA256_BLOCK_LENGTH)\n    {\n        SHA256Init(&context->ictx);\n        SHA256Update(&context->ictx, key, key_length);\n        SHA256Final(&context->ictx, key_hash);\n        key = key_hash;\n        key_length = SHA256_DIGEST_LENGTH;\n    }\n\n    SHA256Init(&context->ictx);\n    memset(pad, 0x36, SHA256_BLOCK_LENGTH);\n\n    for (i = 0; i < key_length; i++)\n        pad[i] ^= key[i];\n\n    SHA256Update(&context->ictx, pad, SHA256_BLOCK_LENGTH);\n    SHA256Init(&context->octx);\n    memset(pad, 0x5c, SHA256_BLOCK_LENGTH);\n\n    for (i = 0; i < key_length; i++)\n        pad[i] ^= key[i];\n\n    SHA256Update(&context->octx, pad, SHA256_BLOCK_LENGTH);\n    zeroize((void *)key_hash, sizeof key_hash);\n}\n\nvoid HMACSHA256Update(HMACSHA256CTX *context, const uint8_t *input,\n                      size_t length)\n{\n    SHA256Update(&context->ictx, input, length);\n}\n"
  },
  {
    "path": "src/UChain/coin/math/external/hmac_sha256.h",
    "content": "/* libsodium: hmac_hmacsha512.c, v0.4.5 2014/04/16 */\n/**\n * Copyright 2005,2007,2009 Colin Percival. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef UC_HMACSHA256_H\n#define UC_HMACSHA256_H\n\n#include <stdint.h>\n#include <stddef.h>\n#include \"sha256.h\"\n\n#define HMACSHA256_DIGEST_LENGTH 32U\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n    typedef struct HMACSHA256CTX\n    {\n        SHA256CTX ctx;\n        SHA256CTX ictx;\n        SHA256CTX octx;\n    } HMACSHA256CTX;\n\n    void HMACSHA256(const uint8_t *input, size_t length, const uint8_t *key,\n                    size_t key_length, uint8_t digest[HMACSHA256_DIGEST_LENGTH]);\n\n    void HMACSHA256Final(HMACSHA256CTX *context,\n                         uint8_t digest[HMACSHA256_DIGEST_LENGTH]);\n\n    void HMACSHA256Init(HMACSHA256CTX *context, const uint8_t *key,\n                        size_t key_length);\n\n    void HMACSHA256Update(HMACSHA256CTX *context, const uint8_t *input,\n                          size_t length);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "src/UChain/coin/math/external/hmac_sha512.c",
    "content": "/* libsodium: hmac_hmacsha512.c, v0.4.5 2014/04/16 */\n/**\n * Copyright 2005,2007,2009 Colin Percival. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#include \"hmac_sha512.h\"\n\n#include <stdint.h>\n#include <string.h>\n#include \"sha512.h\"\n#include \"zeroize.h\"\n\nvoid HMACSHA512(const uint8_t *input, size_t length, const uint8_t *key,\n                size_t key_length, uint8_t digest[HMACSHA512_DIGEST_LENGTH])\n{\n    HMACSHA512CTX context;\n    HMACSHA512Init(&context, key, key_length);\n    HMACSHA512Update(&context, input, length);\n    HMACSHA512Final(&context, digest);\n}\n\nvoid HMACSHA512Final(HMACSHA512CTX *context,\n                     uint8_t digest[HMACSHA512_DIGEST_LENGTH])\n{\n    uint8_t hash[HMACSHA512_DIGEST_LENGTH];\n\n    SHA512Final(&context->ictx, hash);\n    SHA512Update(&context->octx, hash, HMACSHA512_DIGEST_LENGTH);\n    SHA512Final(&context->octx, digest);\n\n    zeroize((void *)hash, sizeof hash);\n}\n\nvoid HMACSHA512Init(HMACSHA512CTX *context, const uint8_t *key,\n                    size_t key_length)\n{\n    size_t i;\n    uint8_t pad[SHA512_BLOCK_LENGTH];\n    uint8_t key_hash[SHA512_DIGEST_LENGTH];\n\n    if (key_length > SHA512_BLOCK_LENGTH)\n    {\n        SHA512Init(&context->ictx);\n        SHA512Update(&context->ictx, key, key_length);\n        SHA512Final(&context->ictx, key_hash);\n        key = key_hash;\n        key_length = SHA512_DIGEST_LENGTH;\n    }\n\n    SHA512Init(&context->ictx);\n    memset(pad, 0x36, SHA512_BLOCK_LENGTH);\n\n    for (i = 0; i < key_length; i++)\n        pad[i] ^= key[i];\n\n    SHA512Update(&context->ictx, pad, SHA512_BLOCK_LENGTH);\n    SHA512Init(&context->octx);\n    memset(pad, 0x5c, SHA512_BLOCK_LENGTH);\n\n    for (i = 0; i < key_length; i++)\n        pad[i] ^= key[i];\n\n    SHA512Update(&context->octx, pad, SHA512_BLOCK_LENGTH);\n    zeroize((void *)key_hash, sizeof key_hash);\n}\n\nvoid HMACSHA512Update(HMACSHA512CTX *context, const uint8_t *input,\n                      size_t length)\n{\n    SHA512Update(&context->ictx, input, length);\n}\n"
  },
  {
    "path": "src/UChain/coin/math/external/hmac_sha512.h",
    "content": "/* libsodium: crypto_auth_hmacsha512.h, v0.4.5 2014/04/16 */\n/**\n * Copyright 2005,2007,2009 Colin Percival. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef UC_HMACSHA512_H\n#define UC_HMACSHA512_H\n\n#include <stdint.h>\n#include <stddef.h>\n#include \"sha512.h\"\n\n#define HMACSHA512_DIGEST_LENGTH 64U\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n    typedef struct HMACSHA512CTX\n    {\n        SHA512CTX ictx;\n        SHA512CTX octx;\n    } HMACSHA512CTX;\n\n    void HMACSHA512(const uint8_t *input, size_t length, const uint8_t *key,\n                    size_t key_length, uint8_t digest[HMACSHA512_DIGEST_LENGTH]);\n\n    void HMACSHA512Final(HMACSHA512CTX *context,\n                         uint8_t digest[HMACSHA512_DIGEST_LENGTH]);\n\n    void HMACSHA512Init(HMACSHA512CTX *context, const uint8_t *key,\n                        size_t key_length);\n\n    void HMACSHA512Update(HMACSHA512CTX *context, const uint8_t *input,\n                          size_t length);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "src/UChain/coin/math/external/lax_der_parsing.c",
    "content": "/**********************************************************************\n * Copyright (c) 2015 Pieter Wuille                                   *\n * Distributed under the MIT software license, see the accompanying   *\n * file COPYING or http://www.opensource.org/licenses/mit-license.php.*\n **********************************************************************/\n\n#include <string.h>\n#include <secp256k1.h>\n\n#include \"lax_der_parsing.h\"\n\nint ecdsa_signature_parse_der_lax(const secp256k1_context *ctx, secp256k1_ecdsa_signature *sig, const unsigned char *input, size_t inputlen)\n{\n    size_t rpos, rlen, spos, slen;\n    size_t pos = 0;\n    size_t lenbyte;\n    unsigned char tmpsig[64] = {0};\n    int overflow = 0;\n\n    /* Hack to initialize sig with a correctly-parsed but invalid signature. */\n    secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);\n\n    /* Sequence tag byte */\n    if (pos == inputlen || input[pos] != 0x30)\n    {\n        return 0;\n    }\n    pos++;\n\n    /* Sequence length bytes */\n    if (pos == inputlen)\n    {\n        return 0;\n    }\n    lenbyte = input[pos++];\n    if (lenbyte & 0x80)\n    {\n        lenbyte -= 0x80;\n        if (pos + lenbyte > inputlen)\n        {\n            return 0;\n        }\n        pos += lenbyte;\n    }\n\n    /* Integer tag byte for R */\n    if (pos == inputlen || input[pos] != 0x02)\n    {\n        return 0;\n    }\n    pos++;\n\n    /* Integer length for R */\n    if (pos == inputlen)\n    {\n        return 0;\n    }\n    lenbyte = input[pos++];\n    if (lenbyte & 0x80)\n    {\n        lenbyte -= 0x80;\n        if (pos + lenbyte > inputlen)\n        {\n            return 0;\n        }\n        while (lenbyte > 0 && input[pos] == 0)\n        {\n            pos++;\n            lenbyte--;\n        }\n        if (lenbyte >= sizeof(size_t))\n        {\n            return 0;\n        }\n        rlen = 0;\n        while (lenbyte > 0)\n        {\n            rlen = (rlen << 8) + input[pos];\n            pos++;\n            lenbyte--;\n        }\n    }\n    else\n    {\n        rlen = lenbyte;\n    }\n    if (rlen > inputlen - pos)\n    {\n        return 0;\n    }\n    rpos = pos;\n    pos += rlen;\n\n    /* Integer tag byte for S */\n    if (pos == inputlen || input[pos] != 0x02)\n    {\n        return 0;\n    }\n    pos++;\n\n    /* Integer length for S */\n    if (pos == inputlen)\n    {\n        return 0;\n    }\n    lenbyte = input[pos++];\n    if (lenbyte & 0x80)\n    {\n        lenbyte -= 0x80;\n        if (pos + lenbyte > inputlen)\n        {\n            return 0;\n        }\n        while (lenbyte > 0 && input[pos] == 0)\n        {\n            pos++;\n            lenbyte--;\n        }\n        if (lenbyte >= sizeof(size_t))\n        {\n            return 0;\n        }\n        slen = 0;\n        while (lenbyte > 0)\n        {\n            slen = (slen << 8) + input[pos];\n            pos++;\n            lenbyte--;\n        }\n    }\n    else\n    {\n        slen = lenbyte;\n    }\n    if (slen > inputlen - pos)\n    {\n        return 0;\n    }\n    spos = pos;\n    pos += slen;\n\n    /* Ignore leading zeroes in R */\n    while (rlen > 0 && input[rpos] == 0)\n    {\n        rlen--;\n        rpos++;\n    }\n    /* Copy R value */\n    if (rlen > 32)\n    {\n        overflow = 1;\n    }\n    else\n    {\n        memcpy(tmpsig + 32 - rlen, input + rpos, rlen);\n    }\n\n    /* Ignore leading zeroes in S */\n    while (slen > 0 && input[spos] == 0)\n    {\n        slen--;\n        spos++;\n    }\n    /* Copy S value */\n    if (slen > 32)\n    {\n        overflow = 1;\n    }\n    else\n    {\n        memcpy(tmpsig + 64 - slen, input + spos, slen);\n    }\n\n    if (!overflow)\n    {\n        overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);\n    }\n    if (overflow)\n    {\n        memset(tmpsig, 0, 64);\n        secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);\n    }\n    return 1;\n}\n"
  },
  {
    "path": "src/UChain/coin/math/external/lax_der_parsing.h",
    "content": "/**********************************************************************\n * Copyright (c) 2015 Pieter Wuille                                   *\n * Distributed under the MIT software license, see the accompanying   *\n * file COPYING or http://www.opensource.org/licenses/mit-license.php.*\n **********************************************************************/\n\n/****\n * Please do not link this file directly. It is not part of the libsecp256k1\n * project and does not promise any stability in its API, functionality or\n * presence. Projects which use this code should instead copy this header\n * and its accompanying .c file directly into their codebase.\n ****/\n\n/* This file defines a function that parses DER with various errors and\n * violations. This is not a part of the library itself, because the allowed\n * violations are chosen arbitrarily and do not follow or establish any\n * standard.\n *\n * In many places it matters that different implementations do not only accept\n * the same set of valid signatures, but also reject the same set of signatures.\n * The only means to accomplish that is by strictly obeying a standard, and not\n * accepting anything else.\n *\n * Nonetheless, sometimes there is a need for compatibility with systems that\n * use signatures which do not strictly obey DER. The snippet below shows how\n * certain violations are easily supported. You may need to adapt it.\n *\n * Do not use this for new systems. Use well-defined DER or compact signatures\n * instead if you have the choice (see secp256k1_ecdsa_signature_parse_der and\n * secp256k1_ecdsa_signature_parse_compact).\n *\n * The supported violations are:\n * - All numbers are parsed as nonnegative integers, even though X.609-0207\n *   section 8.3.3 specifies that integers are always encoded as two's\n *   complement.\n * - Integers can have length 0, even though section 8.3.1 says they can't.\n * - Integers with overly long padding are accepted, violation section\n *   8.3.2.\n * - 127-byte long length descriptors are accepted, even though section\n *   8.1.3.5.c says that they are not.\n * - Trailing garbage data inside or after the signature is ignored.\n * - The length descriptor of the sequence is ignored.\n *\n * Compared to for example OpenSSL, many violations are NOT supported:\n * - Using overly long tag descriptors for the sequence or integers inside,\n *   violating section 8.1.2.2.\n * - Encoding primitive integers as constructed values, violating section\n *   8.3.1.\n */\n\n#ifndef _SECP256K1_CONTRIB_LAX_DER_PARSING_H_\n#define _SECP256K1_CONTRIB_LAX_DER_PARSING_H_\n\n#include <secp256k1.h>\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n    /** Parse a signature in \"lax DER\" format\n *\n *  Returns: 1 when the signature could be parsed, 0 otherwise.\n *  Args: ctx:      a secp256k1 context object\n *  Out:  sig:      a pointer to a signature object\n *  In:   input:    a pointer to the signature to be parsed\n *        inputlen: the length of the array pointed to be input\n *\n *  This function will accept any valid DER encoded signature, even if the\n *  encoded numbers are out of range. In addition, it will accept signatures\n *  which violate the DER spec in various ways. Its purpose is to allow\n *  validation of the Bitcoin blockchain, which includes non-DER signatures\n *  from before the network rules were updated to enforce DER. Note that\n *  the set of supported violations is a strict subset of what OpenSSL will\n *  accept.\n *\n *  After the call, sig will always be initialized. If parsing failed or the\n *  encoded numbers are out of range, signature validation with it is\n *  guaranteed to fail for every message and public key.\n */\n    int ecdsa_signature_parse_der_lax(\n        const secp256k1_context *ctx,\n        secp256k1_ecdsa_signature *sig,\n        const unsigned char *input,\n        size_t inputlen) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "src/UChain/coin/math/external/pbkdf2_sha256.c",
    "content": "/**\n * Copyright 2005,2007,2009 Colin Percival\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#include \"pbkdf2_sha256.h\"\n\n#include <stddef.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/types.h>\n#include <UChain/coin/compat.h>\n#include \"hmac_sha256.h\"\n#include \"zeroize.h\"\n\nstatic BC_C_INLINE void be32enc(void *pp, uint32_t x)\n{\n    uint8_t *p = (uint8_t *)pp;\n\n    p[3] = x & 0xff;\n    p[2] = (x >> 8) & 0xff;\n    p[1] = (x >> 16) & 0xff;\n    p[0] = (x >> 24) & 0xff;\n}\n\n/**\n * pbkdf2_sha256(passphrase, passphrase_length, salt, salt_length, c, buf, dk_length):\n * Compute pbkdf2(passwd, salt, c, dkLen) using hmac_sha256 as the PRF, and\n * write the output to buf.  The value dkLen must be at most 32 * (2^32 - 1).\n */\nvoid pbkdf2_sha256(const uint8_t *passphrase, size_t passphrase_length,\n                   const uint8_t *salt, size_t salt_length, uint64_t c,\n                   uint8_t *buf, size_t dk_length)\n{\n    uint8_t ivec[4];\n    uint8_t U[32], T[32];\n    size_t i, j, k, clen;\n    HMACSHA256CTX PShctx, hctx;\n\n    HMACSHA256Init(&PShctx, passphrase, passphrase_length);\n    HMACSHA256Update(&PShctx, salt, salt_length);\n\n    for (i = 0; i * 32 < dk_length; i++)\n    {\n        be32enc(ivec, (uint32_t)(i + 1));\n        memcpy(&hctx, &PShctx, sizeof(HMACSHA256CTX));\n        HMACSHA256Update(&hctx, ivec, 4);\n        HMACSHA256Final(&hctx, U);\n\n        memcpy(T, U, 32);\n        /* LCOV_EXCL_START */\n        for (j = 2; j <= c; j++)\n        {\n            HMACSHA256Init(&hctx, passphrase, passphrase_length);\n            HMACSHA256Update(&hctx, U, 32);\n            HMACSHA256Final(&hctx, U);\n\n            for (k = 0; k < 32; k++)\n            {\n                T[k] ^= U[k];\n            }\n        }\n        /* LCOV_EXCL_STOP */\n\n        clen = dk_length - i * 32;\n        if (clen > 32)\n        {\n            clen = 32;\n        }\n        memcpy(&buf[i * 32], T, clen);\n    }\n    zeroize(&PShctx, sizeof PShctx);\n}\n"
  },
  {
    "path": "src/UChain/coin/math/external/pbkdf2_sha256.h",
    "content": "/**\n * Copyright 2005,2007,2009 Colin Percival\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n * $FreeBSD: src/lib/libmd/sha256.h,v 1.2 2006/01/17 15:35:56 phk Exp $\n */\n#ifndef UC_PBKDF2SHA256_H\n#define UC_PBKDF2SHA256_H\n\n#include <sys/types.h>\n#include <stdint.h>\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n    /**\n * pbkdf2_sha256(passphrase, passphrase_length, salt, salt_length, c, buf, dk_length):\n * Compute pbkdf2(passwd, salt, c, dkLen) using hmac_sha256 as the PRF, and\n * write the output to buf.  The value dkLen must be at most 32 * (2^32 - 1).\n */\n    void pbkdf2_sha256(const uint8_t *passphrase, size_t passphrase_length,\n                       const uint8_t *salt, size_t salt_length, uint64_t c, uint8_t *buf,\n                       size_t dk_length);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "src/UChain/coin/math/external/pkcs5_pbkdf2.c",
    "content": "/* OpenBSD: pkcs5_pbkdf2.c, v 1.9 2015/02/05 12:59:57 millert */\n/**\n * Copyright (c) 2008 Damien Bergamini <damien.bergamini@free.fr>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n#include \"pkcs5_pbkdf2.h\"\n\n#include <stddef.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n#include \"hmac_sha512.h\"\n#include \"zeroize.h\"\n\nint pkcs5_pbkdf2(const uint8_t *passphrase, size_t passphrase_length,\n                 const uint8_t *salt, size_t salt_length, uint8_t *key, size_t key_length,\n                 size_t iterations)\n{\n    uint8_t *asalt;\n    size_t asalt_size;\n    size_t count, index, iteration, length;\n    uint8_t buffer[HMACSHA512_DIGEST_LENGTH];\n    uint8_t digest1[HMACSHA512_DIGEST_LENGTH];\n    uint8_t digest2[HMACSHA512_DIGEST_LENGTH];\n\n    /* An iteration count of 0 is equivalent to a count of 1. */\n    /* A key_length of 0 is a no-op. */\n    /* A salt_length of 0 is perfectly valid. */\n\n    if (salt_length > SIZE_MAX - 4)\n        return -1;\n    asalt_size = salt_length + 4;\n    asalt = malloc(asalt_size);\n    if (asalt == NULL)\n        return -1;\n\n    memcpy(asalt, salt, salt_length);\n    for (count = 1; key_length > 0; count++)\n    {\n        asalt[salt_length + 0] = (count >> 24) & 0xff;\n        asalt[salt_length + 1] = (count >> 16) & 0xff;\n        asalt[salt_length + 2] = (count >> 8) & 0xff;\n        asalt[salt_length + 3] = (count >> 0) & 0xff;\n        HMACSHA512(asalt, asalt_size, passphrase, passphrase_length, digest1);\n        memcpy(buffer, digest1, sizeof(buffer));\n\n        for (iteration = 1; iteration < iterations; iteration++)\n        {\n            HMACSHA512(digest1, sizeof(digest1), passphrase, passphrase_length,\n                       digest2);\n            memcpy(digest1, digest2, sizeof(digest1));\n            for (index = 0; index < sizeof(buffer); index++)\n                buffer[index] ^= digest1[index];\n        }\n\n        length = (key_length < sizeof(buffer) ? key_length : sizeof(buffer));\n        memcpy(key, buffer, length);\n        key += length;\n        key_length -= length;\n    };\n\n    zeroize(digest1, sizeof(digest1));\n    zeroize(digest2, sizeof(digest2));\n    zeroize(buffer, sizeof(buffer));\n    zeroize(asalt, asalt_size);\n    free(asalt);\n\n    return 0;\n}\n"
  },
  {
    "path": "src/UChain/coin/math/external/pkcs5_pbkdf2.h",
    "content": "/* OpenBSD: pkcs5_pbkdf2.c, v 1.9 2015/02/05 12:59:57 millert */\n/**\n * Copyright (c) 2008 Damien Bergamini <damien.bergamini@free.fr>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n#ifndef UC_PKCS5PBKDF2_H\n#define UC_PKCS5PBKDF2_H\n\n#include <stddef.h>\n#include <stdint.h>\n#include \"pkcs5_pbkdf2.h\"\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n    /* Password-Based Key Derivation Function 2 (PKCS #5 v2.0). */\n    /* Code based on IEEE Std 802.11-2007, Annex H.4.2. */\n    /* returns 0 if successful. */\n    int pkcs5_pbkdf2(const uint8_t *passphrase, size_t passphrase_length,\n                     const uint8_t *salt, size_t salt_length, uint8_t *key, size_t key_length,\n                     size_t iterations);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "src/UChain/coin/math/external/ripemd160.c",
    "content": "/* OpenBSD: rmd160.h, v 1.5 2009/07/05 */\n/**\n * Copyright (c) 2001 Markus Friedl.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n/**\n* Preneel, Bosselaers, Dobbertin, \"The Cryptographic Hash Function RIPEMD-160\",\n* RSA Laboratories, CryptoBytes, Volume 3, Number 2, Autumn 1997,\n* ftp://ftp.rsasecurity.com/pub/cryptobytes/crypto3n2.pdf\n*/\n#include \"ripemd160.h\"\n\n#include <stdint.h>\n#include <string.h>\n#include <UChain/coin/compat.h>\n#include \"zeroize.h\"\n\n#ifdef __BIG_ENDIAN__\n#define RIPEMD160_BIG_ENDIAN\n#elif defined __LITTLE_ENDIAN__\n/* override */\n#elif defined __BYTE_ORDER\n#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__\n#define RIPEMD160_BIG_ENDIAN\n#endif\n#else               /* !defined __LITTLE_ENDIAN__ */\n#include <endian.h> /* machine/endian.h */\n#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__\n#define RIPEMD160_BIG_ENDIAN\n#endif\n#endif\n\n#define byte_length 8\n\n#define PUT_64BIT_LE(cp, value)                            \\\n    do                                                     \\\n    {                                                      \\\n        (cp)[7] = (uint8_t)((value) >> (byte_length * 7)); \\\n        (cp)[6] = (uint8_t)((value) >> (byte_length * 6)); \\\n        (cp)[5] = (uint8_t)((value) >> (byte_length * 5)); \\\n        (cp)[4] = (uint8_t)((value) >> (byte_length * 4)); \\\n        (cp)[3] = (uint8_t)((value) >> (byte_length * 3)); \\\n        (cp)[2] = (uint8_t)((value) >> (byte_length * 2)); \\\n        (cp)[1] = (uint8_t)((value) >> (byte_length * 1)); \\\n        (cp)[0] = (uint8_t)((value) >> (byte_length * 0)); \\\n    } while (0)\n\n#define PUT_32BIT_LE(cp, value)                            \\\n    do                                                     \\\n    {                                                      \\\n        (cp)[3] = (uint8_t)((value) >> (byte_length * 3)); \\\n        (cp)[2] = (uint8_t)((value) >> (byte_length * 2)); \\\n        (cp)[1] = (uint8_t)((value) >> (byte_length * 1)); \\\n        (cp)[0] = (uint8_t)((value) >> (byte_length * 0)); \\\n    } while (0)\n\n#define H0 0x67452301U\n#define H1 0xEFCDAB89U\n#define H2 0x98BADCFEU\n#define H3 0x10325476U\n#define H4 0xC3D2E1F0U\n\n#define K0 0x00000000U\n#define K1 0x5A827999U\n#define K2 0x6ED9EBA1U\n#define K3 0x8F1BBCDCU\n#define K4 0xA953FD4EU\n\n#define KK0 0x50A28BE6U\n#define KK1 0x5C4DD124U\n#define KK2 0x6D703EF3U\n#define KK3 0x7A6D76E9U\n#define KK4 0x00000000U\n\n#define ROL(n, x) (((x) << (n)) | ((x) >> (32 - (n))))\n\n#define F0(x, y, z) ((x) ^ (y) ^ (z))\n#define F1(x, y, z) (((x) & (y)) | ((~x) & (z)))\n#define F2(x, y, z) (((x) | (~y)) ^ (z))\n#define F3(x, y, z) (((x) & (z)) | ((y) & (~z)))\n#define F4(x, y, z) ((x) ^ ((y) | (~z)))\n\n#define R(a, b, c, d, e, Fj, Kj, sj, rj)               \\\n    do                                                 \\\n    {                                                  \\\n        a = ROL(sj, a + Fj(b, c, d) + X(rj) + Kj) + e; \\\n        c = ROL(10, c);                                \\\n    } while (0)\n\n#define X(i) x[i]\n\nstatic uint8_t PAD[RMD160_BLOCK_LENGTH] =\n    {\n        0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};\n\nvoid RMD160(const uint8_t *input, size_t length,\n            uint8_t digest[RMD160_DIGEST_LENGTH])\n{\n    RMD160CTX ctx;\n    RMD160Init(&ctx);\n    RMD160Update(&ctx, input, length);\n    RMD160Final(&ctx, digest);\n}\n\nvoid RMD160Final(RMD160CTX *context, uint8_t digest[RMD160_DIGEST_LENGTH])\n{\n    int i;\n    RMD160Pad(context);\n    for (i = 0; i < 5; i++)\n    {\n        PUT_32BIT_LE(digest + i * 4, context->state[i]);\n    }\n\n    zeroize(context, sizeof *context);\n}\n\nvoid RMD160Init(RMD160CTX *context)\n{\n    context->count = 0;\n\n    context->state[0] = H0;\n    context->state[1] = H1;\n    context->state[2] = H2;\n    context->state[3] = H3;\n    context->state[4] = H4;\n}\n\nvoid RMD160Pad(RMD160CTX *context)\n{\n    uint8_t len[8];\n    uint32_t plen;\n\n    PUT_64BIT_LE(len, context->count);\n\n    plen = RMD160_BLOCK_LENGTH -\n           ((context->count / 8) % RMD160_BLOCK_LENGTH);\n\n    if (plen < 1 + 8)\n    {\n        plen += RMD160_BLOCK_LENGTH;\n    }\n\n    RMD160Update(context, PAD, plen - 8);\n    RMD160Update(context, len, 8);\n}\n\nvoid RMD160Transform(uint32_t state[RMD160_STATE_LENGTH],\n                     const uint8_t block[RMD160_BLOCK_LENGTH])\n{\n    uint32_t a, b, c, d, e, aa, bb, cc, dd, ee, t, x[16];\n\n#ifdef RIPEMD160_BIG_ENDIAN\n    memcpy(x, block, RMD160_BLOCK_LENGTH);\n#else\n    int i;\n    for (i = 0; i < 16; i++)\n    {\n        x[i] = (uint32_t)(\n            (uint32_t)(block[i * 4 + 0]) |\n            (uint32_t)(block[i * 4 + 1]) << byte_length * 1 |\n            (uint32_t)(block[i * 4 + 2]) << byte_length * 2 |\n            (uint32_t)(block[i * 4 + 3]) << byte_length * 3);\n    }\n#endif\n\n    a = state[0];\n    b = state[1];\n    c = state[2];\n    d = state[3];\n    e = state[4];\n\n    R(a, b, c, d, e, F0, K0, 11, 0);\n    R(e, a, b, c, d, F0, K0, 14, 1);\n    R(d, e, a, b, c, F0, K0, 15, 2);\n    R(c, d, e, a, b, F0, K0, 12, 3);\n    R(b, c, d, e, a, F0, K0, 5, 4);\n    R(a, b, c, d, e, F0, K0, 8, 5);\n    R(e, a, b, c, d, F0, K0, 7, 6);\n    R(d, e, a, b, c, F0, K0, 9, 7);\n    R(c, d, e, a, b, F0, K0, 11, 8);\n    R(b, c, d, e, a, F0, K0, 13, 9);\n    R(a, b, c, d, e, F0, K0, 14, 10);\n    R(e, a, b, c, d, F0, K0, 15, 11);\n    R(d, e, a, b, c, F0, K0, 6, 12);\n    R(c, d, e, a, b, F0, K0, 7, 13);\n    R(b, c, d, e, a, F0, K0, 9, 14);\n    R(a, b, c, d, e, F0, K0, 8, 15);\n\n    R(e, a, b, c, d, F1, K1, 7, 7);\n    R(d, e, a, b, c, F1, K1, 6, 4);\n    R(c, d, e, a, b, F1, K1, 8, 13);\n    R(b, c, d, e, a, F1, K1, 13, 1);\n    R(a, b, c, d, e, F1, K1, 11, 10);\n    R(e, a, b, c, d, F1, K1, 9, 6);\n    R(d, e, a, b, c, F1, K1, 7, 15);\n    R(c, d, e, a, b, F1, K1, 15, 3);\n    R(b, c, d, e, a, F1, K1, 7, 12);\n    R(a, b, c, d, e, F1, K1, 12, 0);\n    R(e, a, b, c, d, F1, K1, 15, 9);\n    R(d, e, a, b, c, F1, K1, 9, 5);\n    R(c, d, e, a, b, F1, K1, 11, 2);\n    R(b, c, d, e, a, F1, K1, 7, 14);\n    R(a, b, c, d, e, F1, K1, 13, 11);\n    R(e, a, b, c, d, F1, K1, 12, 8);\n\n    R(d, e, a, b, c, F2, K2, 11, 3);\n    R(c, d, e, a, b, F2, K2, 13, 10);\n    R(b, c, d, e, a, F2, K2, 6, 14);\n    R(a, b, c, d, e, F2, K2, 7, 4);\n    R(e, a, b, c, d, F2, K2, 14, 9);\n    R(d, e, a, b, c, F2, K2, 9, 15);\n    R(c, d, e, a, b, F2, K2, 13, 8);\n    R(b, c, d, e, a, F2, K2, 15, 1);\n    R(a, b, c, d, e, F2, K2, 14, 2);\n    R(e, a, b, c, d, F2, K2, 8, 7);\n    R(d, e, a, b, c, F2, K2, 13, 0);\n    R(c, d, e, a, b, F2, K2, 6, 6);\n    R(b, c, d, e, a, F2, K2, 5, 13);\n    R(a, b, c, d, e, F2, K2, 12, 11);\n    R(e, a, b, c, d, F2, K2, 7, 5);\n    R(d, e, a, b, c, F2, K2, 5, 12);\n\n    R(c, d, e, a, b, F3, K3, 11, 1);\n    R(b, c, d, e, a, F3, K3, 12, 9);\n    R(a, b, c, d, e, F3, K3, 14, 11);\n    R(e, a, b, c, d, F3, K3, 15, 10);\n    R(d, e, a, b, c, F3, K3, 14, 0);\n    R(c, d, e, a, b, F3, K3, 15, 8);\n    R(b, c, d, e, a, F3, K3, 9, 12);\n    R(a, b, c, d, e, F3, K3, 8, 4);\n    R(e, a, b, c, d, F3, K3, 9, 13);\n    R(d, e, a, b, c, F3, K3, 14, 3);\n    R(c, d, e, a, b, F3, K3, 5, 7);\n    R(b, c, d, e, a, F3, K3, 6, 15);\n    R(a, b, c, d, e, F3, K3, 8, 14);\n    R(e, a, b, c, d, F3, K3, 6, 5);\n    R(d, e, a, b, c, F3, K3, 5, 6);\n    R(c, d, e, a, b, F3, K3, 12, 2);\n\n    R(b, c, d, e, a, F4, K4, 9, 4);\n    R(a, b, c, d, e, F4, K4, 15, 0);\n    R(e, a, b, c, d, F4, K4, 5, 5);\n    R(d, e, a, b, c, F4, K4, 11, 9);\n    R(c, d, e, a, b, F4, K4, 6, 7);\n    R(b, c, d, e, a, F4, K4, 8, 12);\n    R(a, b, c, d, e, F4, K4, 13, 2);\n    R(e, a, b, c, d, F4, K4, 12, 10);\n    R(d, e, a, b, c, F4, K4, 5, 14);\n    R(c, d, e, a, b, F4, K4, 12, 1);\n    R(b, c, d, e, a, F4, K4, 13, 3);\n    R(a, b, c, d, e, F4, K4, 14, 8);\n    R(e, a, b, c, d, F4, K4, 11, 11);\n    R(d, e, a, b, c, F4, K4, 8, 6);\n    R(c, d, e, a, b, F4, K4, 5, 15);\n    R(b, c, d, e, a, F4, K4, 6, 13);\n\n    aa = a;\n    bb = b;\n    cc = c;\n    dd = d;\n    ee = e;\n\n    a = state[0];\n    b = state[1];\n    c = state[2];\n    d = state[3];\n    e = state[4];\n\n    R(a, b, c, d, e, F4, KK0, 8, 5);\n    R(e, a, b, c, d, F4, KK0, 9, 14);\n    R(d, e, a, b, c, F4, KK0, 9, 7);\n    R(c, d, e, a, b, F4, KK0, 11, 0);\n    R(b, c, d, e, a, F4, KK0, 13, 9);\n    R(a, b, c, d, e, F4, KK0, 15, 2);\n    R(e, a, b, c, d, F4, KK0, 15, 11);\n    R(d, e, a, b, c, F4, KK0, 5, 4);\n    R(c, d, e, a, b, F4, KK0, 7, 13);\n    R(b, c, d, e, a, F4, KK0, 7, 6);\n    R(a, b, c, d, e, F4, KK0, 8, 15);\n    R(e, a, b, c, d, F4, KK0, 11, 8);\n    R(d, e, a, b, c, F4, KK0, 14, 1);\n    R(c, d, e, a, b, F4, KK0, 14, 10);\n    R(b, c, d, e, a, F4, KK0, 12, 3);\n    R(a, b, c, d, e, F4, KK0, 6, 12);\n\n    R(e, a, b, c, d, F3, KK1, 9, 6);\n    R(d, e, a, b, c, F3, KK1, 13, 11);\n    R(c, d, e, a, b, F3, KK1, 15, 3);\n    R(b, c, d, e, a, F3, KK1, 7, 7);\n    R(a, b, c, d, e, F3, KK1, 12, 0);\n    R(e, a, b, c, d, F3, KK1, 8, 13);\n    R(d, e, a, b, c, F3, KK1, 9, 5);\n    R(c, d, e, a, b, F3, KK1, 11, 10);\n    R(b, c, d, e, a, F3, KK1, 7, 14);\n    R(a, b, c, d, e, F3, KK1, 7, 15);\n    R(e, a, b, c, d, F3, KK1, 12, 8);\n    R(d, e, a, b, c, F3, KK1, 7, 12);\n    R(c, d, e, a, b, F3, KK1, 6, 4);\n    R(b, c, d, e, a, F3, KK1, 15, 9);\n    R(a, b, c, d, e, F3, KK1, 13, 1);\n    R(e, a, b, c, d, F3, KK1, 11, 2);\n\n    R(d, e, a, b, c, F2, KK2, 9, 15);\n    R(c, d, e, a, b, F2, KK2, 7, 5);\n    R(b, c, d, e, a, F2, KK2, 15, 1);\n    R(a, b, c, d, e, F2, KK2, 11, 3);\n    R(e, a, b, c, d, F2, KK2, 8, 7);\n    R(d, e, a, b, c, F2, KK2, 6, 14);\n    R(c, d, e, a, b, F2, KK2, 6, 6);\n    R(b, c, d, e, a, F2, KK2, 14, 9);\n    R(a, b, c, d, e, F2, KK2, 12, 11);\n    R(e, a, b, c, d, F2, KK2, 13, 8);\n    R(d, e, a, b, c, F2, KK2, 5, 12);\n    R(c, d, e, a, b, F2, KK2, 14, 2);\n    R(b, c, d, e, a, F2, KK2, 13, 10);\n    R(a, b, c, d, e, F2, KK2, 13, 0);\n    R(e, a, b, c, d, F2, KK2, 7, 4);\n    R(d, e, a, b, c, F2, KK2, 5, 13);\n\n    R(c, d, e, a, b, F1, KK3, 15, 8);\n    R(b, c, d, e, a, F1, KK3, 5, 6);\n    R(a, b, c, d, e, F1, KK3, 8, 4);\n    R(e, a, b, c, d, F1, KK3, 11, 1);\n    R(d, e, a, b, c, F1, KK3, 14, 3);\n    R(c, d, e, a, b, F1, KK3, 14, 11);\n    R(b, c, d, e, a, F1, KK3, 6, 15);\n    R(a, b, c, d, e, F1, KK3, 14, 0);\n    R(e, a, b, c, d, F1, KK3, 6, 5);\n    R(d, e, a, b, c, F1, KK3, 9, 12);\n    R(c, d, e, a, b, F1, KK3, 12, 2);\n    R(b, c, d, e, a, F1, KK3, 9, 13);\n    R(a, b, c, d, e, F1, KK3, 12, 9);\n    R(e, a, b, c, d, F1, KK3, 5, 7);\n    R(d, e, a, b, c, F1, KK3, 15, 10);\n    R(c, d, e, a, b, F1, KK3, 8, 14);\n\n    R(b, c, d, e, a, F0, KK4, 8, 12);\n    R(a, b, c, d, e, F0, KK4, 5, 15);\n    R(e, a, b, c, d, F0, KK4, 12, 10);\n    R(d, e, a, b, c, F0, KK4, 9, 4);\n    R(c, d, e, a, b, F0, KK4, 12, 1);\n    R(b, c, d, e, a, F0, KK4, 5, 5);\n    R(a, b, c, d, e, F0, KK4, 14, 8);\n    R(e, a, b, c, d, F0, KK4, 6, 7);\n    R(d, e, a, b, c, F0, KK4, 8, 6);\n    R(c, d, e, a, b, F0, KK4, 13, 2);\n    R(b, c, d, e, a, F0, KK4, 6, 13);\n    R(a, b, c, d, e, F0, KK4, 5, 14);\n    R(e, a, b, c, d, F0, KK4, 15, 0);\n    R(d, e, a, b, c, F0, KK4, 13, 3);\n    R(c, d, e, a, b, F0, KK4, 11, 9);\n    R(b, c, d, e, a, F0, KK4, 11, 11);\n\n    t = state[1] + cc + d;\n    state[1] = state[2] + dd + e;\n    state[2] = state[3] + ee + a;\n    state[3] = state[4] + aa + b;\n    state[4] = state[0] + bb + c;\n    state[0] = t;\n}\n\nvoid RMD160Update(RMD160CTX *context, const uint8_t *input, size_t length)\n{\n    uint32_t have, off, need;\n\n    have = (context->count / 8) % RMD160_BLOCK_LENGTH;\n    need = RMD160_BLOCK_LENGTH - have;\n    context->count += 8 * length;\n    off = 0;\n\n    if (length >= need)\n    {\n        if (have)\n        {\n            memcpy(context->buffer + have, input, need);\n            RMD160Transform(context->state, context->buffer);\n            off = need;\n            have = 0;\n        }\n\n        while (off + RMD160_BLOCK_LENGTH <= length)\n        {\n            RMD160Transform(context->state, input + off);\n            off += RMD160_BLOCK_LENGTH;\n        }\n    }\n\n    if (off < length)\n    {\n        memcpy(context->buffer + have, input + off, length - off);\n    }\n}\n"
  },
  {
    "path": "src/UChain/coin/math/external/ripemd160.h",
    "content": "/* OpenBSD: rmd160.h, v1.5 2009/07/05 */\n/**\n * Copyright (c) 2001 Markus Friedl. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n#ifndef UC_RIPEMD160_H\n#define UC_RIPEMD160_H\n\n#include <stdint.h>\n#include <stddef.h>\n\n#define RMD160_STATE_LENGTH 5U\n#define RMD160_BLOCK_LENGTH 64U\n#define RMD160_DIGEST_LENGTH 20U\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n    typedef struct RMD160CTX\n    {\n        uint32_t state[RMD160_STATE_LENGTH];\n        uint64_t count;\n        uint8_t buffer[RMD160_BLOCK_LENGTH];\n    } RMD160CTX;\n\n    void RMD160(const uint8_t *input, size_t length,\n                uint8_t digest[RMD160_DIGEST_LENGTH]);\n\n    void RMD160Final(RMD160CTX *context, uint8_t digest[RMD160_DIGEST_LENGTH]);\n\n    void RMD160Init(RMD160CTX *context);\n\n    void RMD160Pad(RMD160CTX *context);\n\n    void RMD160Transform(uint32_t state[RMD160_STATE_LENGTH],\n                         const uint8_t block[RMD160_BLOCK_LENGTH]);\n\n    void RMD160Update(RMD160CTX *context, const uint8_t *input, size_t length);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "src/UChain/coin/math/external/sha1.c",
    "content": "/* OpenBSD: sha1.c, v 1.23 2014/01/08 */\n/**\n* SHA-1 in C\n* By Steve Reid <steve@edmweb.com>\n* 100% Public Domain\n*\n* Test Vectors (from FIPS PUB 180-1)\n* \"abc\"\n*   A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D\n* \"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\"\n*   84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1\n* A million repetitions of \"a\"\n*   34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F\n*/\n#include \"sha1.h\"\n\n#include <stdint.h>\n#include <string.h>\n#include <UChain/coin/compat.h>\n#include \"zeroize.h\"\n\n#ifdef __BIG_ENDIAN__\n#define SHA1_BIG_ENDIAN\n#elif defined __LITTLE_ENDIAN__\n/* override */\n#elif defined __BYTE_ORDER\n#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__\n#define SHA1_BIG_ENDIAN\n#endif\n#else               /* !defined __LITTLE_ENDIAN__ */\n#include <endian.h> /* machine/endian.h */\n#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__\n#define SHA1_BIG_ENDIAN\n#endif\n#endif\n\n#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))\n\n#ifdef SHA1_BIG_ENDIAN\n#define blk0(b, i) b->l[i]\n#else\n#define blk0(b, i) (b->l[i] =                             \\\n                        (rol(b->l[i], 24) & 0xFF00FF00) | \\\n                        (rol(b->l[i], 8) & 0x00FF00FF))\n#endif\n\n#define blk(b, i) (b->l[i & 15] =                   \\\n                       rol(b->l[(i + 13) & 15] ^    \\\n                               b->l[(i + 8) & 15] ^ \\\n                               b->l[(i + 2) & 15] ^ \\\n                               b->l[i & 15],        \\\n                           1))\n\n#define R0(b, v, w, x, y, z, i)                                     \\\n    z += ((w & (x ^ y)) ^ y) + blk0(b, i) + 0x5A827999 + rol(v, 5); \\\n    w = rol(w, 30);\n\n#define R1(b, v, w, x, y, z, i)                                    \\\n    z += ((w & (x ^ y)) ^ y) + blk(b, i) + 0x5A827999 + rol(v, 5); \\\n    w = rol(w, 30);\n\n#define R2(b, v, w, x, y, z, i)                            \\\n    z += (w ^ x ^ y) + blk(b, i) + 0x6ED9EBA1 + rol(v, 5); \\\n    w = rol(w, 30);\n\n#define R3(b, v, w, x, y, z, i)                                          \\\n    z += (((w | x) & y) | (w & x)) + blk(b, i) + 0x8F1BBCDC + rol(v, 5); \\\n    w = rol(w, 30);\n\n#define R4(b, v, w, x, y, z, i)                            \\\n    z += (w ^ x ^ y) + blk(b, i) + 0xCA62C1D6 + rol(v, 5); \\\n    w = rol(w, 30);\n\ntypedef union {\n    uint8_t c[64];\n    uint32_t l[16];\n} CHAR64LONG16;\n\nvoid SHA1_(const uint8_t *input, size_t length,\n           uint8_t digest[SHA1_DIGEST_LENGTH])\n{\n    SHA1CTX context;\n    SHA1Init(&context);\n    SHA1Update(&context, input, length);\n    SHA1Final(&context, digest);\n}\n\nvoid SHA1Final(SHA1CTX *context, uint8_t digest[SHA1_DIGEST_LENGTH])\n{\n    uint8_t i;\n    SHA1Pad(context);\n    for (i = 0; i < SHA1_DIGEST_LENGTH; i++)\n    {\n        digest[i] = (uint8_t)((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);\n    }\n\n    zeroize(context, sizeof *context);\n}\n\nvoid SHA1Init(SHA1CTX *context)\n{\n    context->count = 0;\n\n    context->state[0] = 0x67452301;\n    context->state[1] = 0xEFCDAB89;\n    context->state[2] = 0x98BADCFE;\n    context->state[3] = 0x10325476;\n    context->state[4] = 0xC3D2E1F0;\n}\n\nvoid SHA1Pad(SHA1CTX *context)\n{\n    uint8_t i;\n    uint8_t len[8];\n\n    for (i = 0; i < 8; i++)\n    {\n        len[i] = (uint8_t)((context->count >> ((7 - (i & 7)) * 8)) & 255);\n    }\n\n    SHA1Update(context, (uint8_t *)\"\\200\", 1);\n\n    while ((context->count & 504) != 448)\n    {\n        SHA1Update(context, (uint8_t *)\"\\0\", 1);\n    }\n\n    SHA1Update(context, len, 8);\n}\n\nvoid SHA1Transform(uint32_t state[SHA1_STATE_LENGTH],\n                   const uint8_t block[SHA1_BLOCK_LENGTH])\n{\n    uint32_t a, b, c, d, e;\n    uint8_t workspace[SHA1_BLOCK_LENGTH];\n    CHAR64LONG16 *w = (CHAR64LONG16 *)workspace;\n\n    memcpy(w, block, SHA1_BLOCK_LENGTH);\n\n    a = state[0];\n    b = state[1];\n    c = state[2];\n    d = state[3];\n    e = state[4];\n\n    R0(w, a, b, c, d, e, 0);\n    R0(w, e, a, b, c, d, 1);\n    R0(w, d, e, a, b, c, 2);\n    R0(w, c, d, e, a, b, 3);\n    R0(w, b, c, d, e, a, 4);\n    R0(w, a, b, c, d, e, 5);\n    R0(w, e, a, b, c, d, 6);\n    R0(w, d, e, a, b, c, 7);\n    R0(w, c, d, e, a, b, 8);\n    R0(w, b, c, d, e, a, 9);\n    R0(w, a, b, c, d, e, 10);\n    R0(w, e, a, b, c, d, 11);\n    R0(w, d, e, a, b, c, 12);\n    R0(w, c, d, e, a, b, 13);\n    R0(w, b, c, d, e, a, 14);\n    R0(w, a, b, c, d, e, 15);\n    R1(w, e, a, b, c, d, 16);\n    R1(w, d, e, a, b, c, 17);\n    R1(w, c, d, e, a, b, 18);\n    R1(w, b, c, d, e, a, 19);\n    R2(w, a, b, c, d, e, 20);\n    R2(w, e, a, b, c, d, 21);\n    R2(w, d, e, a, b, c, 22);\n    R2(w, c, d, e, a, b, 23);\n    R2(w, b, c, d, e, a, 24);\n    R2(w, a, b, c, d, e, 25);\n    R2(w, e, a, b, c, d, 26);\n    R2(w, d, e, a, b, c, 27);\n    R2(w, c, d, e, a, b, 28);\n    R2(w, b, c, d, e, a, 29);\n    R2(w, a, b, c, d, e, 30);\n    R2(w, e, a, b, c, d, 31);\n    R2(w, d, e, a, b, c, 32);\n    R2(w, c, d, e, a, b, 33);\n    R2(w, b, c, d, e, a, 34);\n    R2(w, a, b, c, d, e, 35);\n    R2(w, e, a, b, c, d, 36);\n    R2(w, d, e, a, b, c, 37);\n    R2(w, c, d, e, a, b, 38);\n    R2(w, b, c, d, e, a, 39);\n    R3(w, a, b, c, d, e, 40);\n    R3(w, e, a, b, c, d, 41);\n    R3(w, d, e, a, b, c, 42);\n    R3(w, c, d, e, a, b, 43);\n    R3(w, b, c, d, e, a, 44);\n    R3(w, a, b, c, d, e, 45);\n    R3(w, e, a, b, c, d, 46);\n    R3(w, d, e, a, b, c, 47);\n    R3(w, c, d, e, a, b, 48);\n    R3(w, b, c, d, e, a, 49);\n    R3(w, a, b, c, d, e, 50);\n    R3(w, e, a, b, c, d, 51);\n    R3(w, d, e, a, b, c, 52);\n    R3(w, c, d, e, a, b, 53);\n    R3(w, b, c, d, e, a, 54);\n    R3(w, a, b, c, d, e, 55);\n    R3(w, e, a, b, c, d, 56);\n    R3(w, d, e, a, b, c, 57);\n    R3(w, c, d, e, a, b, 58);\n    R3(w, b, c, d, e, a, 59);\n    R4(w, a, b, c, d, e, 60);\n    R4(w, e, a, b, c, d, 61);\n    R4(w, d, e, a, b, c, 62);\n    R4(w, c, d, e, a, b, 63);\n    R4(w, b, c, d, e, a, 64);\n    R4(w, a, b, c, d, e, 65);\n    R4(w, e, a, b, c, d, 66);\n    R4(w, d, e, a, b, c, 67);\n    R4(w, c, d, e, a, b, 68);\n    R4(w, b, c, d, e, a, 69);\n    R4(w, a, b, c, d, e, 70);\n    R4(w, e, a, b, c, d, 71);\n    R4(w, d, e, a, b, c, 72);\n    R4(w, c, d, e, a, b, 73);\n    R4(w, b, c, d, e, a, 74);\n    R4(w, a, b, c, d, e, 75);\n    R4(w, e, a, b, c, d, 76);\n    R4(w, d, e, a, b, c, 77);\n    R4(w, c, d, e, a, b, 78);\n    R4(w, b, c, d, e, a, 79);\n\n    state[0] += a;\n    state[1] += b;\n    state[2] += c;\n    state[3] += d;\n    state[4] += e;\n\n    a = b = c = d = e = 0;\n}\n\nvoid SHA1Update(SHA1CTX *context, const uint8_t *input, size_t length)\n{\n    uint32_t i = 0;\n    uint32_t j = (uint32_t)((context->count >> 3) & 63);\n\n    context->count += (length << 3);\n\n    if ((j + length) > 63)\n    {\n        memcpy(&context->buffer[j], input, (i = 64 - j));\n        SHA1Transform(context->state, context->buffer);\n\n        for (; i + 63 < length; i += 64)\n            SHA1Transform(context->state, (uint8_t *)&input[i]);\n\n        j = 0;\n    }\n\n    memcpy(&context->buffer[j], &input[i], length - i);\n}\n"
  },
  {
    "path": "src/UChain/coin/math/external/sha1.h",
    "content": "/* OpenBSD: sha1.h, v1.5 2007/09/10 */\n/**\n* SHA-1 in C\n* By Steve Reid <steve@edmweb.com>\n* 100% Public Domain\n*/\n#ifndef UC_SHA1_H\n#define UC_SHA1_H\n\n#include <stdint.h>\n#include <stddef.h>\n\n#define SHA1_STATE_LENGTH 5U\n#define SHA1_BLOCK_LENGTH 64U\n#define SHA1_DIGEST_LENGTH 20U\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n    typedef struct SHA1CTX\n    {\n        uint32_t state[SHA1_STATE_LENGTH];\n        uint64_t count;\n        uint8_t buffer[SHA1_BLOCK_LENGTH];\n    } SHA1CTX;\n\n    void SHA1_(const uint8_t *input, size_t length,\n               uint8_t digest[SHA1_DIGEST_LENGTH]);\n\n    void SHA1Final(SHA1CTX *context, uint8_t digest[SHA1_DIGEST_LENGTH]);\n\n    void SHA1Init(SHA1CTX *context);\n\n    void SHA1Pad(SHA1CTX *context);\n\n    void SHA1Transform(uint32_t state[SHA1_STATE_LENGTH],\n                       const uint8_t block[SHA1_BLOCK_LENGTH]);\n\n    void SHA1Update(SHA1CTX *context, const uint8_t *input, size_t length);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "src/UChain/coin/math/external/sha256.c",
    "content": "/* libsodium: hash_sha256.c, v0.4.5 2014/04/16 */\n/**\n * Copyright 2005,2007,2009 Colin Percival. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#include \"sha256.h\"\n\n#include <stdint.h>\n#include <string.h>\n#include \"zeroize.h\"\n\nstatic uint32_t be32dec(const void *pp)\n{\n    const uint8_t *p = (uint8_t const *)pp;\n\n    return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) +\n            ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24));\n}\n\nstatic void be32enc(void *pp, uint32_t x)\n{\n    uint8_t *p = (uint8_t *)pp;\n\n    p[3] = x & 0xff;\n    p[2] = (x >> 8) & 0xff;\n    p[1] = (x >> 16) & 0xff;\n    p[0] = (x >> 24) & 0xff;\n}\n\nstatic void be32enc_vect(uint8_t *dst, const uint32_t *src, size_t len)\n{\n    size_t i;\n    for (i = 0; i < len / 4; i++)\n    {\n        be32enc(dst + i * 4, src[i]);\n    }\n}\n\nstatic void be32dec_vect(uint32_t *dst, const uint8_t *src, size_t len)\n{\n    size_t i;\n    for (i = 0; i < len / 4; i++)\n    {\n        dst[i] = be32dec(src + i * 4);\n    }\n}\n\n#define Ch(x, y, z) ((x & (y ^ z)) ^ z)\n#define Maj(x, y, z) ((x & (y | z)) | (y & z))\n#define SHR(x, n) (x >> n)\n#define ROTR(x, n) ((x >> n) | (x << (32 - n)))\n#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))\n#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))\n#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))\n#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))\n\n#define RND(a, b, c, d, e, f, g, h, k) \\\n    t0 = h + S1(e) + Ch(e, f, g) + k;  \\\n    t1 = S0(a) + Maj(a, b, c);         \\\n    d += t0;                           \\\n    h = t0 + t1;\n\n#define RNDr(S, W, i, k)                  \\\n    RND(S[(64 - i) % 8], S[(65 - i) % 8], \\\n        S[(66 - i) % 8], S[(67 - i) % 8], \\\n        S[(68 - i) % 8], S[(69 - i) % 8], \\\n        S[(70 - i) % 8], S[(71 - i) % 8], \\\n        W[i] + k)\n\nstatic unsigned char PAD[SHA256_BLOCK_LENGTH] =\n    {\n        0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};\n\nvoid SHA256_(const uint8_t *input, size_t length,\n             uint8_t digest[SHA256_DIGEST_LENGTH])\n{\n    SHA256CTX context;\n    SHA256Init(&context);\n    SHA256Update(&context, input, length);\n    SHA256Final(&context, digest);\n}\n\nvoid SHA256Final(SHA256CTX *context, uint8_t digest[SHA256_DIGEST_LENGTH])\n{\n    SHA256Pad(context);\n    be32enc_vect(digest, context->state, SHA256_DIGEST_LENGTH);\n    zeroize((void *)context, sizeof *context);\n}\n\nvoid SHA256Init(SHA256CTX *context)\n{\n    context->count[0] = context->count[1] = 0;\n\n    context->state[0] = 0x6A09E667;\n    context->state[1] = 0xBB67AE85;\n    context->state[2] = 0x3C6EF372;\n    context->state[3] = 0xA54FF53A;\n    context->state[4] = 0x510E527F;\n    context->state[5] = 0x9B05688C;\n    context->state[6] = 0x1F83D9AB;\n    context->state[7] = 0x5BE0CD19;\n}\n\nvoid SHA256Pad(SHA256CTX *context)\n{\n    uint8_t len[8];\n    uint32_t r, plen;\n\n    be32enc_vect(len, context->count, 8);\n\n    r = (context->count[1] >> 3) & 0x3f;\n    plen = (r < 56) ? (56 - r) : (120 - r);\n\n    SHA256Update(context, PAD, plen);\n    SHA256Update(context, len, 8);\n}\n\nvoid SHA256Transform(uint32_t state[SHA256_STATE_LENGTH],\n                     const uint8_t block[SHA256_BLOCK_LENGTH])\n{\n    int i;\n    uint32_t W[64];\n    uint32_t S[8];\n    uint32_t t0, t1;\n\n    be32dec_vect(W, block, SHA256_BLOCK_LENGTH);\n\n    for (i = 16; i < 64; i++)\n    {\n        W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];\n    }\n\n    memcpy(S, state, 32);\n\n    RNDr(S, W, 0, 0x428a2f98);\n    RNDr(S, W, 1, 0x71374491);\n    RNDr(S, W, 2, 0xb5c0fbcf);\n    RNDr(S, W, 3, 0xe9b5dba5);\n    RNDr(S, W, 4, 0x3956c25b);\n    RNDr(S, W, 5, 0x59f111f1);\n    RNDr(S, W, 6, 0x923f82a4);\n    RNDr(S, W, 7, 0xab1c5ed5);\n    RNDr(S, W, 8, 0xd807aa98);\n    RNDr(S, W, 9, 0x12835b01);\n    RNDr(S, W, 10, 0x243185be);\n    RNDr(S, W, 11, 0x550c7dc3);\n    RNDr(S, W, 12, 0x72be5d74);\n    RNDr(S, W, 13, 0x80deb1fe);\n    RNDr(S, W, 14, 0x9bdc06a7);\n    RNDr(S, W, 15, 0xc19bf174);\n    RNDr(S, W, 16, 0xe49b69c1);\n    RNDr(S, W, 17, 0xefbe4786);\n    RNDr(S, W, 18, 0x0fc19dc6);\n    RNDr(S, W, 19, 0x240ca1cc);\n    RNDr(S, W, 20, 0x2de92c6f);\n    RNDr(S, W, 21, 0x4a7484aa);\n    RNDr(S, W, 22, 0x5cb0a9dc);\n    RNDr(S, W, 23, 0x76f988da);\n    RNDr(S, W, 24, 0x983e5152);\n    RNDr(S, W, 25, 0xa831c66d);\n    RNDr(S, W, 26, 0xb00327c8);\n    RNDr(S, W, 27, 0xbf597fc7);\n    RNDr(S, W, 28, 0xc6e00bf3);\n    RNDr(S, W, 29, 0xd5a79147);\n    RNDr(S, W, 30, 0x06ca6351);\n    RNDr(S, W, 31, 0x14292967);\n    RNDr(S, W, 32, 0x27b70a85);\n    RNDr(S, W, 33, 0x2e1b2138);\n    RNDr(S, W, 34, 0x4d2c6dfc);\n    RNDr(S, W, 35, 0x53380d13);\n    RNDr(S, W, 36, 0x650a7354);\n    RNDr(S, W, 37, 0x766a0abb);\n    RNDr(S, W, 38, 0x81c2c92e);\n    RNDr(S, W, 39, 0x92722c85);\n    RNDr(S, W, 40, 0xa2bfe8a1);\n    RNDr(S, W, 41, 0xa81a664b);\n    RNDr(S, W, 42, 0xc24b8b70);\n    RNDr(S, W, 43, 0xc76c51a3);\n    RNDr(S, W, 44, 0xd192e819);\n    RNDr(S, W, 45, 0xd6990624);\n    RNDr(S, W, 46, 0xf40e3585);\n    RNDr(S, W, 47, 0x106aa070);\n    RNDr(S, W, 48, 0x19a4c116);\n    RNDr(S, W, 49, 0x1e376c08);\n    RNDr(S, W, 50, 0x2748774c);\n    RNDr(S, W, 51, 0x34b0bcb5);\n    RNDr(S, W, 52, 0x391c0cb3);\n    RNDr(S, W, 53, 0x4ed8aa4a);\n    RNDr(S, W, 54, 0x5b9cca4f);\n    RNDr(S, W, 55, 0x682e6ff3);\n    RNDr(S, W, 56, 0x748f82ee);\n    RNDr(S, W, 57, 0x78a5636f);\n    RNDr(S, W, 58, 0x84c87814);\n    RNDr(S, W, 59, 0x8cc70208);\n    RNDr(S, W, 60, 0x90befffa);\n    RNDr(S, W, 61, 0xa4506ceb);\n    RNDr(S, W, 62, 0xbef9a3f7);\n    RNDr(S, W, 63, 0xc67178f2);\n\n    for (i = 0; i < 8; i++)\n    {\n        state[i] += S[i];\n    }\n\n    zeroize((void *)W, sizeof W);\n    zeroize((void *)S, sizeof S);\n    zeroize((void *)&t0, sizeof t0);\n    zeroize((void *)&t1, sizeof t1);\n}\n\nvoid SHA256Update(SHA256CTX *context, const uint8_t *input, size_t length)\n{\n    uint32_t bitlen[2];\n    uint32_t r = (context->count[1] >> 3) & 0x3f;\n\n    bitlen[1] = ((uint32_t)length) << 3;\n    bitlen[0] = (uint32_t)(length >> 29);\n\n    if ((context->count[1] += bitlen[1]) < bitlen[1])\n    {\n        context->count[0]++;\n    }\n\n    context->count[0] += bitlen[0];\n\n    if (length < 64 - r)\n    {\n        memcpy(&context->buf[r], input, length);\n        return;\n    }\n\n    memcpy(&context->buf[r], input, 64 - r);\n    SHA256Transform(context->state, context->buf);\n\n    input += 64 - r;\n    length -= 64 - r;\n\n    while (length >= 64)\n    {\n        SHA256Transform(context->state, input);\n        input += 64;\n        length -= 64;\n    }\n\n    memcpy(context->buf, input, length);\n}\n"
  },
  {
    "path": "src/UChain/coin/math/external/sha256.h",
    "content": "/* libsodium: crypto_hash_sha256.h, v0.4.5 2014/04/16 */\n/**\n * Copyright 2005,2007,2009 Colin Percival. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef UC_SHA256_H\n#define UC_SHA256_H\n\n#include <stdint.h>\n#include <stddef.h>\n\n#define SHA256_STATE_LENGTH 8U\n#define SHA256_COUNT_LENGTH 2U\n#define SHA256_BLOCK_LENGTH 64U\n#define SHA256_DIGEST_LENGTH 32U\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n    typedef struct SHA256CTX\n    {\n        uint32_t state[SHA256_STATE_LENGTH];\n        uint32_t count[SHA256_COUNT_LENGTH];\n        uint8_t buf[SHA256_BLOCK_LENGTH];\n    } SHA256CTX;\n\n    void SHA256_(const uint8_t *input, size_t length,\n                 uint8_t digest[SHA256_DIGEST_LENGTH]);\n\n    void SHA256Final(SHA256CTX *context, uint8_t digest[SHA256_DIGEST_LENGTH]);\n\n    void SHA256Init(SHA256CTX *context);\n\n    void SHA256Pad(SHA256CTX *context);\n\n    void SHA256Transform(uint32_t state[SHA256_STATE_LENGTH],\n                         const uint8_t block[SHA256_BLOCK_LENGTH]);\n\n    void SHA256Update(SHA256CTX *context, const uint8_t *input, size_t length);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "src/UChain/coin/math/external/sha512.c",
    "content": "/* libsodium: hash_sha512.c, v0.4.5 2014/04/16 */\n/**\n * Copyright 2005,2007,2009 Colin Percival, All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#include \"sha512.h\"\n\n#include <string.h>\n#include <stdint.h>\n#include \"zeroize.h\"\n\nstatic uint64_t be64dec(const void *pp)\n{\n    const uint8_t *p = (uint8_t const *)pp;\n\n    return ((uint64_t)(p[7]) + ((uint64_t)(p[6]) << 8) +\n            ((uint64_t)(p[5]) << 16) + ((uint64_t)(p[4]) << 24) +\n            ((uint64_t)(p[3]) << 32) + ((uint64_t)(p[2]) << 40) +\n            ((uint64_t)(p[1]) << 48) + ((uint64_t)(p[0]) << 56));\n}\n\nstatic void be64enc(void *pp, uint64_t x)\n{\n    uint8_t *p = (uint8_t *)pp;\n\n    p[7] = x & 0xff;\n    p[6] = (x >> 8) & 0xff;\n    p[5] = (x >> 16) & 0xff;\n    p[4] = (x >> 24) & 0xff;\n    p[3] = (x >> 32) & 0xff;\n    p[2] = (x >> 40) & 0xff;\n    p[1] = (x >> 48) & 0xff;\n    p[0] = (x >> 56) & 0xff;\n}\n\nstatic void be64enc_vect(unsigned char *dst, const uint64_t *src, size_t len)\n{\n    size_t i;\n    for (i = 0; i < len / 8; i++)\n    {\n        be64enc(dst + i * 8, src[i]);\n    }\n}\n\nstatic void be64dec_vect(uint64_t *dst, const unsigned char *src, size_t len)\n{\n    size_t i;\n    for (i = 0; i < len / 8; i++)\n    {\n        dst[i] = be64dec(src + i * 8);\n    }\n}\n\n#define Ch(x, y, z) ((x & (y ^ z)) ^ z)\n#define Maj(x, y, z) ((x & (y | z)) | (y & z))\n#define SHR(x, n) (x >> n)\n#define ROTR(x, n) ((x >> n) | (x << (64 - n)))\n#define S0(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39))\n#define S1(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41))\n#define s0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7))\n#define s1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6))\n\n#define RND(a, b, c, d, e, f, g, h, k) \\\n    t0 = h + S1(e) + Ch(e, f, g) + k;  \\\n    t1 = S0(a) + Maj(a, b, c);         \\\n    d += t0;                           \\\n    h = t0 + t1;\n\n#define RNDr(S, W, i, k)                  \\\n    RND(S[(80 - i) % 8], S[(81 - i) % 8], \\\n        S[(82 - i) % 8], S[(83 - i) % 8], \\\n        S[(84 - i) % 8], S[(85 - i) % 8], \\\n        S[(86 - i) % 8], S[(87 - i) % 8], \\\n        W[i] + k)\n\nstatic unsigned char PAD[SHA512_BLOCK_LENGTH] =\n    {\n        0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};\n\nvoid SHA512_(const uint8_t *input, size_t length,\n             uint8_t digest[SHA512_DIGEST_LENGTH])\n{\n    SHA512CTX context;\n    SHA512Init(&context);\n    SHA512Update(&context, input, length);\n    SHA512Final(&context, digest);\n}\n\nvoid SHA512Final(SHA512CTX *context, uint8_t digest[SHA512_DIGEST_LENGTH])\n{\n    SHA512Pad(context);\n    be64enc_vect(digest, context->state, SHA512_DIGEST_LENGTH);\n    zeroize((void *)context, sizeof *context);\n}\n\nvoid SHA512Init(SHA512CTX *context)\n{\n    context->count[0] = context->count[1] = 0;\n\n    context->state[0] = 0x6a09e667f3bcc908ULL;\n    context->state[1] = 0xbb67ae8584caa73bULL;\n    context->state[2] = 0x3c6ef372fe94f82bULL;\n    context->state[3] = 0xa54ff53a5f1d36f1ULL;\n    context->state[4] = 0x510e527fade682d1ULL;\n    context->state[5] = 0x9b05688c2b3e6c1fULL;\n    context->state[6] = 0x1f83d9abfb41bd6bULL;\n    context->state[7] = 0x5be0cd19137e2179ULL;\n}\n\nvoid SHA512Pad(SHA512CTX *context)\n{\n    uint8_t len[16];\n    size_t r, plen;\n\n    be64enc_vect(len, context->count, 16);\n\n    r = (context->count[1] >> 3) & 0x7f;\n    plen = (r < 112) ? (112 - r) : (240 - r);\n\n    SHA512Update(context, PAD, plen);\n    SHA512Update(context, len, 16);\n}\n\nvoid SHA512Transform(uint64_t state[SHA512_STATE_LENGTH],\n                     const uint8_t block[SHA512_BLOCK_LENGTH])\n{\n    int i;\n    uint64_t W[80];\n    uint64_t S[8];\n    uint64_t t0, t1;\n\n    be64dec_vect(W, block, SHA512_BLOCK_LENGTH);\n\n    for (i = 16; i < 80; i++)\n    {\n        W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];\n    }\n\n    memcpy(S, state, 64);\n\n    RNDr(S, W, 0, 0x428a2f98d728ae22ULL);\n    RNDr(S, W, 1, 0x7137449123ef65cdULL);\n    RNDr(S, W, 2, 0xb5c0fbcfec4d3b2fULL);\n    RNDr(S, W, 3, 0xe9b5dba58189dbbcULL);\n    RNDr(S, W, 4, 0x3956c25bf348b538ULL);\n    RNDr(S, W, 5, 0x59f111f1b605d019ULL);\n    RNDr(S, W, 6, 0x923f82a4af194f9bULL);\n    RNDr(S, W, 7, 0xab1c5ed5da6d8118ULL);\n    RNDr(S, W, 8, 0xd807aa98a3030242ULL);\n    RNDr(S, W, 9, 0x12835b0145706fbeULL);\n    RNDr(S, W, 10, 0x243185be4ee4b28cULL);\n    RNDr(S, W, 11, 0x550c7dc3d5ffb4e2ULL);\n    RNDr(S, W, 12, 0x72be5d74f27b896fULL);\n    RNDr(S, W, 13, 0x80deb1fe3b1696b1ULL);\n    RNDr(S, W, 14, 0x9bdc06a725c71235ULL);\n    RNDr(S, W, 15, 0xc19bf174cf692694ULL);\n    RNDr(S, W, 16, 0xe49b69c19ef14ad2ULL);\n    RNDr(S, W, 17, 0xefbe4786384f25e3ULL);\n    RNDr(S, W, 18, 0x0fc19dc68b8cd5b5ULL);\n    RNDr(S, W, 19, 0x240ca1cc77ac9c65ULL);\n    RNDr(S, W, 20, 0x2de92c6f592b0275ULL);\n    RNDr(S, W, 21, 0x4a7484aa6ea6e483ULL);\n    RNDr(S, W, 22, 0x5cb0a9dcbd41fbd4ULL);\n    RNDr(S, W, 23, 0x76f988da831153b5ULL);\n    RNDr(S, W, 24, 0x983e5152ee66dfabULL);\n    RNDr(S, W, 25, 0xa831c66d2db43210ULL);\n    RNDr(S, W, 26, 0xb00327c898fb213fULL);\n    RNDr(S, W, 27, 0xbf597fc7beef0ee4ULL);\n    RNDr(S, W, 28, 0xc6e00bf33da88fc2ULL);\n    RNDr(S, W, 29, 0xd5a79147930aa725ULL);\n    RNDr(S, W, 30, 0x06ca6351e003826fULL);\n    RNDr(S, W, 31, 0x142929670a0e6e70ULL);\n    RNDr(S, W, 32, 0x27b70a8546d22ffcULL);\n    RNDr(S, W, 33, 0x2e1b21385c26c926ULL);\n    RNDr(S, W, 34, 0x4d2c6dfc5ac42aedULL);\n    RNDr(S, W, 35, 0x53380d139d95b3dfULL);\n    RNDr(S, W, 36, 0x650a73548baf63deULL);\n    RNDr(S, W, 37, 0x766a0abb3c77b2a8ULL);\n    RNDr(S, W, 38, 0x81c2c92e47edaee6ULL);\n    RNDr(S, W, 39, 0x92722c851482353bULL);\n    RNDr(S, W, 40, 0xa2bfe8a14cf10364ULL);\n    RNDr(S, W, 41, 0xa81a664bbc423001ULL);\n    RNDr(S, W, 42, 0xc24b8b70d0f89791ULL);\n    RNDr(S, W, 43, 0xc76c51a30654be30ULL);\n    RNDr(S, W, 44, 0xd192e819d6ef5218ULL);\n    RNDr(S, W, 45, 0xd69906245565a910ULL);\n    RNDr(S, W, 46, 0xf40e35855771202aULL);\n    RNDr(S, W, 47, 0x106aa07032bbd1b8ULL);\n    RNDr(S, W, 48, 0x19a4c116b8d2d0c8ULL);\n    RNDr(S, W, 49, 0x1e376c085141ab53ULL);\n    RNDr(S, W, 50, 0x2748774cdf8eeb99ULL);\n    RNDr(S, W, 51, 0x34b0bcb5e19b48a8ULL);\n    RNDr(S, W, 52, 0x391c0cb3c5c95a63ULL);\n    RNDr(S, W, 53, 0x4ed8aa4ae3418acbULL);\n    RNDr(S, W, 54, 0x5b9cca4f7763e373ULL);\n    RNDr(S, W, 55, 0x682e6ff3d6b2b8a3ULL);\n    RNDr(S, W, 56, 0x748f82ee5defb2fcULL);\n    RNDr(S, W, 57, 0x78a5636f43172f60ULL);\n    RNDr(S, W, 58, 0x84c87814a1f0ab72ULL);\n    RNDr(S, W, 59, 0x8cc702081a6439ecULL);\n    RNDr(S, W, 60, 0x90befffa23631e28ULL);\n    RNDr(S, W, 61, 0xa4506cebde82bde9ULL);\n    RNDr(S, W, 62, 0xbef9a3f7b2c67915ULL);\n    RNDr(S, W, 63, 0xc67178f2e372532bULL);\n    RNDr(S, W, 64, 0xca273eceea26619cULL);\n    RNDr(S, W, 65, 0xd186b8c721c0c207ULL);\n    RNDr(S, W, 66, 0xeada7dd6cde0eb1eULL);\n    RNDr(S, W, 67, 0xf57d4f7fee6ed178ULL);\n    RNDr(S, W, 68, 0x06f067aa72176fbaULL);\n    RNDr(S, W, 69, 0x0a637dc5a2c898a6ULL);\n    RNDr(S, W, 70, 0x113f9804bef90daeULL);\n    RNDr(S, W, 71, 0x1b710b35131c471bULL);\n    RNDr(S, W, 72, 0x28db77f523047d84ULL);\n    RNDr(S, W, 73, 0x32caab7b40c72493ULL);\n    RNDr(S, W, 74, 0x3c9ebe0a15c9bebcULL);\n    RNDr(S, W, 75, 0x431d67c49c100d4cULL);\n    RNDr(S, W, 76, 0x4cc5d4becb3e42b6ULL);\n    RNDr(S, W, 77, 0x597f299cfc657e2aULL);\n    RNDr(S, W, 78, 0x5fcb6fab3ad6faecULL);\n    RNDr(S, W, 79, 0x6c44198c4a475817ULL);\n\n    for (i = 0; i < 8; i++)\n    {\n        state[i] += S[i];\n    }\n\n    zeroize((void *)W, sizeof W);\n    zeroize((void *)S, sizeof S);\n    zeroize((void *)&t0, sizeof t0);\n    zeroize((void *)&t1, sizeof t1);\n}\n\nvoid SHA512Update(SHA512CTX *context, const uint8_t *input, size_t length)\n{\n    uint64_t bitlen[2];\n    size_t r = (context->count[1] >> 3) & 0x7f;\n\n    bitlen[1] = ((uint64_t)length) << 3;\n    bitlen[0] = ((uint64_t)length) >> 61;\n\n    if ((context->count[1] += bitlen[1]) < bitlen[1])\n    {\n        context->count[0]++;\n    }\n\n    context->count[0] += bitlen[0];\n\n    if (length < 128 - r)\n    {\n        memcpy(&context->buf[r], input, length);\n        return;\n    }\n\n    memcpy(&context->buf[r], input, 128 - r);\n    SHA512Transform(context->state, context->buf);\n\n    input += 128 - r;\n    length -= 128 - r;\n\n    while (length >= 128)\n    {\n        SHA512Transform(context->state, input);\n        input += 128;\n        length -= 128;\n    }\n\n    memcpy(context->buf, input, length);\n}\n"
  },
  {
    "path": "src/UChain/coin/math/external/sha512.h",
    "content": "/* libsodium: crypto_hash_sha512.h, v0.4.5 2014/04/16 */\n/**\n * Copyright 2005,2007,2009 Colin Percival. All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#ifndef UC_SHA512_H\n#define UC_SHA512_H\n\n#include <stdint.h>\n#include <stddef.h>\n\n#define SHA512_STATE_LENGTH 8U\n#define SHA512_COUNT_LENGTH 2U\n#define SHA512_BLOCK_LENGTH 128U\n#define SHA512_DIGEST_LENGTH 64U\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n    typedef struct SHA512CTX\n    {\n        uint64_t state[SHA512_STATE_LENGTH];\n        uint64_t count[SHA512_COUNT_LENGTH];\n        uint8_t buf[SHA512_BLOCK_LENGTH];\n    } SHA512CTX;\n\n    void SHA512_(const uint8_t *input, size_t length,\n                 uint8_t digest[SHA512_DIGEST_LENGTH]);\n\n    void SHA512Final(SHA512CTX *context, uint8_t digest[SHA512_DIGEST_LENGTH]);\n\n    void SHA512Init(SHA512CTX *context);\n\n    void SHA512Pad(SHA512CTX *context);\n\n    void SHA512Transform(uint64_t state[SHA512_STATE_LENGTH],\n                         const uint8_t block[SHA512_BLOCK_LENGTH]);\n\n    void SHA512Update(SHA512CTX *context, const uint8_t *input, size_t length);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "src/UChain/coin/math/external/zeroize.c",
    "content": "/* libsodium: utils.c, v0.4.5 2014/04/16 */\n/**\n * Copyright (c) 2013-2014\n * Frank Denis <j at pureftpd dot org>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n#include \"zeroize.h\"\n\n#include <stddef.h>\n#include <stdint.h>\n#include <stdlib.h>\n\n/* TODO: deal with determination of HAVE_SECUREZEROMEMORY and HAVE_MEMSET_S */\n/* These are performance optimizations, not required for security. */\nvoid zeroize(void *const buffer, size_t length)\n{\n#ifdef HAVE_SECUREZEROMEMORY\n    SecureZeroMemory(buffer, length);\n#elif defined(HAVE_MEMSET_S)\n    if (memset_s(buffer, (rsize_t)length, 0, (rsize_t)length) != 0)\n        abort();\n#else\n    size_t i;\n    volatile uint8_t *vbuffer = (volatile uint8_t *)buffer;\n    for (i = 0; i < length; i++)\n        vbuffer[i] = 0;\n#endif\n}\n"
  },
  {
    "path": "src/UChain/coin/math/external/zeroize.h",
    "content": "/* libsodium: utils.c, v0.4.5 2014/04/16 */\n/**\n * Copyright (c) 2013-2014\n * Frank Denis <j at pureftpd dot org>\n *\n * Permission to use, copy, modify, and distribute this software for any\n * purpose with or without fee is hereby granted, provided that the above\n * copyright notice and this permission notice appear in all copies.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n#ifndef UC_ZEROIZE_HPP\n#define UC_ZEROIZE_HPP\n\n#include <stddef.h>\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n    void zeroize(void *const buffer, size_t length);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif\n"
  },
  {
    "path": "src/UChain/coin/math/hash.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/math/hash.hpp>\n\n#include <algorithm>\n#include <cstddef>\n#include <cstdint>\n#include <errno.h>\n#include <new>\n#include <stdexcept>\n#include \"external/crypto_scrypt.h\"\n#include \"external/hmac_sha256.h\"\n#include \"external/hmac_sha512.h\"\n#include \"external/pkcs5_pbkdf2.h\"\n#include \"external/ripemd160.h\"\n#include \"external/sha1.h\"\n#include \"external/sha256.h\"\n#include \"external/sha512.h\"\n\nnamespace libbitcoin\n{\n\nshort_hash ripemd160_hash(data_slice data)\n{\n    short_hash hash;\n    RMD160(data.data(), data.size(), hash.data());\n    return hash;\n}\n\nshort_hash sha1_hash(data_slice data)\n{\n    short_hash hash;\n    SHA1_(data.data(), data.size(), hash.data());\n    return hash;\n}\n\nhash_digest sha256_hash(data_slice data)\n{\n    hash_digest hash;\n    SHA256_(data.data(), data.size(), hash.data());\n    return hash;\n}\n\nhash_digest sha256_hash(data_slice first, data_slice second)\n{\n    hash_digest hash;\n\n    SHA256CTX context;\n    SHA256Init(&context);\n    SHA256Update(&context, first.data(), first.size());\n    SHA256Update(&context, second.data(), second.size());\n    SHA256Final(&context, hash.data());\n\n    return hash;\n}\n\nhash_digest hmac_sha256_hash(data_slice data, data_slice key)\n{\n    hash_digest hash;\n    HMACSHA256(data.data(), data.size(), key.data(), key.size(), hash.data());\n    return hash;\n}\n\nlong_hash sha512_hash(data_slice data)\n{\n    long_hash hash;\n    SHA512_(data.data(), data.size(), hash.data());\n    return hash;\n}\n\nlong_hash hmac_sha512_hash(data_slice data, data_slice key)\n{\n    long_hash hash;\n    HMACSHA512(data.data(), data.size(), key.data(), key.size(), hash.data());\n    return hash;\n}\n\nlong_hash pkcs5_pbkdf2_hmac_sha512(data_slice passphrase,\n                                   data_slice salt, size_t iterations)\n{\n    long_hash hash;\n    const auto result = pkcs5_pbkdf2(passphrase.data(), passphrase.size(),\n                                     salt.data(), salt.size(), hash.data(), hash.size(), iterations);\n\n    if (result != 0)\n        throw std::bad_alloc();\n\n    return hash;\n}\n\nhash_digest bitcoin_hash(data_slice data)\n{\n    return sha256_hash(sha256_hash(data));\n}\n\nshort_hash bitcoin_short_hash(data_slice data)\n{\n    return ripemd160_hash(sha256_hash(data));\n}\n\nstatic void handle_script_result(int result)\n{\n    if (result == 0)\n        return;\n\n    switch (errno)\n    {\n    case EFBIG:\n        throw std::length_error(\"scrypt parameter too large\");\n    case EINVAL:\n        throw std::runtime_error(\"scrypt invalid argument\");\n    case ENOMEM:\n        throw std::length_error(\"scrypt address space\");\n    default:\n        throw std::bad_alloc();\n    }\n}\n\ndata_chunk scrypt(data_slice data, data_slice salt, uint64_t N, uint32_t p,\n                  uint32_t r, size_t length)\n{\n    data_chunk output(length);\n    const auto result = crypto_scrypt(data.data(), data.size(), salt.data(),\n                                      salt.size(), N, r, p, output.data(), output.size());\n    handle_script_result(result);\n    return output;\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/math/hash_number.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/math/hash_number.hpp>\n\nnamespace libbitcoin\n{\n\nhash_number::hash_number()\n{\n}\nhash_number::hash_number(uint64_t value)\n    : hash_(value)\n{\n}\nbool hash_number::set_compact(uint32_t compact)\n{\n    bool is_negative = true, is_overflow = true;\n    hash_.SetCompact(compact, &is_negative, &is_overflow);\n    return !is_negative && !is_overflow;\n}\nuint32_t hash_number::compact() const\n{\n    return hash_.GetCompact();\n}\nvoid hash_number::set_hash(const hash_digest &hash)\n{\n    std::copy(hash.begin(), hash.end(), hash_.begin());\n}\nhash_digest hash_number::hash() const\n{\n    hash_digest result;\n    std::copy(hash_.begin(), hash_.end(), result.begin());\n    return result;\n}\n\nconst hash_number hash_number::operator~() const\n{\n    hash_number result;\n    result.hash_ = ~hash_;\n    return result;\n}\n\nhash_number &hash_number::operator*=(uint32_t value)\n{\n    hash_ *= value;\n    return *this;\n}\nhash_number &hash_number::operator/=(uint32_t value)\n{\n    hash_ /= value;\n    return *this;\n}\nhash_number &hash_number::operator<<=(uint32_t shift)\n{\n    hash_ <<= shift;\n    return *this;\n}\nhash_number &hash_number::operator/=(const hash_number &number_b)\n{\n    hash_ /= number_b.hash_;\n    return *this;\n}\nhash_number &hash_number::operator+=(const hash_number &number_b)\n{\n    hash_ += number_b.hash_;\n    return *this;\n}\n\nbool operator>(const hash_number &number_a, const hash_number &number_b)\n{\n    return number_a.hash_.CompareTo(number_b.hash_) > 0;\n}\nbool operator<=(const hash_number &number_a, const hash_number &number_b)\n{\n    return number_a.hash_.CompareTo(number_b.hash_) <= 0;\n}\nconst hash_number operator<<(const hash_number &number_a, int shift)\n{\n    return hash_number(number_a) <<= shift;\n}\nconst hash_number operator/(\n    const hash_number &number_a, const hash_number &number_b)\n{\n    return hash_number(number_a) /= number_b;\n}\nconst hash_number operator+(\n    const hash_number &number_a, const hash_number &number_b)\n{\n    return hash_number(number_a) += number_b;\n}\nbool operator==(\n    const hash_number &number, uint64_t value)\n{\n    return number.hash_.EqualTo(value);\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/math/script_number.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/math/script_number.hpp>\n\n#include <UChain/coin/constants.hpp>\n#include <UChain/coin/utility/assert.hpp>\n\nnamespace libbitcoin\n{\n\ndata_chunk script_number_serialize(const int64_t value)\n{\n    if (value == 0)\n        return data_chunk();\n\n    data_chunk result;\n    const bool is_negative = value < 0;\n    uint64_t abs_value = is_negative ? -value : value;\n\n    while (abs_value)\n    {\n        result.push_back(abs_value & 0xff);\n        abs_value >>= 8;\n    }\n\n    // - If the most significant byte is >= 0x80 and the value is positive,\n    // push a new zero-byte to make the significant byte < 0x80 again.\n\n    // - If the most significant byte is >= 0x80 and the value is negative,\n    // push a new 0x80 byte that will be popped off when converting to\n    // an integral.\n\n    // - If the most significant byte is < 0x80 and the value is negative,\n    // add 0x80 to it, since it will be subtracted and interpreted as\n    // a negative when converting to an integral.\n\n    if ((result.back() & 0x80) != 0)\n        result.push_back(is_negative ? 0x80 : 0);\n    else if (is_negative)\n        result.back() |= 0x80;\n\n    return result;\n}\n\nint64_t script_number_deserialize(const data_chunk &data)\n{\n    if (data.empty())\n        return 0;\n\n    int64_t result = 0;\n    for (size_t i = 0; i != data.size(); ++i)\n        result |= static_cast<int64_t>(data[i]) << 8 * i;\n\n    // If the input vector's most significant byte is 0x80, remove it from\n    // the result's msb and return a negative.\n    if (data.back() & 0x80)\n        return -(result & ~(0x80 << (8 * (data.size() - 1))));\n\n    return result;\n}\n\nscript_number::script_number(const int64_t value)\n    : value_(value)\n{\n}\nscript_number::script_number()\n{\n    // You must call set_data() after.\n}\n\nbool script_number::set_data(const data_chunk &data, uint8_t max_size)\n{\n    if (data.size() > max_size)\n        return false;\n\n    value_ = script_number_deserialize(data);\n    return true;\n}\ndata_chunk script_number::data() const\n{\n    return script_number_serialize(value_);\n}\n\nint32_t script_number::int32() const\n{\n    if (value_ > max_int32)\n        return max_int32;\n    else if (value_ < min_int32)\n        return min_int32;\n\n    return static_cast<int32_t>(value_);\n}\n\nint64_t script_number::int64() const\n{\n    return value_;\n}\n\nbool script_number::operator==(const int64_t value) const\n{\n    return value_ == value;\n}\nbool script_number::operator!=(const int64_t value) const\n{\n    return value_ != value;\n}\nbool script_number::operator<=(const int64_t value) const\n{\n    return value_ <= value;\n}\nbool script_number::operator<(const int64_t value) const\n{\n    return value_ < value;\n}\nbool script_number::operator>=(const int64_t value) const\n{\n    return value_ >= value;\n}\nbool script_number::operator>(const int64_t value) const\n{\n    return value_ > value;\n}\n\nbool script_number::operator==(const script_number &other) const\n{\n    return operator==(other.value_);\n}\nbool script_number::operator!=(const script_number &other) const\n{\n    return operator!=(other.value_);\n}\nbool script_number::operator<=(const script_number &other) const\n{\n    return operator<=(other.value_);\n}\nbool script_number::operator<(const script_number &other) const\n{\n    return operator<(other.value_);\n}\nbool script_number::operator>=(const script_number &other) const\n{\n    return operator>=(other.value_);\n}\nbool script_number::operator>(const script_number &other) const\n{\n    return operator>(other.value_);\n}\n\nscript_number script_number::operator+(const int64_t value) const\n{\n    return script_number(value_ + value);\n}\n\nscript_number script_number::operator-(const int64_t value) const\n{\n    return script_number(value_ - value);\n}\n\nscript_number script_number::operator+(const script_number &other) const\n{\n    return operator+(other.value_);\n}\n\nscript_number script_number::operator-(const script_number &other) const\n{\n    return operator-(other.value_);\n}\n\nscript_number script_number::operator-() const\n{\n    BITCOIN_ASSERT(value_ != std::numeric_limits<int64_t>::min());\n    return script_number(-value_);\n}\n\nscript_number &script_number::operator+=(const int64_t value)\n{\n    BITCOIN_ASSERT(value == 0 ||\n                   (value > 0 && value_ <= max_int64 - value) ||\n                   (value < 0 && value_ >= min_int64 - value));\n    value_ += value;\n    return *this;\n}\nscript_number &script_number::operator-=(const int64_t value)\n{\n    BITCOIN_ASSERT(value == 0 ||\n                   (value > 0 && value_ >= min_int64 + value) ||\n                   (value < 0 && value_ <= max_int64 + value));\n    value_ -= value;\n    return *this;\n}\nscript_number &script_number::operator+=(const script_number &other)\n{\n    return operator+=(other.value_);\n}\nscript_number &script_number::operator-=(const script_number &other)\n{\n    return operator-=(other.value_);\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/math/secp256k1_initializer.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include \"secp256k1_initializer.hpp\"\n\n#include <mutex>\n#include <secp256k1.h>\n\nnamespace libbitcoin\n{\n\n// We do not share contexts because they may or may not both be required.\nsecp256k1_signing signing;\nsecp256k1_verification verification;\n\n// Static helper for use with std::call_once.\nvoid secp256k1_initializer::set_context(secp256k1_context **context,\n                                        int flags)\n{\n  *context = secp256k1_context_create(flags);\n}\n\n// Protected base class constructor (must be derived).\nsecp256k1_initializer::secp256k1_initializer(int flags)\n    : flags_(flags), context_(nullptr)\n{\n}\n\n// Clean up the context on destruct.\nsecp256k1_initializer::~secp256k1_initializer()\n{\n  if (context_ != nullptr)\n    secp256k1_context_destroy(context_);\n}\n\n// Get the curve context and initialize on first use.\nsecp256k1_context *secp256k1_initializer::context()\n{\n  std::call_once(mutex_, set_context, &context_, flags_);\n  return context_;\n}\n\n// Concrete type for signing init.\nsecp256k1_signing::secp256k1_signing()\n    : secp256k1_initializer(SECP256K1_CONTEXT_SIGN)\n{\n}\n\n// Concrete type for verification init.\nsecp256k1_verification::secp256k1_verification()\n    : secp256k1_initializer(SECP256K1_CONTEXT_VERIFY)\n{\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/math/secp256k1_initializer.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SECP256K1_INITIALIZER_HPP\n#define UC_SECP256K1_INITIALIZER_HPP\n\n#include <mutex>\n#include <secp256k1.h>\n#include <UChain/coin/define.hpp>\n\nnamespace libbitcoin\n{\n\n/**\n * Virtual base class for secp256k1 context management.\n * This class holds no static state but will only initialize its state once for\n * the given mutex. This can be assigned to a static or otherwise. It lazily\n * inits the context once and destroys the context on destruct as necessary.\n */\nclass BC_API secp256k1_initializer\n{\n  private:\n    static void set_context(secp256k1_context **context, int flags);\n\n  protected:\n    int flags_;\n\n    /**\n     * Construct a signing context initializer of the specified context.\n     * @param[in]  flags  { SECP256K1_CONTEXT_SIGN, SECP256K1_CONTEXT_VERIFY }\n     */\n    secp256k1_initializer(int flags);\n\n  public:\n    /**\n     * Free the context if initialized.\n     */\n    ~secp256k1_initializer();\n\n    /**\n     * Call to obtain the secp256k1 context, initialized on first call.\n     */\n    secp256k1_context *context();\n\n  private:\n    std::once_flag mutex_;\n    secp256k1_context *context_;\n};\n\n/**\n * Create and hold this class to initialize signing context on first use.\n */\nclass BC_API secp256k1_signing\n    : public secp256k1_initializer\n{\n  public:\n    /**\n     * Construct a signing context initializer.\n     */\n    secp256k1_signing();\n};\n\n/**\n * Create and hold this class to initialize verification context on first use.\n */\nclass BC_API secp256k1_verification\n    : public secp256k1_initializer\n{\n  public:\n    /**\n     * Construct a verification context initializer.\n     */\n    secp256k1_verification();\n};\n\n/**\n * Use bc::signing.context() to obtain the secp256k1 signing context.\n */\nextern secp256k1_signing signing;\n\n/**\n * Use bc::verification.context() to obtain the secp256k1 verification context.\n */\nextern secp256k1_verification verification;\n\n} // namespace libbitcoin\n\n#endif"
  },
  {
    "path": "src/UChain/coin/math/stealth.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/math/stealth.hpp>\n\n#include <algorithm>\n#include <UChain/coin/chain/script/operation.hpp>\n#include <UChain/coin/chain/script/script.hpp>\n#include <UChain/coin/constants.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/utility/binary.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/endian.hpp>\n\nnamespace libbitcoin\n{\n\nusing namespace chain;\n\nbool is_stealth_script(const script &script)\n{\n    if (script.pattern() != chain::script_pattern::null_data)\n        return false;\n\n    BITCOIN_ASSERT(script.operations.size() == 2);\n    const auto &data = script.operations[1].data;\n    return (data.size() >= hash_size);\n}\n\nbool to_stealth_prefix(uint32_t &out_prefix, const script &script)\n{\n    if (!is_stealth_script(script))\n        return false;\n\n    // A stealth prefix is the full 32 bits (prefix to the hash).\n    // A stealth filter is a leftmost substring of the stealth prefix.\n    constexpr size_t size = binary::bits_per_block * sizeof(uint32_t);\n\n    const auto script_hash = bitcoin_hash(script.to_data(false));\n    out_prefix = from_little_endian_unsafe<uint32_t>(script_hash.begin());\n    return true;\n}\n#include <limits>\n// The public key must have a sign value of 0x02 (i.e. must be even y-valued).\nstatic bool create_ephemeral_keys(ec_secret &out_secret,\n                                  ec_compressed &out_point, const data_chunk &seed)\n{\n    static const data_chunk magic(to_chunk(\"Stealth seed\"));\n    auto nonced_seed = build_chunk({to_array(0), seed});\n\n    // Iterate up to 256 times before giving up on finding a valid key pair.\n    // This gives extremely high success probability given even distribution.\n    for (uint8_t nonce = 0; nonce <= std::numeric_limits<unsigned char>::max(); ++nonce)\n    {\n        nonced_seed[0] = nonce;\n        const auto secret = hmac_sha256_hash(nonced_seed, magic);\n\n        ec_compressed point;\n        if (secret_to_public(point, secret) &&\n            point.front() == ephemeral_public_key_sign)\n        {\n            out_point = point;\n            out_secret = secret;\n            return true;\n        }\n    }\n\n    return false;\n}\n\n// No reason to return the public key (except our internal optimization).\nbool create_ephemeral_key(ec_secret &out_secret, const data_chunk &seed)\n{\n    ec_compressed unused;\n    return create_ephemeral_keys(out_secret, unused, seed);\n}\n\n// Mine a filter into the leftmost bytes of sha256(sha256(output-script)).\nbool create_stealth_data(data_chunk &out_stealth_data, ec_secret &out_secret,\n                         const binary &filter, const data_chunk &seed)\n{\n    // Create a valid ephemeral key pair.\n    ec_secret secret;\n    ec_compressed point;\n    if (!create_ephemeral_keys(secret, point, seed))\n        return false;\n\n    // [ephemeral-public-key-hash:32][pad:0-44][nonce:4]\n    static const size_t max_pad_size = operation::max_null_data_size -\n                                       hash_size - sizeof(uint32_t);\n\n    // Derive our initial nonce data from the provided seed.\n    const auto bytes = sha512_hash(seed);\n\n    // Create a pad size of 0-44 using the last of bytes (avoiding pad/nonce).\n    const auto pad_size = bytes.back() % max_pad_size;\n\n    // Allocate data of target size (36-80 bytes)\n    data_chunk data(hash_size + pad_size + sizeof(uint32_t));\n\n    // Copy the unsigned portion of the ephemeral public key into data.\n    std::copy(point.begin() + 1, point.end(), data.begin());\n\n    // Copy arbitrary pad bytes into data.\n    const auto pad_begin = data.begin() + hash_size;\n    std::copy(bytes.begin(), bytes.begin() + pad_size, pad_begin);\n\n    // Create an initial 32 bit nonce value from last byte (avoiding pad).\n    const auto start = from_little_endian_unsafe<uint32_t>(bytes.begin() +\n                                                           max_pad_size);\n\n    // Mine a prefix into the double sha256 hash of the stealth script.\n    // This will iterate up to 2^32 times before giving up.\n    for (uint32_t nonce = start + 1; nonce != start; ++nonce)\n    {\n        // Create the stealth script with the current data.\n        const auto ops = operation::to_null_data_pattern(data);\n        const auto stealth_script = script{ops};\n\n        // Test for match of filter to stealth script hash prefix.\n        uint32_t field;\n        if (to_stealth_prefix(field, stealth_script) &&\n            filter.is_prefix_of(field))\n        {\n            out_stealth_data = data;\n            out_secret = secret;\n            return true;\n        }\n    }\n\n    return false;\n}\n\nbool extract_ephemeral_key(ec_compressed &out_ephemeral_public_key,\n                           const script &script)\n{\n    if (!is_stealth_script(script))\n        return false;\n\n    // The sign of the ephemeral public key is fixed by convention.\n    // This requires the spender to generate a compliant (y-even) key.\n    // That requires iteration with probability of 1 in 2 chance of success.\n    out_ephemeral_public_key[0] = ephemeral_public_key_sign;\n\n    const auto &data = script.operations[1].data;\n    std::copy(data.begin(), data.begin() + hash_size,\n              out_ephemeral_public_key.begin() + 1);\n\n    return true;\n}\n\nbool extract_ephemeral_key(hash_digest &out_unsigned_ephemeral_key,\n                           const script &script)\n{\n    if (!is_stealth_script(script))\n        return false;\n\n    const auto &data = script.operations[1].data;\n    std::copy(data.begin(), data.begin() + hash_size,\n              out_unsigned_ephemeral_key.begin());\n\n    return true;\n}\n\nbool shared_secret(ec_secret &out_shared, const ec_secret &secret,\n                   const ec_compressed &point)\n{\n    auto copy = point;\n    if (!ec_multiply(copy, secret))\n        return false;\n\n    out_shared = sha256_hash(copy);\n    return true;\n}\n\nbool uncover_stealth(ec_compressed &out_stealth,\n                     const ec_compressed &ephemeral_or_scan, const ec_secret &scan_or_ophemeral,\n                     const ec_compressed &spend)\n{\n    ec_secret shared;\n    if (!shared_secret(shared, scan_or_ophemeral, ephemeral_or_scan))\n        return false;\n\n    auto copy = spend;\n    if (!ec_add(copy, shared))\n        return false;\n\n    out_stealth = copy;\n    return true;\n}\n\nbool uncover_stealth(ec_secret &out_stealth,\n                     const ec_compressed &ephemeral_or_scan, const ec_secret &scan_or_ephemeral,\n                     const ec_secret &spend)\n{\n    ec_secret shared;\n    if (!shared_secret(shared, scan_or_ephemeral, ephemeral_or_scan))\n        return false;\n\n    auto copy = spend;\n    if (!ec_add(copy, shared))\n        return false;\n\n    out_stealth = copy;\n    return true;\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/math/uint256.cpp",
    "content": "// Copyright (c) 2009-2010 Satoshi Nakamoto\n// Copyright (c) 2009-2014 The Bitcoin developers\n// Distributed under the MIT/X11 software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#include <UChain/coin/math/uint256.hpp>\n\n#include <stdio.h>\n#include <string.h>\n#include <UChain/coin/utility/assert.hpp>\n\nnamespace libbitcoin\n{\n\ntemplate <unsigned int BITS>\nbase_uint<BITS>::base_uint(const std::vector<unsigned char> &vch)\n{\n    if (vch.size() != sizeof(pn))\n        throw uint_error(\"Converting vector of wrong size to base_uint\");\n\n    memcpy(pn, &vch[0], sizeof(pn));\n}\n\ntemplate <unsigned int BITS>\nbase_uint<BITS> &base_uint<BITS>::operator<<=(unsigned int shift)\n{\n    base_uint<BITS> a(*this);\n    for (int i = 0; i < WIDTH; i++)\n        pn[i] = 0;\n\n    int k = shift / 32;\n    shift = shift % 32;\n    for (int i = 0; i < WIDTH; i++)\n    {\n        if (i + k + 1 < WIDTH && shift != 0)\n            pn[i + k + 1] |= (a.pn[i] >> (32 - shift));\n\n        if (i + k < WIDTH)\n            pn[i + k] |= (a.pn[i] << shift);\n    }\n\n    return *this;\n}\n\ntemplate <unsigned int BITS>\nbase_uint<BITS> &base_uint<BITS>::operator>>=(unsigned int shift)\n{\n    base_uint<BITS> a(*this);\n    for (int i = 0; i < WIDTH; i++)\n        pn[i] = 0;\n\n    int k = shift / 32;\n    shift = shift % 32;\n    for (int i = 0; i < WIDTH; i++)\n    {\n        if (i - k - 1 >= 0 && shift != 0)\n            pn[i - k - 1] |= (a.pn[i] << (32 - shift));\n\n        if (i - k >= 0)\n            pn[i - k] |= (a.pn[i] >> shift);\n    }\n\n    return *this;\n}\n\ntemplate <unsigned int BITS>\nbase_uint<BITS> &base_uint<BITS>::operator*=(uint32_t b32)\n{\n    uint64_t carry = 0;\n    for (int i = 0; i < WIDTH; i++)\n    {\n        uint64_t n = carry + (uint64_t)b32 * pn[i];\n        pn[i] = n & 0xffffffff;\n        carry = n >> 32;\n    }\n\n    return *this;\n}\n\ntemplate <unsigned int BITS>\nbase_uint<BITS> &base_uint<BITS>::operator*=(const base_uint &b)\n{\n    base_uint<BITS> a = *this;\n    *this = 0;\n    for (int j = 0; j < WIDTH; j++)\n    {\n        uint64_t carry = 0;\n        for (int i = 0; i + j < WIDTH; i++)\n        {\n            uint64_t n = carry + pn[i + j] + (uint64_t)a.pn[j] * b.pn[i];\n            pn[i + j] = n & 0xffffffff;\n            carry = n >> 32;\n        }\n    }\n\n    return *this;\n}\n\ntemplate <unsigned int BITS>\nbase_uint<BITS> &base_uint<BITS>::operator/=(const base_uint &b)\n{\n    // make a copy, so we can shift.\n    base_uint<BITS> div = b;\n\n    // make a copy, so we can subtract.\n    base_uint<BITS> num = *this;\n\n    // the quotient.\n    *this = 0;\n\n    int num_bits = num.bits();\n    int div_bits = div.bits();\n    if (div_bits == 0)\n        throw uint_error(\"Division by zero\");\n\n    // the result is certainly 0.\n    if (div_bits > num_bits)\n        return *this;\n\n    int shift = num_bits - div_bits;\n\n    // shift so that div and nun align.\n    div <<= shift;\n\n    while (shift >= 0)\n    {\n        if (num >= div)\n        {\n            num -= div;\n\n            // set a bit of the result.\n            pn[shift / 32] |= (1 << (shift & 31));\n        }\n\n        // shift back.\n        div >>= 1;\n        shift--;\n    }\n\n    // num now contains the remainder of the division.\n    return *this;\n}\n\ntemplate <unsigned int BITS>\nint base_uint<BITS>::CompareTo(const base_uint<BITS> &b) const\n{\n    for (int i = WIDTH - 1; i >= 0; i--)\n    {\n        if (pn[i] < b.pn[i])\n            return -1;\n\n        if (pn[i] > b.pn[i])\n            return 1;\n    }\n\n    return 0;\n}\n\ntemplate <unsigned int BITS>\nbool base_uint<BITS>::EqualTo(uint64_t b) const\n{\n    for (int i = WIDTH - 1; i >= 2; i--)\n        if (pn[i] != 0)\n            return false;\n\n    if (pn[1] != (b >> 32))\n        return false;\n\n    if (pn[0] != (b & 0xfffffffful))\n        return false;\n\n    return true;\n}\n\ntemplate <unsigned int BITS>\nunsigned int base_uint<BITS>::bits() const\n{\n    for (int pos = WIDTH - 1; pos >= 0; pos--)\n    {\n        if (pn[pos] != 0)\n        {\n            for (int bits = 31; bits > 0; bits--)\n                if ((pn[pos] & 1 << bits) != 0)\n                    return 32 * pos + bits + 1;\n\n            return 32 * pos + 1;\n        }\n    }\n\n    return 0;\n}\n\n// Explicit instantiations for base_uint<256>\ntemplate base_uint<256>::base_uint(const std::vector<unsigned char> &);\ntemplate base_uint<256> &base_uint<256>::operator<<=(unsigned int);\ntemplate base_uint<256> &base_uint<256>::operator>>=(unsigned int);\ntemplate base_uint<256> &base_uint<256>::operator*=(uint32_t b32);\ntemplate base_uint<256> &base_uint<256>::operator*=(const base_uint<256> &b);\ntemplate base_uint<256> &base_uint<256>::operator/=(const base_uint<256> &b);\ntemplate int base_uint<256>::CompareTo(const base_uint<256> &) const;\ntemplate bool base_uint<256>::EqualTo(uint64_t) const;\ntemplate unsigned int base_uint<256>::bits() const;\n\nuint32_t uint256_t::GetCompact(bool fNegative) const\n{\n    int nSize = (bits() + 7) / 8;\n    uint32_t nCompact = 0;\n\n    if (nSize <= 3)\n    {\n        nCompact = (uint32_t)(GetLow64() << 8 * (3 - nSize));\n    }\n    else\n    {\n        uint256_t bn = *this >> 8 * (nSize - 3);\n        nCompact = (uint32_t)(bn.GetLow64());\n    }\n\n    // The 0x00800000 bit denotes the sign. Thus, if it is already set,\n    // divide the mantissa by 256 and increase the exponent.\n    if (nCompact & 0x00800000)\n    {\n        nCompact >>= 8;\n        nSize++;\n    }\n\n    BITCOIN_ASSERT((nCompact & ~0x007fffff) == 0);\n    BITCOIN_ASSERT(nSize < 256);\n    nCompact |= nSize << 24;\n    nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0);\n    return nCompact;\n}\n\n// This implementation directly uses shifts instead of going\n// through an intermediate MPI representation.\nuint256_t &uint256_t::SetCompact(uint32_t nCompact, bool *pfNegative,\n                                 bool *pfOverflow)\n{\n    int nSize = nCompact >> 24;\n    uint32_t nWord = nCompact & 0x007fffff;\n\n    if (nSize <= 3)\n    {\n        nWord >>= 8 * (3 - nSize);\n        *this = nWord;\n    }\n    else\n    {\n        *this = nWord;\n        *this <<= 8 * (nSize - 3);\n    }\n\n    if (pfNegative != nullptr)\n        *pfNegative = nWord != 0 && (nCompact & 0x00800000) != 0;\n\n    if (pfOverflow != nullptr)\n        *pfOverflow = nWord != 0 && ((nSize > 34) ||\n                                     (nWord > 0xff && nSize > 33) ||\n                                     (nWord > 0xffff && nSize > 32));\n\n    return *this;\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/address.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/address.hpp>\n\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string address::command = \"addr\";\nconst uint32_t address::version_minimum = version::level::minimum;\nconst uint32_t address::version_maximum = version::level::maximum;\n\naddress address::factory_from_data(uint32_t version, const data_chunk &data)\n{\n    address instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\naddress address::factory_from_data(uint32_t version, std::istream &stream)\n{\n    address instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\naddress address::factory_from_data(uint32_t version, reader &source)\n{\n    address instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nbool address::is_valid() const\n{\n    return !addresses.empty();\n}\n\nvoid address::reset()\n{\n    addresses.clear();\n    addresses.shrink_to_fit();\n}\n\nbool address::from_data(uint32_t version, const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(version, istream);\n}\n\nbool address::from_data(uint32_t version, std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(version, source);\n}\n\nbool address::from_data(uint32_t version, reader &source)\n{\n    reset();\n\n    uint64_t count = source.read_variable_uint_little_endian();\n    auto result = static_cast<bool>(source);\n\n    if (result)\n    {\n        addresses.resize(count);\n\n        for (auto &address : addresses)\n        {\n            result = address.from_data(version, source, true);\n\n            if (!result)\n                break;\n        }\n    }\n\n    if (!result)\n        reset();\n\n    return result;\n}\n\ndata_chunk address::to_data(uint32_t version) const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(version, ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version));\n    return data;\n}\n\nvoid address::to_data(uint32_t version, std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(version, sink);\n}\n\nvoid address::to_data(uint32_t version, writer &sink) const\n{\n    sink.write_variable_uint_little_endian(addresses.size());\n    for (const network_address &net_address : addresses)\n        net_address.to_data(version, sink, true);\n}\n\nuint64_t address::serialized_size(uint32_t version) const\n{\n    return variable_uint_size(addresses.size()) +\n           (addresses.size() * network_address::satoshi_fixed_size(version, true));\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/alert.cpp",
    "content": "/*\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/alert.hpp>\n\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string alert::command = \"alert\";\nconst uint32_t alert::version_minimum = version::level::minimum;\nconst uint32_t alert::version_maximum = version::level::maximum;\n\nalert alert::factory_from_data(uint32_t version, const data_chunk &data)\n{\n    alert instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\nalert alert::factory_from_data(uint32_t version, std::istream &stream)\n{\n    alert instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\nalert alert::factory_from_data(uint32_t version, reader &source)\n{\n    alert instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nbool alert::is_valid() const\n{\n    return !payload.empty() || !signature.empty();\n}\n\nvoid alert::reset()\n{\n    payload.clear();\n    payload.shrink_to_fit();\n    signature.clear();\n    signature.shrink_to_fit();\n}\n\nbool alert::from_data(uint32_t version, const data_chunk &data)\n{\n    boost::iostreams::stream<byte_source<data_chunk>> istream(data);\n    return from_data(version, istream);\n}\n\nbool alert::from_data(uint32_t version, std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(version, source);\n}\n\nbool alert::from_data(uint32_t version, reader &source)\n{\n    reset();\n\n    auto size = source.read_variable_uint_little_endian();\n    BITCOIN_ASSERT(size <= bc::max_size_t);\n    const auto payload_size = static_cast<size_t>(size);\n    size_t signature_size = 0;\n    auto result = static_cast<bool>(source);\n\n    if (result)\n    {\n        payload = source.read_data(payload_size);\n        result = source && (payload.size() == payload_size);\n    }\n\n    if (result)\n    {\n        size = source.read_variable_uint_little_endian();\n        BITCOIN_ASSERT(size <= bc::max_size_t);\n        signature_size = static_cast<size_t>(size);\n        result = source;\n    }\n\n    if (result)\n    {\n        signature = source.read_data(signature_size);\n        result = source && (signature.size() == signature_size);\n    }\n\n    if (!result)\n        reset();\n\n    return result;\n}\n\ndata_chunk alert::to_data(uint32_t version) const\n{\n    data_chunk data;\n    boost::iostreams::stream<byte_sink<data_chunk>> ostream(data);\n    to_data(version, ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version));\n    return data;\n}\n\nvoid alert::to_data(uint32_t version, std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(version, sink);\n}\n\nvoid alert::to_data(uint32_t version, writer &sink) const\n{\n    sink.write_variable_uint_little_endian(payload.size());\n    sink.write_data(payload);\n    sink.write_variable_uint_little_endian(signature.size());\n    sink.write_data(signature);\n}\n\nuint64_t alert::serialized_size(uint32_t version) const\n{\n    return variable_uint_size(payload.size()) + payload.size() +\n           variable_uint_size(signature.size()) + signature.size();\n}\n\nbool operator==(const alert &left, const alert &right)\n{\n    bool result = (left.payload.size() == right.payload.size()) &&\n                  (left.signature.size() == right.signature.size());\n\n    for (size_t i = 0; i < left.payload.size() && result; i++)\n        result = (left.payload[i] == right.payload[i]);\n\n    for (size_t i = 0; i < left.signature.size() && result; i++)\n        result = (left.signature[i] == right.signature[i]);\n\n    return result;\n}\n\nbool operator!=(const alert &left, const alert &right)\n{\n    return !(left == right);\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/alert_payload.cpp",
    "content": "/*\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/alert_payload.hpp>\n\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\n// Libbitcon doesn't use this.\nconst ec_uncompressed alert_payload::satoshi_public_key{\n    {0x04, 0xfc, 0x97, 0x02, 0x84, 0x78, 0x40, 0xaa, 0xf1, 0x95, 0xde,\n     0x84, 0x42, 0xeb, 0xec, 0xed, 0xf5, 0xb0, 0x95, 0xcd, 0xbb, 0x9b,\n     0xc7, 0x16, 0xbd, 0xa9, 0x11, 0x09, 0x71, 0xb2, 0x8a, 0x49, 0xe0,\n     0xea, 0xd8, 0x56, 0x4f, 0xf0, 0xdb, 0x22, 0x20, 0x9e, 0x03, 0x74,\n     0x78, 0x2c, 0x09, 0x3b, 0xb8, 0x99, 0x69, 0x2d, 0x52, 0x4e, 0x9d,\n     0x6a, 0x69, 0x56, 0xe7, 0xc5, 0xec, 0xbc, 0xd6, 0x82, 0x84}};\n\nalert_payload alert_payload::factory_from_data(uint32_t version,\n                                               const data_chunk &data)\n{\n    alert_payload instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\nalert_payload alert_payload::factory_from_data(uint32_t version,\n                                               std::istream &stream)\n{\n    alert_payload instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\nalert_payload alert_payload::factory_from_data(uint32_t version,\n                                               reader &source)\n{\n    alert_payload instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nbool alert_payload::is_valid() const\n{\n    return (version != 0) || (relay_until != 0) || (expiration != 0) || (id != 0) || (cancel != 0) || !set_cancel.empty() || (min_version != 0) || (max_version != 0) || !set_sub_version.empty() || (priority != 0) || !comment.empty() || !status_bar.empty() || !reserved.empty();\n}\n\nvoid alert_payload::reset()\n{\n    version = 0;\n    relay_until = 0;\n    expiration = 0;\n    id = 0;\n    cancel = 0;\n    set_cancel.clear();\n    set_cancel.shrink_to_fit();\n    min_version = 0;\n    max_version = 0;\n    set_sub_version.clear();\n    set_sub_version.shrink_to_fit();\n    priority = 0;\n    comment.clear();\n    comment.shrink_to_fit();\n    status_bar.clear();\n    status_bar.shrink_to_fit();\n    reserved.clear();\n    reserved.shrink_to_fit();\n}\n\nbool alert_payload::from_data(uint32_t version, const data_chunk &data)\n{\n    boost::iostreams::stream<byte_source<data_chunk>> istream(data);\n    return from_data(version, istream);\n}\n\nbool alert_payload::from_data(uint32_t version, std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(version, source);\n}\n\nbool alert_payload::from_data(uint32_t version, reader &source)\n{\n    reset();\n\n    this->version = source.read_4_bytes_little_endian();\n    relay_until = source.read_8_bytes_little_endian();\n    expiration = source.read_8_bytes_little_endian();\n    id = source.read_4_bytes_little_endian();\n    cancel = source.read_4_bytes_little_endian();\n    const auto cancel_size = source.read_variable_uint_little_endian();\n    set_cancel.reserve(cancel_size);\n\n    for (uint64_t i = 0; i < cancel_size && source; i++)\n        set_cancel.push_back(source.read_4_bytes_little_endian());\n\n    min_version = source.read_4_bytes_little_endian();\n    max_version = source.read_4_bytes_little_endian();\n    const auto sub_version_size = source.read_variable_uint_little_endian();\n    set_sub_version.reserve(sub_version_size);\n\n    for (uint64_t i = 0; i < sub_version_size && source; i++)\n        set_sub_version.push_back(source.read_string());\n\n    priority = source.read_4_bytes_little_endian();\n    comment = source.read_string();\n    status_bar = source.read_string();\n    reserved = source.read_string();\n\n    if (!source)\n        reset();\n\n    return source;\n}\n\ndata_chunk alert_payload::to_data(uint32_t version) const\n{\n    data_chunk data;\n    boost::iostreams::stream<byte_sink<data_chunk>> ostream(data);\n    to_data(version, ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version));\n    return data;\n}\n\nvoid alert_payload::to_data(uint32_t version, std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(version, sink);\n}\n\nvoid alert_payload::to_data(uint32_t version, writer &sink) const\n{\n    sink.write_4_bytes_little_endian(this->version);\n    sink.write_8_bytes_little_endian(relay_until);\n    sink.write_8_bytes_little_endian(expiration);\n    sink.write_4_bytes_little_endian(id);\n    sink.write_4_bytes_little_endian(cancel);\n    sink.write_variable_uint_little_endian(set_cancel.size());\n\n    for (const auto &entry : set_cancel)\n        sink.write_4_bytes_little_endian(entry);\n\n    sink.write_4_bytes_little_endian(min_version);\n    sink.write_4_bytes_little_endian(max_version);\n    sink.write_variable_uint_little_endian(set_sub_version.size());\n\n    for (const auto &entry : set_sub_version)\n        sink.write_string(entry);\n\n    sink.write_4_bytes_little_endian(priority);\n    sink.write_string(comment);\n    sink.write_string(status_bar);\n    sink.write_string(reserved);\n}\n\nuint64_t alert_payload::serialized_size(uint32_t version) const\n{\n    uint64_t size = 40 + variable_uint_size(comment.size()) + comment.size() +\n                    variable_uint_size(status_bar.size()) + status_bar.size() +\n                    variable_uint_size(reserved.size()) + reserved.size() +\n                    variable_uint_size(set_cancel.size()) + (4 * set_cancel.size()) +\n                    variable_uint_size(set_sub_version.size());\n\n    for (const auto &sub_version : set_sub_version)\n        size += variable_uint_size(sub_version.size()) + sub_version.size();\n\n    return size;\n}\n\nbool operator==(const alert_payload &left,\n                const alert_payload &right)\n{\n    bool result = (left.version == right.version) &&\n                  (left.relay_until == right.relay_until) &&\n                  (left.expiration == right.expiration) &&\n                  (left.id == right.id) &&\n                  (left.cancel == right.cancel) &&\n                  (left.set_cancel.size() == right.set_cancel.size()) &&\n                  (left.min_version == right.min_version) &&\n                  (left.max_version == right.max_version) &&\n                  (left.set_sub_version.size() == right.set_sub_version.size()) &&\n                  (left.priority == right.priority) &&\n                  (left.comment == right.comment) &&\n                  (left.status_bar == right.status_bar) &&\n                  (left.reserved == right.reserved);\n\n    for (size_t i = 0; i < left.set_cancel.size() && result; i++)\n        result = (left.set_cancel[i] == right.set_cancel[i]);\n\n    for (size_t i = 0; i < left.set_sub_version.size() && result; i++)\n        result = (left.set_sub_version[i] == right.set_sub_version[i]);\n\n    return result;\n}\n\nbool operator!=(const alert_payload &left, const alert_payload &right)\n{\n    return !(left == right);\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/block_msg.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/block_msg.hpp>\n\n#include <cstdint>\n#include <cstddef>\n#include <istream>\n#include <utility>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/chain/header.hpp>\n#include <UChain/coin/chain/transaction.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/reader.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string block_msg::command = \"block\";\nconst uint32_t block_msg::version_minimum = version::level::minimum;\nconst uint32_t block_msg::version_maximum = version::level::maximum;\n\nblock_msg block_msg::factory_from_data(uint32_t version,\n                                               const data_chunk &data, bool with_transaction_count)\n{\n    block_msg instance;\n    instance.from_data(version, data, with_transaction_count);\n    return instance;\n}\n\nblock_msg block_msg::factory_from_data(uint32_t version,\n                                               std::istream &stream, bool with_transaction_count)\n{\n    block_msg instance;\n    instance.from_data(version, stream, with_transaction_count);\n    return instance;\n}\n\nblock_msg block_msg::factory_from_data(uint32_t version,\n                                               reader &source, bool with_transaction_count)\n{\n    block_msg instance;\n    instance.from_data(version, source, with_transaction_count);\n    return instance;\n}\n\nblock_msg::block_msg()\n    : block(), originator_(0)\n{\n}\n\nblock_msg::block_msg(const block &other)\n    : block(other)\n{\n}\n\nblock_msg::block_msg(const block_msg &other)\n    : block_msg(other.header, other.transactions)\n{\n}\n\nblock_msg::block_msg(const chain::header &header,\n                             const chain::transaction::list &transactions)\n    : block(header, transactions), originator_(0)\n{\n}\n\nblock_msg::block_msg(block &&other)\n    : block(std::forward<block>(other))\n{\n}\n\nblock_msg::block_msg(block_msg &&other)\n    : block_msg(std::forward<chain::header>(other.header),\n                    std::forward<chain::transaction::list>(other.transactions))\n{\n}\n\nblock_msg::block_msg(chain::header &&header,\n                             chain::transaction::list &&transactions)\n    : block(std::forward<chain::header>(header),\n            std::forward<chain::transaction::list>(transactions)),\n      originator_(0)\n{\n}\n\nblock_msg &block_msg::operator=(block_msg &&other)\n{\n    header = std::move(other.header);\n    transactions = std::move(other.transactions);\n    originator_ = other.originator_;\n    return *this;\n}\n\nbool block_msg::from_data(uint32_t version, const data_chunk &data,\n                              bool with_transaction_count)\n{\n    originator_ = version;\n    return block::from_data(data, with_transaction_count);\n}\n\nbool block_msg::from_data(uint32_t version, std::istream &stream,\n                              bool with_transaction_count)\n{\n    originator_ = version;\n    return block::from_data(stream, with_transaction_count);\n}\n\nbool block_msg::from_data(uint32_t version, reader &source,\n                              bool with_transaction_count)\n{\n    originator_ = version;\n    return block::from_data(source, with_transaction_count);\n}\n\ndata_chunk block_msg::to_data(uint32_t version,\n                                  bool with_transaction_count) const\n{\n    return block::to_data(with_transaction_count);\n}\n\nvoid block_msg::to_data(uint32_t version, std::ostream &stream,\n                            bool with_transaction_count) const\n{\n    block::to_data(stream, with_transaction_count);\n}\n\nvoid block_msg::to_data(uint32_t version, writer &sink,\n                            bool with_transaction_count) const\n{\n    block::to_data(sink, with_transaction_count);\n}\n\nuint64_t block_msg::serialized_size(uint32_t version,\n                                        bool with_transaction_count) const\n{\n    return block::serialized_size(with_transaction_count);\n}\n\nuint64_t block_msg::originator() const\n{\n    return originator_;\n}\n\nvoid block_msg::set_originator(uint64_t value)\n{\n    originator_ = value;\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/block_txs.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/block_txs.hpp>\n\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string block_txs::command = \"blocktxn\";\nconst uint32_t block_txs::version_minimum = version::level::bip152;\nconst uint32_t block_txs::version_maximum = version::level::bip152;\n\nblock_txs block_txs::factory_from_data(\n    const uint32_t version, const data_chunk &data)\n{\n    block_txs instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\nblock_txs block_txs::factory_from_data(\n    const uint32_t version, std::istream &stream)\n{\n    block_txs instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\nblock_txs block_txs::factory_from_data(\n    const uint32_t version, reader &source)\n{\n    block_txs instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nbool block_txs::is_valid() const\n{\n    return (block_hash != null_hash);\n}\n\nvoid block_txs::reset()\n{\n    block_hash = null_hash;\n    transactions.clear();\n    transactions.shrink_to_fit();\n}\n\nbool block_txs::from_data(uint32_t version,\n                                   const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(version, istream);\n}\n\nbool block_txs::from_data(uint32_t version,\n                                   std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(version, source);\n}\n\nbool block_txs::from_data(uint32_t version, reader &source)\n{\n    reset();\n    auto result = !(version < block_txs::version_minimum);\n    block_hash = source.read_hash();\n    result &= static_cast<bool>(source);\n    const auto count = source.read_variable_uint_little_endian();\n    result &= static_cast<bool>(source);\n\n    if (result)\n    {\n        transactions.resize(count);\n\n        for (auto &transaction : transactions)\n        {\n            result = transaction.from_data(source);\n\n            if (!result)\n                break;\n        }\n    }\n\n    if (!result)\n        reset();\n\n    return result;\n}\n\ndata_chunk block_txs::to_data(uint32_t version) const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(version, ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version));\n    return data;\n}\n\nvoid block_txs::to_data(uint32_t version,\n                                 std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(version, sink);\n}\n\nvoid block_txs::to_data(uint32_t version, writer &sink) const\n{\n    sink.write_hash(block_hash);\n    sink.write_variable_uint_little_endian(transactions.size());\n\n    for (const auto &element : transactions)\n        element.to_data(sink);\n}\n\nuint64_t block_txs::serialized_size(uint32_t version) const\n{\n    uint64_t size = hash_size + variable_uint_size(transactions.size());\n\n    for (const auto &element : transactions)\n        size += element.serialized_size();\n\n    return size;\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/compact_block.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/compact_block.hpp>\n\n#include <initializer_list>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string compact_block::command = \"cmpctblock\";\nconst uint32_t compact_block::version_minimum = version::level::bip152;\nconst uint32_t compact_block::version_maximum = version::level::bip152;\n\ncompact_block compact_block::factory_from_data(uint32_t version,\n                                               const data_chunk &data)\n{\n    compact_block instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\ncompact_block compact_block::factory_from_data(uint32_t version,\n                                               std::istream &stream)\n{\n    compact_block instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\ncompact_block compact_block::factory_from_data(uint32_t version,\n                                               reader &source)\n{\n    compact_block instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nbool compact_block::is_valid() const\n{\n    return header.is_valid() && !short_ids.empty() && !transactions.empty();\n}\n\nvoid compact_block::reset()\n{\n    header.reset();\n    nonce = 0;\n    short_ids.clear();\n    short_ids.shrink_to_fit();\n    transactions.clear();\n    transactions.shrink_to_fit();\n}\n\nbool compact_block::from_data(uint32_t version, const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(version, istream);\n}\n\nbool compact_block::from_data(uint32_t version, std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(version, source);\n}\n\nbool compact_block::from_data(uint32_t version, reader &source)\n{\n    reset();\n\n    auto insufficient_version = (version < compact_block::version_minimum);\n    auto result = header.from_data(source, false);\n    nonce = source.read_8_bytes_little_endian();\n    const auto short_ids_count = source.read_variable_uint_little_endian();\n    result &= static_cast<bool>(source);\n\n    if (result)\n        short_ids.reserve(short_ids_count);\n\n    for (uint64_t i = 0; (i < short_ids_count) && result; ++i)\n    {\n        short_ids.push_back(source.read_mini_hash());\n        result = static_cast<bool>(source);\n    }\n\n    const auto transaction_count = source.read_variable_uint_little_endian();\n    result &= static_cast<bool>(source);\n\n    if (result)\n    {\n        transactions.resize(transaction_count);\n\n        for (auto &transaction : transactions)\n        {\n            result = transaction.from_data(version, source);\n\n            if (!result)\n                break;\n        }\n    }\n\n    if (!result || insufficient_version)\n        reset();\n\n    return result && !insufficient_version;\n}\n\ndata_chunk compact_block::to_data(uint32_t version) const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(version, ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version));\n    return data;\n}\n\nvoid compact_block::to_data(uint32_t version, std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(version, sink);\n}\n\nvoid compact_block::to_data(uint32_t version, writer &sink) const\n{\n    header.to_data(sink, false);\n    sink.write_8_bytes_little_endian(nonce);\n    sink.write_variable_uint_little_endian(short_ids.size());\n    for (const auto &element : short_ids)\n        sink.write_mini_hash(element);\n\n    sink.write_variable_uint_little_endian(transactions.size());\n    for (const auto &element : transactions)\n        element.to_data(version, sink);\n}\n\nuint64_t compact_block::serialized_size(uint32_t version) const\n{\n    uint64_t size = chain::header::satoshi_fixed_size_without_transaction_count() +\n                    variable_uint_size(short_ids.size()) + (short_ids.size() * 6) +\n                    variable_uint_size(transactions.size()) + 8;\n\n    for (const auto &tx : transactions)\n        size += tx.serialized_size(version);\n\n    return size;\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/fee_filter.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/fee_filter.hpp>\n\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string fee_filter::command = \"feefilter\";\nconst uint32_t fee_filter::version_minimum = version::level::bip133;\nconst uint32_t fee_filter::version_maximum = version::level::bip133;\n\nfee_filter fee_filter::factory_from_data(uint32_t version, const data_chunk &data)\n{\n    fee_filter instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\nfee_filter fee_filter::factory_from_data(uint32_t version, std::istream &stream)\n{\n    fee_filter instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\nfee_filter fee_filter::factory_from_data(uint32_t version, reader &source)\n{\n    fee_filter instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nuint64_t fee_filter::satoshi_fixed_size(uint32_t version)\n{\n    return sizeof(minimum_fee);\n}\n\nfee_filter::fee_filter()\n    : minimum_fee(0), valid_(false)\n{\n}\n\nfee_filter::fee_filter(uint64_t minimum)\n    : minimum_fee(minimum), valid_(true)\n{\n}\n\nbool fee_filter::from_data(uint32_t version, const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(version, istream);\n}\n\nbool fee_filter::from_data(uint32_t version, std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(version, source);\n}\n\nbool fee_filter::from_data(uint32_t version, reader &source)\n{\n    reset();\n\n    valid_ = !(version < fee_filter::version_minimum);\n    minimum_fee = source.read_8_bytes_little_endian();\n    valid_ &= static_cast<bool>(source);\n\n    if (!valid_)\n        reset();\n\n    return valid_;\n}\n\ndata_chunk fee_filter::to_data(uint32_t version) const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(version, ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version));\n    return data;\n}\n\nvoid fee_filter::to_data(uint32_t version, std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(version, sink);\n}\n\nvoid fee_filter::to_data(uint32_t version, writer &sink) const\n{\n    sink.write_8_bytes_little_endian(minimum_fee);\n}\n\nbool fee_filter::is_valid() const\n{\n    return valid_;\n}\n\nvoid fee_filter::reset()\n{\n    valid_ = false;\n    minimum_fee = 0;\n}\n\nuint64_t fee_filter::serialized_size(uint32_t version) const\n{\n    return satoshi_fixed_size(version);\n}\n\nbool fee_filter::operator==(const fee_filter &other) const\n{\n    return (minimum_fee == other.minimum_fee);\n}\n\nbool fee_filter::operator!=(const fee_filter &other) const\n{\n    return !(*this == other);\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/filter_add.cpp",
    "content": "/*\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/filter_add.hpp>\n\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string filter_add::command = \"filteradd\";\nconst uint32_t filter_add::version_minimum = version::level::bip37;\nconst uint32_t filter_add::version_maximum = version::level::maximum;\n\nfilter_add filter_add::factory_from_data(uint32_t version,\n                                         const data_chunk &data)\n{\n    filter_add instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\nfilter_add filter_add::factory_from_data(uint32_t version,\n                                         std::istream &stream)\n{\n    filter_add instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\nfilter_add filter_add::factory_from_data(uint32_t version,\n                                         reader &source)\n{\n    filter_add instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nbool filter_add::is_valid() const\n{\n    return !data.empty();\n}\n\nvoid filter_add::reset()\n{\n    data.clear();\n    data.shrink_to_fit();\n}\n\nbool filter_add::from_data(uint32_t version, const data_chunk &data)\n{\n    boost::iostreams::stream<byte_source<data_chunk>> istream(data);\n    return from_data(version, istream);\n}\n\nbool filter_add::from_data(uint32_t version, std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(version, source);\n}\n\nbool filter_add::from_data(uint32_t version, reader &source)\n{\n    reset();\n\n    const auto insufficient_version = (version < filter_add::version_minimum);\n    const auto size = source.read_variable_uint_little_endian();\n    BITCOIN_ASSERT(size <= bc::max_size_t);\n    const auto data_size = static_cast<size_t>(size);\n    bool result = static_cast<bool>(source);\n\n    if (result)\n    {\n        data = source.read_data(data_size);\n        result = source && (data.size() == data_size);\n    }\n\n    if (!result || insufficient_version)\n        reset();\n\n    return result && !insufficient_version;\n}\n\ndata_chunk filter_add::to_data(uint32_t version) const\n{\n    data_chunk data;\n    boost::iostreams::stream<byte_sink<data_chunk>> ostream(data);\n    to_data(version, ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version));\n    return data;\n}\n\nvoid filter_add::to_data(uint32_t version, std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(version, sink);\n}\n\nvoid filter_add::to_data(uint32_t version, writer &sink) const\n{\n    sink.write_variable_uint_little_endian(data.size());\n    sink.write_data(data);\n}\n\nuint64_t filter_add::serialized_size(uint32_t version) const\n{\n    return variable_uint_size(data.size()) + data.size();\n}\n\nbool operator==(const filter_add &left,\n                const filter_add &right)\n{\n    bool result = (left.data.size() == right.data.size());\n\n    for (data_chunk::size_type i = 0; i < left.data.size() && result; i++)\n        result = (left.data[i] == right.data[i]);\n\n    return result;\n}\n\nbool operator!=(const filter_add &left,\n                const filter_add &right)\n{\n    return !(left == right);\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/filter_clear.cpp",
    "content": "/*\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/filter_clear.hpp>\n\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string filter_clear::command = \"filterclear\";\nconst uint32_t filter_clear::version_minimum = version::level::bip37;\nconst uint32_t filter_clear::version_maximum = version::level::maximum;\n\nfilter_clear filter_clear::factory_from_data(uint32_t version,\n                                             const data_chunk &data)\n{\n    filter_clear instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\nfilter_clear filter_clear::factory_from_data(uint32_t version,\n                                             std::istream &stream)\n{\n    filter_clear instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\nfilter_clear filter_clear::factory_from_data(uint32_t version,\n                                             reader &source)\n{\n    filter_clear instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nfilter_clear::filter_clear()\n{\n    reset();\n}\n\nbool filter_clear::is_valid() const\n{\n    return !insufficient_version_;\n}\n\nvoid filter_clear::reset()\n{\n    insufficient_version_ = false;\n}\n\nbool filter_clear::from_data(uint32_t version, const data_chunk &data)\n{\n    boost::iostreams::stream<byte_source<data_chunk>> istream(data);\n    return from_data(version, istream);\n}\n\nbool filter_clear::from_data(uint32_t version, std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(version, source);\n}\n\nbool filter_clear::from_data(uint32_t version, reader &source)\n{\n    reset();\n    insufficient_version_ = (version < filter_clear::version_minimum);\n    return !insufficient_version_;\n}\n\ndata_chunk filter_clear::to_data(uint32_t version) const\n{\n    data_chunk data;\n    boost::iostreams::stream<byte_sink<data_chunk>> ostream(data);\n    to_data(version, ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version));\n    return data;\n}\n\nvoid filter_clear::to_data(uint32_t version, std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(version, sink);\n}\n\nvoid filter_clear::to_data(uint32_t version, writer &sink) const\n{\n}\n\nuint64_t filter_clear::serialized_size(uint32_t version) const\n{\n    return filter_clear::satoshi_fixed_size(version);\n}\n\nuint64_t filter_clear::satoshi_fixed_size(uint32_t version)\n{\n    return 0;\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/filter_load.cpp",
    "content": "/*\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/filter_load.hpp>\n\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string filter_load::command = \"filterload\";\nconst uint32_t filter_load::version_minimum = version::level::bip37;\nconst uint32_t filter_load::version_maximum = version::level::maximum;\n\nfilter_load filter_load::factory_from_data(uint32_t version,\n                                           const data_chunk &data)\n{\n    filter_load instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\nfilter_load filter_load::factory_from_data(uint32_t version,\n                                           std::istream &stream)\n{\n    filter_load instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\nfilter_load filter_load::factory_from_data(uint32_t version,\n                                           reader &source)\n{\n    filter_load instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nbool filter_load::is_valid() const\n{\n    return !filter.empty() || (hash_functions != 0) || (tweak != 0) || (flags != 0x00);\n}\n\nvoid filter_load::reset()\n{\n    filter.clear();\n    filter.shrink_to_fit();\n    hash_functions = 0;\n    tweak = 0;\n    flags = 0x00;\n}\n\nbool filter_load::from_data(uint32_t version, const data_chunk &data)\n{\n    boost::iostreams::stream<byte_source<data_chunk>> istream(data);\n    return from_data(version, istream);\n}\n\nbool filter_load::from_data(uint32_t version, std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(version, source);\n}\n\nbool filter_load::from_data(uint32_t version, reader &source)\n{\n    reset();\n\n    const auto insufficent_version = (version < filter_load::version_minimum);\n    const auto size = source.read_variable_uint_little_endian();\n    BITCOIN_ASSERT(size <= bc::max_size_t);\n    const auto filter_size = static_cast<size_t>(size);\n    bool result = static_cast<bool>(source);\n\n    if (result)\n    {\n        filter = source.read_data(filter_size);\n        hash_functions = source.read_4_bytes_little_endian();\n        tweak = source.read_4_bytes_little_endian();\n        flags = source.read_byte();\n        result = source && (filter.size() == filter_size);\n    }\n\n    if (!result || insufficent_version)\n        reset();\n\n    return result && !insufficent_version;\n}\n\ndata_chunk filter_load::to_data(uint32_t version) const\n{\n    data_chunk data;\n    boost::iostreams::stream<byte_sink<data_chunk>> ostream(data);\n    to_data(version, ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version));\n    return data;\n}\n\nvoid filter_load::to_data(uint32_t version, std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(version, sink);\n}\n\nvoid filter_load::to_data(uint32_t version, writer &sink) const\n{\n    sink.write_variable_uint_little_endian(filter.size());\n    sink.write_data(filter);\n    sink.write_4_bytes_little_endian(hash_functions);\n    sink.write_4_bytes_little_endian(tweak);\n    sink.write_byte(flags);\n}\n\nuint64_t filter_load::serialized_size(uint32_t version) const\n{\n    return 1 + 4 + 4 + variable_uint_size(filter.size()) + filter.size();\n}\n\nbool operator==(const filter_load &left,\n                const filter_load &right)\n{\n    bool result = (left.filter.size() == right.filter.size()) &&\n                  (left.hash_functions == right.hash_functions) &&\n                  (left.tweak == right.tweak) &&\n                  (left.flags == right.flags);\n\n    for (data_chunk::size_type i = 0; i < left.filter.size() && result; i++)\n        result = (left.filter[i] == right.filter[i]);\n\n    return result;\n}\n\nbool operator!=(const filter_load &left,\n                const filter_load &right)\n{\n    return !(left == right);\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/get_address.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/get_address.hpp>\n\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string get_address::command = \"getaddr\";\nconst uint32_t get_address::version_minimum = version::level::minimum;\nconst uint32_t get_address::version_maximum = version::level::maximum;\n\nget_address get_address::factory_from_data(uint32_t version,\n                                           const data_chunk &data)\n{\n    get_address instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\nget_address get_address::factory_from_data(uint32_t version,\n                                           std::istream &stream)\n{\n    get_address instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\nget_address get_address::factory_from_data(uint32_t version,\n                                           reader &source)\n{\n    get_address instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nbool get_address::is_valid() const\n{\n    return true;\n}\n\nvoid get_address::reset()\n{\n}\n\nbool get_address::from_data(uint32_t version, const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(version, istream);\n}\n\nbool get_address::from_data(uint32_t version, std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(version, source);\n}\n\nbool get_address::from_data(uint32_t version, reader &source)\n{\n    reset();\n    return source;\n}\n\ndata_chunk get_address::to_data(uint32_t version) const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(version, ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version));\n    return data;\n}\n\nvoid get_address::to_data(uint32_t version, std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(version, sink);\n}\n\nvoid get_address::to_data(uint32_t version, writer &sink) const\n{\n}\n\nuint64_t get_address::serialized_size(uint32_t version) const\n{\n    return get_address::satoshi_fixed_size(version);\n}\n\nuint64_t get_address::satoshi_fixed_size(uint32_t version)\n{\n    return 0;\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/get_block_txs.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/get_block_txs.hpp>\n\n#include <initializer_list>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string get_block_txs::command = \"getblocktxn\";\nconst uint32_t get_block_txs::version_minimum = version::level::bip152;\nconst uint32_t get_block_txs::version_maximum = version::level::bip152;\n\nget_block_txs get_block_txs::factory_from_data(\n    const uint32_t version, const data_chunk &data)\n{\n    get_block_txs instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\nget_block_txs get_block_txs::factory_from_data(\n    const uint32_t version, std::istream &stream)\n{\n    get_block_txs instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\nget_block_txs get_block_txs::factory_from_data(\n    const uint32_t version, reader &source)\n{\n    get_block_txs instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nbool get_block_txs::is_valid() const\n{\n    return (block_hash != null_hash);\n}\n\nvoid get_block_txs::reset()\n{\n    block_hash = null_hash;\n    indexes.clear();\n    indexes.shrink_to_fit();\n}\n\nbool get_block_txs::from_data(uint32_t version,\n                                       const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(version, istream);\n}\n\nbool get_block_txs::from_data(uint32_t version,\n                                       std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(version, source);\n}\n\nbool get_block_txs::from_data(uint32_t version,\n                                       reader &source)\n{\n    reset();\n    block_hash = source.read_hash();\n    auto result = static_cast<bool>(source);\n\n    const auto count = source.read_variable_uint_little_endian();\n    result &= static_cast<bool>(source);\n\n    if (result)\n        indexes.reserve(count);\n\n    for (uint64_t i = 0; (i < count) && result; ++i)\n    {\n        indexes.push_back(source.read_variable_uint_little_endian());\n        result = static_cast<bool>(source);\n    }\n\n    if (!result)\n        reset();\n\n    return result;\n}\n\ndata_chunk get_block_txs::to_data(uint32_t version) const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(version, ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version));\n    return data;\n}\n\nvoid get_block_txs::to_data(uint32_t version,\n                                     std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(version, sink);\n}\n\nvoid get_block_txs::to_data(uint32_t version,\n                                     writer &sink) const\n{\n    sink.write_hash(block_hash);\n    sink.write_variable_uint_little_endian(indexes.size());\n    for (const auto &element : indexes)\n        sink.write_variable_uint_little_endian(element);\n}\n\nuint64_t get_block_txs::serialized_size(uint32_t version) const\n{\n    uint64_t size = hash_size + variable_uint_size(indexes.size());\n\n    for (const auto &element : indexes)\n        size += variable_uint_size(element);\n\n    return size;\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/get_blocks.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/get_blocks.hpp>\n\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string get_blocks::command = \"getblocks\";\nconst uint32_t get_blocks::version_minimum = version::level::minimum;\nconst uint32_t get_blocks::version_maximum = version::level::maximum;\n\nget_blocks get_blocks::factory_from_data(uint32_t version,\n                                         const data_chunk &data)\n{\n    get_blocks instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\nget_blocks get_blocks::factory_from_data(uint32_t version,\n                                         std::istream &stream)\n{\n    get_blocks instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\nget_blocks get_blocks::factory_from_data(uint32_t version,\n                                         reader &source)\n{\n    get_blocks instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nget_blocks::get_blocks()\n    : start_hashes(), stop_hash()\n{\n}\n\nget_blocks::get_blocks(const hash_list &start, const hash_digest &stop)\n    : start_hashes(start), stop_hash(stop)\n{\n}\n\nget_blocks::get_blocks(hash_list &&start, hash_digest &&stop)\n    : start_hashes(std::forward<hash_list>(start)),\n      stop_hash(std::forward<hash_digest>(stop))\n{\n}\n\nbool get_blocks::is_valid() const\n{\n    return !start_hashes.empty() || (stop_hash != null_hash);\n}\n\nvoid get_blocks::reset()\n{\n    start_hashes.clear();\n    start_hashes.shrink_to_fit();\n    stop_hash.fill(0);\n}\n\nbool get_blocks::from_data(uint32_t version, const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(version, istream);\n}\n\nbool get_blocks::from_data(uint32_t version, std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(version, source);\n}\n\nbool get_blocks::from_data(uint32_t version, reader &source)\n{\n    reset();\n\n    // discard protocol version because it is stupid.\n    source.read_4_bytes_little_endian();\n\n    const auto count = source.read_variable_uint_little_endian();\n    start_hashes.reserve(count);\n\n    for (uint64_t i = 0; i < count && source; ++i)\n        start_hashes.push_back(source.read_hash());\n\n    if (source)\n        stop_hash = source.read_hash();\n    else\n        reset();\n\n    return source;\n}\n\ndata_chunk get_blocks::to_data(uint32_t version) const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(version, ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version));\n    return data;\n}\n\nvoid get_blocks::to_data(uint32_t version, std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(version, sink);\n}\n\nvoid get_blocks::to_data(uint32_t version, writer &sink) const\n{\n    sink.write_4_bytes_little_endian(version);\n    sink.write_variable_uint_little_endian(start_hashes.size());\n\n    for (const auto &start_hash : start_hashes)\n        sink.write_hash(start_hash);\n\n    sink.write_hash(stop_hash);\n}\n\nuint64_t get_blocks::serialized_size(uint32_t version) const\n{\n    return 36 + variable_uint_size(start_hashes.size()) +\n           hash_size * start_hashes.size();\n}\n\nbool operator==(const get_blocks &left, const get_blocks &right)\n{\n    auto result = (left.start_hashes.size() == right.start_hashes.size());\n\n    for (size_t i = 0; i < left.start_hashes.size() && result; i++)\n        result = (left.start_hashes[i] == right.start_hashes[i]);\n\n    return result && left.stop_hash == right.stop_hash;\n}\n\nbool operator!=(const get_blocks &left, const get_blocks &right)\n{\n    return !(left == right);\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/get_data.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/get_data.hpp>\n\n#include <initializer_list>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/message/inventory.hpp>\n#include <UChain/coin/message/version.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string get_data::command = \"getdata\";\nconst uint32_t get_data::version_minimum = version::level::minimum;\nconst uint32_t get_data::version_maximum = version::level::maximum;\n\nget_data get_data::factory_from_data(uint32_t version,\n                                     const data_chunk &data)\n{\n    get_data instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\nget_data get_data::factory_from_data(uint32_t version,\n                                     std::istream &stream)\n{\n    get_data instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\nget_data get_data::factory_from_data(uint32_t version,\n                                     reader &source)\n{\n    get_data instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nget_data::get_data()\n    : inventory()\n{\n}\n\nget_data::get_data(const inventory_vector::list &elements)\n    : inventory(elements)\n{\n}\n\nget_data::get_data(const hash_list &hashes, inventory::type_id type)\n    : inventory(hashes, type)\n{\n}\n\nget_data::get_data(const std::initializer_list<inventory_vector> &elements)\n    : inventory(elements)\n{\n}\n\nbool get_data::from_data(uint32_t version, const data_chunk &data)\n{\n    return inventory::from_data(version, data);\n}\n\nbool get_data::from_data(uint32_t version, std::istream &stream)\n{\n    return inventory::from_data(version, stream);\n}\n\nbool get_data::from_data(uint32_t version, reader &source)\n{\n    bool result = !(version < get_data::version_minimum);\n\n    if (result)\n        result = inventory::from_data(version, source);\n\n    if (!result)\n        reset();\n\n    return result;\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/get_headers.cpp",
    "content": "/*\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/get_headers.hpp>\n\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/message/version.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string get_headers::command = \"getheaders\";\nconst uint32_t get_headers::version_minimum = version::level::headers;\nconst uint32_t get_headers::version_maximum = version::level::maximum;\n\nget_headers get_headers::factory_from_data(uint32_t version,\n                                           const data_chunk &data)\n{\n    get_headers instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\nget_headers get_headers::factory_from_data(uint32_t version,\n                                           std::istream &stream)\n{\n    get_headers instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\nget_headers get_headers::factory_from_data(uint32_t version,\n                                           reader &source)\n{\n    get_headers instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nget_headers::get_headers()\n    : get_blocks()\n{\n}\n\nget_headers::get_headers(const hash_list &start, const hash_digest &stop)\n    : get_blocks(start, stop)\n{\n}\n\nget_headers::get_headers(hash_list &&start, hash_digest &&stop)\n    : get_headers(start, stop)\n{\n}\n\nbool get_headers::from_data(uint32_t version, const data_chunk &data)\n{\n    return get_blocks::from_data(version, data);\n}\n\nbool get_headers::from_data(uint32_t version, std::istream &stream)\n{\n    return get_blocks::from_data(version, stream);\n}\n\nbool get_headers::from_data(uint32_t version, reader &source)\n{\n    bool result = !(version < version_minimum);\n\n    if (result)\n        result = get_blocks::from_data(version, source);\n    else\n        reset();\n\n    return result;\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/headers.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/headers.hpp>\n\n#include <algorithm>\n#include <cstdint>\n#include <utility>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/message/inventory.hpp>\n#include <UChain/coin/message/inventory_vector.hpp>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string headers::command = \"headers\";\nconst uint32_t headers::version_minimum = version::level::headers;\nconst uint32_t headers::version_maximum = version::level::maximum;\n\nheaders headers::factory_from_data(uint32_t version,\n                                   const data_chunk &data)\n{\n    headers instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\nheaders headers::factory_from_data(uint32_t version,\n                                   std::istream &stream)\n{\n    headers instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\nheaders headers::factory_from_data(uint32_t version,\n                                   reader &source)\n{\n    headers instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nheaders::headers()\n{\n}\n\nheaders::headers(const chain::header::list &values)\n{\n    elements.insert(elements.end(), values.begin(), values.end());\n}\n\nheaders::headers(const std::initializer_list<chain::header> &values)\n{\n    elements.insert(elements.end(), values.begin(), values.end());\n}\n\nbool headers::is_valid() const\n{\n    return !elements.empty();\n}\n\nvoid headers::reset()\n{\n    elements.clear();\n    elements.shrink_to_fit();\n}\n\nbool headers::from_data(uint32_t version, const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(version, istream);\n}\n\nbool headers::from_data(uint32_t version, std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(version, source);\n}\n\nbool headers::from_data(uint32_t version, reader &source)\n{\n    reset();\n\n    auto result = !(version < version_minimum);\n    const auto count = source.read_variable_uint_little_endian();\n    result &= static_cast<bool>(source);\n\n    if (result)\n    {\n        elements.resize(count);\n\n        for (auto &element : elements)\n        {\n            result = element.from_data(source, true);\n\n            if (!result)\n                break;\n        }\n    }\n\n    if (!result)\n        reset();\n\n    return result;\n}\n\ndata_chunk headers::to_data(uint32_t version) const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(version, ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version));\n    return data;\n}\n\nvoid headers::to_data(uint32_t version, std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(version, sink);\n}\n\nvoid headers::to_data(uint32_t version, writer &sink) const\n{\n    sink.write_variable_uint_little_endian(elements.size());\n\n    for (const auto &element : elements)\n        element.to_data(sink, true);\n}\n\nvoid headers::to_hashes(hash_list &out) const\n{\n    const auto map = [](const chain::header &header) {\n        return header.hash();\n    };\n\n    out.resize(elements.size());\n    std::transform(elements.begin(), elements.end(), out.begin(), map);\n}\n\nvoid headers::to_inventory(inventory_vector::list &out,\n                           inventory::type_id type) const\n{\n    const auto map = [type](const chain::header &header) {\n        return inventory_vector{type, header.hash()};\n    };\n\n    out.resize(elements.size());\n    std::transform(elements.begin(), elements.end(), out.begin(), map);\n}\n\nuint64_t headers::serialized_size(uint32_t version) const\n{\n    uint64_t size = variable_uint_size(elements.size());\n\n    for (const auto &element : elements)\n        size += element.serialized_size(true);\n\n    return size;\n}\n\nbool operator==(const headers &left, const headers &right)\n{\n    return left.elements == right.elements;\n}\n\nbool operator!=(const headers &left, const headers &right)\n{\n    return !(left == right);\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/heading.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/heading.hpp>\n\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/messages.hpp>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nsize_t heading::maximum_size()\n{\n    // This assumes that the heading doesn't shrink in size.\n    return serialized_size();\n}\n\n// A maximal inventory is 50,000 entries, the largest valid message.\n// Inventory with 50,000 entries is 3 + 36 * 50,000 bytes (1,800,003).\n// The variable integer portion is maximum 3 bytes (with a count of 50,000).\n// According to protocol documentation get_blocks is limited only by the\n// general maximum payload size of 0x02000000 (33,554,432). But this is an\n// absurd limit for a message that should always be very small.\nsize_t heading::maximum_payload_size(uint32_t)\n{\n    static constexpr size_t vector = sizeof(uint32_t) + hash_size;\n    static constexpr size_t maximum = 3u + vector * 50000u;\n    static_assert(maximum <= max_size_t, \"maximum_payload_size overflow\");\n    return maximum;\n}\n\nsize_t heading::serialized_size()\n{\n    return sizeof(uint32_t) + command_size + sizeof(uint32_t) +\n           sizeof(uint32_t);\n}\n\nheading heading::factory_from_data(const data_chunk &data)\n{\n    heading instance;\n    instance.from_data(data);\n    return instance;\n}\n\nheading heading::factory_from_data(std::istream &stream)\n{\n    heading instance;\n    instance.from_data(stream);\n    return instance;\n}\n\nheading heading::factory_from_data(reader &source)\n{\n    heading instance;\n    instance.from_data(source);\n    return instance;\n}\n\nbool heading::is_valid() const\n{\n    return (magic != 0) || (payload_size != 0) || (checksum != 0) || !command.empty();\n}\n\nvoid heading::reset()\n{\n    magic = 0;\n    command.clear();\n    command.shrink_to_fit();\n    payload_size = 0;\n    checksum = 0;\n}\n\nbool heading::from_data(const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(istream);\n}\n\nbool heading::from_data(std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(source);\n}\n\nbool heading::from_data(reader &source)\n{\n    reset();\n    magic = source.read_4_bytes_little_endian();\n    command = source.read_fixed_string(command_size);\n    payload_size = source.read_4_bytes_little_endian();\n    checksum = source.read_4_bytes_little_endian();\n\n    if (!source)\n        reset();\n\n    return source;\n}\n\ndata_chunk heading::to_data() const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == heading::serialized_size());\n    return data;\n}\n\nvoid heading::to_data(std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(sink);\n}\n\nvoid heading::to_data(writer &sink) const\n{\n    sink.write_4_bytes_little_endian(magic);\n    sink.write_fixed_string(command, command_size);\n    sink.write_4_bytes_little_endian(payload_size);\n    sink.write_4_bytes_little_endian(checksum);\n}\n\nmessage_type heading::type() const\n{\n    // TODO: convert to static map.\n    if (command == address::command)\n        return message_type::address;\n    if (command == block_txs::command)\n        return message_type::block_txs;\n    if (command == block_msg::command)\n        return message_type::block_msg;\n    if (command == compact_block::command)\n        return message_type::compact_block;\n    if (command == filter_add::command)\n        return message_type::filter_add;\n    if (command == filter_clear::command)\n        return message_type::filter_clear;\n    if (command == filter_load::command)\n        return message_type::filter_load;\n    if (command == get_address::command)\n        return message_type::get_address;\n    if (command == get_block_txs::command)\n        return message_type::get_block_txs;\n    if (command == get_blocks::command)\n        return message_type::get_blocks;\n    if (command == get_data::command)\n        return message_type::get_data;\n    if (command == get_headers::command)\n        return message_type::get_headers;\n    if (command == headers::command)\n        return message_type::headers;\n    if (command == inventory::command)\n        return message_type::inventory;\n    if (command == memory_pool::command)\n        return message_type::memory_pool;\n    if (command == merkle_block::command)\n        return message_type::merkle_block;\n    if (command == not_found::command)\n        return message_type::not_found;\n    if (command == ping::command)\n        return message_type::ping;\n    if (command == pong::command)\n        return message_type::pong;\n    if (command == reject::command)\n        return message_type::reject;\n    if (command == send_compact_blocks::command)\n        return message_type::send_compact_blocks;\n    if (command == send_headers::command)\n        return message_type::send_headers;\n    if (command == tx_message::command)\n        return message_type::tx_message;\n    if (command == verack::command)\n        return message_type::verack;\n    if (command == version::command)\n        return message_type::version;\n\n    return message_type::unknown;\n}\n\nbool operator==(const heading &left, const heading &right)\n{\n    return (left.magic == right.magic) && (left.command == right.command) && (left.payload_size == right.payload_size) && (left.checksum == right.checksum);\n}\n\nbool operator!=(const heading &left, const heading &right)\n{\n    return !(left == right);\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/inventory.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/inventory.hpp>\n\n#include <algorithm>\n#include <initializer_list>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/message/inventory.hpp>\n#include <UChain/coin/message/inventory_vector.hpp>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string inventory::command = \"inv\";\nconst uint32_t inventory::version_minimum = version::level::minimum;\nconst uint32_t inventory::version_maximum = version::level::maximum;\n\ninventory inventory::factory_from_data(uint32_t version,\n                                       const data_chunk &data)\n{\n    inventory instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\ninventory inventory::factory_from_data(uint32_t version,\n                                       std::istream &stream)\n{\n    inventory instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\ninventory inventory::factory_from_data(uint32_t version,\n                                       reader &source)\n{\n    inventory instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\ninventory::inventory()\n{\n}\n\ninventory::inventory(const inventory_vector::list &values)\n{\n    inventories.insert(inventories.end(), values.begin(), values.end());\n}\n\ninventory::inventory(const hash_list &hashes, type_id type)\n{\n    const auto map = [type](const hash_digest &hash) {\n        return inventory_vector{type, hash};\n    };\n\n    inventories.resize(hashes.size());\n    std::transform(hashes.begin(), hashes.end(), inventories.begin(), map);\n}\n\ninventory::inventory(const std::initializer_list<inventory_vector> &values)\n{\n    inventories.insert(inventories.end(), values.begin(), values.end());\n}\n\nbool inventory::is_valid() const\n{\n    return !inventories.empty();\n}\n\nvoid inventory::reset()\n{\n    inventories.clear();\n    inventories.shrink_to_fit();\n}\n\nbool inventory::from_data(uint32_t version, const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(version, istream);\n}\n\nbool inventory::from_data(uint32_t version, std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(version, source);\n}\n\nbool inventory::from_data(uint32_t version, reader &source)\n{\n    reset();\n    const auto count = source.read_variable_uint_little_endian();\n    auto result = static_cast<bool>(source);\n\n    if (result)\n    {\n        inventories.resize(count);\n\n        for (auto &inventory : inventories)\n        {\n            result = inventory.from_data(version, source);\n\n            if (!result)\n                break;\n        }\n    }\n\n    if (!result)\n        reset();\n\n    return result;\n}\n\ndata_chunk inventory::to_data(uint32_t version) const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(version, ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version));\n    return data;\n}\n\nvoid inventory::to_data(uint32_t version, std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(version, sink);\n}\n\nvoid inventory::to_data(uint32_t version, writer &sink) const\n{\n    sink.write_variable_uint_little_endian(inventories.size());\n\n    for (const auto &inventory : inventories)\n        inventory.to_data(version, sink);\n}\n\nvoid inventory::to_hashes(hash_list &out, type_id type) const\n{\n    out.reserve(inventories.size());\n\n    for (const auto &inventory : inventories)\n        if (inventory.type == type)\n            out.push_back(inventory.hash);\n\n    out.shrink_to_fit();\n}\n\nvoid inventory::reduce(inventory_vector::list &out, type_id type) const\n{\n    out.reserve(inventories.size());\n\n    for (const auto &inventory : inventories)\n        if (inventory.type == type)\n            out.push_back(inventory);\n\n    out.shrink_to_fit();\n}\n\nuint64_t inventory::serialized_size(uint32_t version) const\n{\n    return variable_uint_size(inventories.size()) + inventories.size() *\n                                                        inventory_vector::satoshi_fixed_size(version);\n}\n\nsize_t inventory::count(type_id type) const\n{\n    const auto is_type = [type](const inventory_vector &element) {\n        return element.type == type;\n    };\n\n    return count_if(inventories.begin(), inventories.end(), is_type);\n}\n\nbool operator==(const inventory &left, const inventory &right)\n{\n    return left.inventories == right.inventories;\n}\n\nbool operator!=(const inventory &left, const inventory &right)\n{\n    return !(left == right);\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/inventory_vector.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/inventory_vector.hpp>\n\n#include <cstdint>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/message/inventory.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nuint32_t inventory_vector::to_number(type_id inventory_type)\n{\n    switch (inventory_type)\n    {\n    case type_id::error:\n    case type_id::none:\n    default:\n        return 0;\n    case type_id::transaction:\n        return 1;\n    case type_id::block:\n        return 2;\n    case type_id::compact_block:\n        return 4;\n    }\n}\n\ninventory_vector::type_id inventory_vector::to_type(uint32_t value)\n{\n    switch (value)\n    {\n    case 0:\n        return type_id::error;\n    case 1:\n        return type_id::transaction;\n    case 2:\n        return type_id::block;\n    case 4:\n        return type_id::compact_block;\n    default:\n        return type_id::none;\n    }\n}\n\ninventory_vector inventory_vector::factory_from_data(uint32_t version,\n                                                     const data_chunk &data)\n{\n    inventory_vector instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\ninventory_vector inventory_vector::factory_from_data(uint32_t version,\n                                                     std::istream &stream)\n{\n    inventory_vector instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\ninventory_vector inventory_vector::factory_from_data(uint32_t version,\n                                                     reader &source)\n{\n    inventory_vector instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nbool inventory_vector::is_valid() const\n{\n    return (type != inventory::type_id::error) || (hash != null_hash);\n}\n\nvoid inventory_vector::reset()\n{\n    type = inventory::type_id::error;\n    hash.fill(0);\n}\n\nbool inventory_vector::from_data(uint32_t version,\n                                 const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(version, istream);\n}\n\nbool inventory_vector::from_data(uint32_t version,\n                                 std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(version, source);\n}\n\nbool inventory_vector::from_data(uint32_t version,\n                                 reader &source)\n{\n    reset();\n\n    uint32_t raw_type = source.read_4_bytes_little_endian();\n    type = inventory_vector::to_type(raw_type);\n    hash = source.read_hash();\n    bool result = static_cast<bool>(source);\n\n    if (!result)\n        reset();\n\n    return result;\n}\n\ndata_chunk inventory_vector::to_data(uint32_t version) const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(version, ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version));\n    return data;\n}\n\nvoid inventory_vector::to_data(uint32_t version,\n                               std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(version, sink);\n}\n\nvoid inventory_vector::to_data(uint32_t version,\n                               writer &sink) const\n{\n    const auto raw_type = inventory_vector::to_number(type);\n    sink.write_4_bytes_little_endian(raw_type);\n    sink.write_hash(hash);\n}\n\nuint64_t inventory_vector::serialized_size(uint32_t version) const\n{\n    return inventory_vector::satoshi_fixed_size(version);\n}\n\nuint64_t inventory_vector::satoshi_fixed_size(uint32_t version)\n{\n    return sizeof(hash) + sizeof(uint32_t);\n}\n\nbool inventory_vector::is_block_type() const\n{\n    return type == inventory::type_id::block ||\n           type == inventory::type_id::compact_block ||\n           type == inventory::type_id::filtered_block;\n}\n\nbool inventory_vector::is_transaction_type() const\n{\n    return type == message::inventory::type_id::transaction;\n}\n\nbool operator==(const inventory_vector &left, const inventory_vector &right)\n{\n    return (left.hash == right.hash) && (left.type == right.type);\n}\n\nbool operator!=(const inventory_vector &left, const inventory_vector &right)\n{\n    return !(left == right);\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/memory_pool.cpp",
    "content": "/*\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/memory_pool.hpp>\n\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string memory_pool::command = \"mempool\";\nconst uint32_t memory_pool::version_minimum = version::level::bip35;\nconst uint32_t memory_pool::version_maximum = version::level::maximum;\n\nmemory_pool memory_pool::factory_from_data(uint32_t version,\n                                           const data_chunk &data)\n{\n    memory_pool instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\nmemory_pool memory_pool::factory_from_data(uint32_t version,\n                                           std::istream &stream)\n{\n    memory_pool instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\nmemory_pool memory_pool::factory_from_data(uint32_t version,\n                                           reader &source)\n{\n    memory_pool instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nmemory_pool::memory_pool()\n{\n    reset();\n}\n\nbool memory_pool::is_valid() const\n{\n    return !insufficient_version_;\n}\n\nvoid memory_pool::reset()\n{\n    insufficient_version_ = false;\n}\n\nbool memory_pool::from_data(uint32_t version, const data_chunk &data)\n{\n    boost::iostreams::stream<byte_source<data_chunk>> istream(data);\n    return from_data(version, istream);\n}\n\nbool memory_pool::from_data(uint32_t version, std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(version, source);\n}\n\nbool memory_pool::from_data(uint32_t version, reader &source)\n{\n    reset();\n    insufficient_version_ = (version < memory_pool::version_minimum);\n    return !insufficient_version_;\n}\n\ndata_chunk memory_pool::to_data(uint32_t version) const\n{\n    data_chunk data;\n    boost::iostreams::stream<byte_sink<data_chunk>> ostream(data);\n    to_data(version, ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version));\n    return data;\n}\n\nvoid memory_pool::to_data(uint32_t version, std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(version, sink);\n}\n\nvoid memory_pool::to_data(uint32_t version, writer &sink) const\n{\n}\n\nuint64_t memory_pool::serialized_size(uint32_t version) const\n{\n    return memory_pool::satoshi_fixed_size(version);\n}\n\nuint64_t memory_pool::satoshi_fixed_size(uint32_t version)\n{\n    return 0;\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/merkle_block.cpp",
    "content": "/*\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/merkle_block.hpp>\n\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string merkle_block::command = \"merkleblock\";\nconst uint32_t merkle_block::version_minimum = version::level::bip37;\nconst uint32_t merkle_block::version_maximum = version::level::maximum;\n\nmerkle_block merkle_block::factory_from_data(uint32_t version,\n                                             const data_chunk &data)\n{\n    merkle_block instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\nmerkle_block merkle_block::factory_from_data(uint32_t version,\n                                             std::istream &stream)\n{\n    merkle_block instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\nmerkle_block merkle_block::factory_from_data(uint32_t version,\n                                             reader &source)\n{\n    merkle_block instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nbool merkle_block::is_valid() const\n{\n    return !hashes.empty() || !flags.empty() || header.is_valid();\n}\n\nvoid merkle_block::reset()\n{\n    header.reset();\n    hashes.clear();\n    hashes.shrink_to_fit();\n    flags.clear();\n    flags.shrink_to_fit();\n}\n\nbool merkle_block::from_data(uint32_t version, const data_chunk &data)\n{\n    boost::iostreams::stream<byte_source<data_chunk>> istream(data);\n    return from_data(version, istream);\n}\n\nbool merkle_block::from_data(uint32_t version, std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(version, source);\n}\n\nbool merkle_block::from_data(uint32_t version, reader &source)\n{\n    reset();\n\n    bool result = !(version < merkle_block::version_minimum);\n    uint64_t hash_count = 0;\n\n    if (result)\n        result = header.from_data(source, true);\n\n    if (result)\n    {\n        hash_count = source.read_variable_uint_little_endian();\n        result = source;\n    }\n\n    if (result)\n        hashes.reserve(hash_count);\n\n    for (uint64_t i = 0; (i < hash_count) && result; ++i)\n    {\n        hashes.push_back(source.read_hash());\n        result = source;\n    }\n\n    if (result)\n    {\n        const auto size = source.read_variable_uint_little_endian();\n        BITCOIN_ASSERT(size <= bc::max_size_t);\n        const auto flag_count = static_cast<size_t>(size);\n        flags = source.read_data(flag_count);\n        result = source && (flags.size() == flag_count);\n    }\n\n    if (!result)\n        reset();\n\n    return result;\n}\n\ndata_chunk merkle_block::to_data(uint32_t version) const\n{\n    data_chunk data;\n    boost::iostreams::stream<byte_sink<data_chunk>> ostream(data);\n    to_data(version, ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version));\n    return data;\n}\n\nvoid merkle_block::to_data(uint32_t version, std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(version, sink);\n}\n\nvoid merkle_block::to_data(uint32_t version, writer &sink) const\n{\n    header.to_data(sink, true);\n\n    sink.write_variable_uint_little_endian(hashes.size());\n\n    for (const auto &hash : hashes)\n        sink.write_hash(hash);\n\n    sink.write_variable_uint_little_endian(flags.size());\n    sink.write_data(flags);\n}\n\nuint64_t merkle_block::serialized_size(uint32_t version) const\n{\n    return header.serialized_size(true) +\n           variable_uint_size(hashes.size()) + (hash_size * hashes.size()) +\n           variable_uint_size(flags.size()) + flags.size();\n}\n\nbool operator==(const merkle_block &block_a,\n                const merkle_block &block_b)\n{\n    bool result = (block_a.header == block_b.header) &&\n                  (block_a.hashes.size() == block_b.hashes.size()) &&\n                  (block_a.flags.size() == block_b.flags.size());\n\n    for (hash_list::size_type i = 0; i < block_a.hashes.size() && result; i++)\n        result = (block_a.hashes[i] == block_b.hashes[i]);\n\n    for (data_chunk::size_type i = 0; i < block_a.flags.size() && result; i++)\n        result = (block_a.flags[i] == block_b.flags[i]);\n\n    return result;\n}\n\nbool operator!=(const merkle_block &block_a,\n                const merkle_block &block_b)\n{\n    return !(block_a == block_b);\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/network_address.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/network_address.hpp>\n\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n#include <string.h>\n\n#define INADDR_NONE ((in_addr_t)0xffffffff)\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nip_address null_address =\n    {\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};\n\nstatic const unsigned char pchIPv4[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff};\nstatic const unsigned char pchOnionCat[] = {0xFD, 0x87, 0xD8, 0x7E, 0xEB, 0x43};\n\nnetwork_address network_address::factory_from_data(uint32_t version,\n                                                   const data_chunk &data, bool with_timestamp)\n{\n    network_address instance;\n    instance.from_data(version, data, with_timestamp);\n    return instance;\n}\n\nnetwork_address network_address::factory_from_data(uint32_t version,\n                                                   std::istream &stream, bool with_timestamp)\n{\n    network_address instance;\n    instance.from_data(version, stream, with_timestamp);\n    return instance;\n}\n\nnetwork_address network_address::factory_from_data(uint32_t version,\n                                                   reader &source, bool with_timestamp)\n{\n    network_address instance;\n    instance.from_data(version, source, with_timestamp);\n    return instance;\n}\n\nbool network_address::is_valid() const\n{\n#if 0\n    return (timestamp != 0)\n        || (services != 0)\n        || (port != 0)\n        || (ip != null_address);\n#else\n    // Cleanup 3-byte shifted addresses caused by garbage in size field\n    // of addr messages from versions before 0.2.9 checksum.\n    // Two consecutive addr messages look like this:\n    // header20 vectorlen3 addr26 addr26 addr26 header20 vectorlen3 addr26 addr26 addr26...\n    // so if the first length field is garbled, it reads the second batch\n    // of addr misaligned by 3 bytes.\n    if (memcmp(ip.data(), pchIPv4 + 3, sizeof(pchIPv4) - 3) == 0)\n        return false;\n\n    // unspecified IPv6 address (::/128)\n    unsigned char ipNone[16] = {};\n    if (memcmp(ip.data(), ipNone, 16) == 0)\n        return false;\n\n    // documentation IPv6 address\n    if (is_RFC3849())\n        return false;\n\n    if (is_ipv4())\n    {\n        // INADDR_NONE\n        uint32_t ipNone = 0;\n        if (memcmp(&ip[12], &ipNone, 4) == 0)\n            return false;\n\n        // 0\n        ipNone = 0;\n        if (memcmp(&ip[12], &ipNone, 4) == 0)\n            return false;\n    }\n\n    return true;\n#endif\n}\n\nvoid network_address::reset()\n{\n    timestamp = 0;\n    services = 0;\n    ip.fill(0);\n    port = 0;\n}\n\nbool network_address::from_data(uint32_t version,\n                                const data_chunk &data, bool with_timestamp)\n{\n    data_source istream(data);\n    return from_data(version, istream, with_timestamp);\n}\n\nbool network_address::from_data(uint32_t version,\n                                std::istream &stream, bool with_timestamp)\n{\n    istream_reader source(stream);\n    return from_data(version, source, with_timestamp);\n}\n\nbool network_address::from_data(uint32_t version,\n                                reader &source, bool with_timestamp)\n{\n    auto result = false;\n\n    reset();\n\n    if (with_timestamp)\n        timestamp = source.read_4_bytes_little_endian();\n\n    services = source.read_8_bytes_little_endian();\n    const auto ip_size = source.read_data(ip.data(), ip.size());\n    port = source.read_2_bytes_big_endian();\n    result = source && (ip.size() == ip_size);\n\n    if (!result)\n        reset();\n\n    return result;\n}\n\ndata_chunk network_address::to_data(uint32_t version,\n                                    bool with_timestamp) const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(version, ostream, with_timestamp);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version, with_timestamp));\n    return data;\n}\n\nvoid network_address::to_data(uint32_t version,\n                              std::ostream &stream, bool with_timestamp) const\n{\n    ostream_writer sink(stream);\n    to_data(version, sink, with_timestamp);\n}\n\nvoid network_address::to_data(uint32_t version,\n                              writer &sink, bool with_timestamp) const\n{\n    if (with_timestamp)\n        sink.write_4_bytes_little_endian(timestamp);\n\n    sink.write_8_bytes_little_endian(services);\n    sink.write_data(ip.data(), ip.size());\n    sink.write_2_bytes_big_endian(port);\n}\n\nuint64_t network_address::serialized_size(uint32_t version,\n                                          bool with_timestamp) const\n{\n    return network_address::satoshi_fixed_size(version, with_timestamp);\n}\n\nuint64_t network_address::satoshi_fixed_size(uint32_t version,\n                                             bool with_timestamp)\n{\n    uint64_t result = 26;\n\n    if (with_timestamp)\n        result += 4;\n\n    return result;\n}\n\nunsigned int network_address::get_byte(int n) const\n{\n    return ip[15 - n];\n}\n\nbool network_address::is_ipv4() const\n{\n    return (memcmp(ip.data(), pchIPv4, sizeof(pchIPv4)) == 0);\n}\n\nbool network_address::is_ipv6() const\n{\n    return (!is_ipv4() && !is_tor());\n}\n\nbool network_address::is_private_network()\n{\n    return is_RFC1918();\n}\n\nbool network_address::is_RFC1918() const\n{\n    return is_ipv4() && (get_byte(3) == 10 ||\n                         (get_byte(3) == 192 && get_byte(2) == 168) ||\n                         (get_byte(3) == 172 && (get_byte(2) >= 16 && get_byte(2) <= 31)));\n    return false;\n}\n\nbool network_address::is_RFC3927() const\n{\n    return is_ipv4() && (get_byte(3) == 169 && get_byte(2) == 254);\n}\n\nbool network_address::is_RFC3849() const\n{\n    return get_byte(15) == 0x20 && get_byte(14) == 0x01 && get_byte(13) == 0x0D && get_byte(12) == 0xB8;\n}\n\nbool network_address::is_RFC3964() const\n{\n    return (get_byte(15) == 0x20 && get_byte(14) == 0x02);\n}\n\nbool network_address::is_RFC6052() const\n{\n    static const unsigned char pchRFC6052[] = {0, 0x64, 0xFF, 0x9B, 0, 0, 0, 0, 0, 0, 0, 0};\n    return (memcmp(ip.data(), pchRFC6052, sizeof(pchRFC6052)) == 0);\n}\n\nbool network_address::is_RFC4380() const\n{\n    return (get_byte(15) == 0x20 && get_byte(14) == 0x01 && get_byte(13) == 0 && get_byte(12) == 0);\n}\n\nbool network_address::is_RFC4862() const\n{\n    static const unsigned char pchRFC4862[] = {0xFE, 0x80, 0, 0, 0, 0, 0, 0};\n    return (memcmp(ip.data(), pchRFC4862, sizeof(pchRFC4862)) == 0);\n}\n\nbool network_address::is_RFC4193() const\n{\n    return ((get_byte(15) & 0xFE) == 0xFC);\n}\n\nbool network_address::is_RFC6145() const\n{\n    static const unsigned char pchRFC6145[] = {0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0};\n    return (memcmp(ip.data(), pchRFC6145, sizeof(pchRFC6145)) == 0);\n}\n\nbool network_address::is_RFC4843() const\n{\n    return (get_byte(15) == 0x20 && get_byte(14) == 0x01 && get_byte(13) == 0x00 && (get_byte(12) & 0xF0) == 0x10);\n}\n\nbool network_address::is_tor() const\n{\n    return (memcmp(ip.data(), pchOnionCat, sizeof(pchOnionCat)) == 0);\n}\n\nbool network_address::is_local() const\n{\n    // IPv4 loopback\n    if (is_ipv4() && (get_byte(3) == 127 || get_byte(3) == 0))\n        return true;\n\n    // IPv6 loopback (::1/128)\n    static const unsigned char pchLocal[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};\n    if (memcmp(ip.data(), pchLocal, 16) == 0)\n        return true;\n\n    return false;\n}\n\nbool network_address::is_routable() const\n{\n    return is_valid() && !(is_RFC3927() || is_RFC4862() || (is_RFC4193() && !is_tor()) || is_RFC4843() || is_local());\n    //return is_valid() && !(is_RFC1918() || is_RFC3927() || is_RFC4862() || (is_RFC4193() && !is_tor()) || is_RFC4843() || is_local());\n}\n\nbool network_address::is_ulticast() const\n{\n    return (is_ipv4() && (get_byte(3) & 0xF0) == 0xE0) || (get_byte(15) == 0xFF);\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/not_found.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/not_found.hpp>\n\n#include <initializer_list>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/message/inventory.hpp>\n#include <UChain/coin/message/version.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string not_found::command = \"notfound\";\nconst uint32_t not_found::version_minimum = version::level::bip37;\nconst uint32_t not_found::version_maximum = version::level::maximum;\n\nnot_found not_found::factory_from_data(uint32_t version,\n                                       const data_chunk &data)\n{\n    not_found instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\nnot_found not_found::factory_from_data(uint32_t version,\n                                       std::istream &stream)\n{\n    not_found instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\nnot_found not_found::factory_from_data(uint32_t version,\n                                       reader &source)\n{\n    not_found instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nnot_found::not_found()\n    : inventory()\n{\n}\n\nnot_found::not_found(const inventory_vector::list &values)\n    : inventory(values)\n{\n}\n\nnot_found::not_found(const hash_list &hashes, inventory::type_id type)\n    : inventory(hashes, type)\n{\n}\n\nnot_found::not_found(const std::initializer_list<inventory_vector> &values)\n    : inventory(values)\n{\n}\n\nbool not_found::from_data(uint32_t version, const data_chunk &data)\n{\n    return inventory::from_data(version, data);\n}\n\nbool not_found::from_data(uint32_t version, std::istream &stream)\n{\n    return inventory::from_data(version, stream);\n}\n\nbool not_found::from_data(uint32_t version, reader &source)\n{\n    bool result = !(version < not_found::version_minimum);\n\n    if (result)\n        result = inventory::from_data(version, source);\n\n    if (!result)\n        reset();\n\n    return result;\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/ping.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/ping.hpp>\n\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string ping::command = \"ping\";\nconst uint32_t ping::version_minimum = version::level::minimum;\nconst uint32_t ping::version_maximum = version::level::maximum;\n\nping ping::factory_from_data(uint32_t version, const data_chunk &data)\n{\n    ping instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\nping ping::factory_from_data(uint32_t version, std::istream &stream)\n{\n    ping instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\nping ping::factory_from_data(uint32_t version, reader &source)\n{\n    ping instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nuint64_t ping::satoshi_fixed_size(uint32_t version)\n{\n    return version < version::level::bip31 ? 0 : sizeof(nonce);\n}\n\nping::ping()\n    : ping(0)\n{\n}\n\nping::ping(uint64_t nonce)\n    : nonce(nonce), valid_(nonce != 0)\n{\n}\n\nbool ping::from_data(uint32_t version, const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(version, istream);\n}\n\nbool ping::from_data(uint32_t version, std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(version, source);\n}\n\nbool ping::from_data(uint32_t version, reader &source)\n{\n    reset();\n\n    if (version >= version::level::bip31)\n        nonce = source.read_8_bytes_little_endian();\n\n    // Must track valid because is_valid doesn't include version parameter.\n    // Otherwise when below bip31 then the object would always be invalid.\n    valid_ = source;\n\n    if (!valid_)\n        reset();\n\n    return valid_;\n}\n\ndata_chunk ping::to_data(uint32_t version) const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(version, ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version));\n    return data;\n}\n\nvoid ping::to_data(uint32_t version, std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(version, sink);\n}\n\nvoid ping::to_data(uint32_t version, writer &sink) const\n{\n    if (version >= version::level::bip31)\n        sink.write_8_bytes_little_endian(nonce);\n}\n\nbool ping::is_valid() const\n{\n    return valid_;\n}\n\nvoid ping::reset()\n{\n    nonce = 0;\n}\n\nuint64_t ping::serialized_size(uint32_t version) const\n{\n    return satoshi_fixed_size(version);\n}\n\nbool operator==(const ping &left, const ping &right)\n{\n    // Nonce should be zero if not used.\n    return (left.nonce == right.nonce);\n}\n\nbool operator!=(const ping &left, const ping &right)\n{\n    // Nonce should be zero if not used.\n    return !(left == right);\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/pong.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/pong.hpp>\n\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string pong::command = \"pong\";\nconst uint32_t pong::version_minimum = version::level::minimum;\nconst uint32_t pong::version_maximum = version::level::maximum;\n\npong pong::factory_from_data(uint32_t version, const data_chunk &data)\n{\n    pong instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\npong pong::factory_from_data(uint32_t version, std::istream &stream)\n{\n    pong instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\npong pong::factory_from_data(uint32_t version, reader &source)\n{\n    pong instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nuint64_t pong::satoshi_fixed_size(uint32_t version)\n{\n    return sizeof(nonce);\n}\n\nbool pong::from_data(uint32_t version, const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(version, istream);\n}\n\nbool pong::from_data(uint32_t version, std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(version, source);\n}\n\nbool pong::from_data(uint32_t version, reader &source)\n{\n    reset();\n\n    nonce = source.read_8_bytes_little_endian();\n\n    if (!source)\n        reset();\n\n    return source;\n}\n\ndata_chunk pong::to_data(uint32_t version) const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(version, ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version));\n    return data;\n}\n\nvoid pong::to_data(uint32_t version, std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(version, sink);\n}\n\nvoid pong::to_data(uint32_t version, writer &sink) const\n{\n    sink.write_8_bytes_little_endian(nonce);\n}\n\nbool pong::is_valid() const\n{\n    return (nonce != 0);\n}\n\nvoid pong::reset()\n{\n    nonce = 0;\n}\n\nuint64_t pong::serialized_size(uint32_t version) const\n{\n    return satoshi_fixed_size(version);\n}\n\nbool operator==(const pong &left, const pong &right)\n{\n    return (left.nonce == right.nonce);\n}\n\nbool operator!=(const pong &left, const pong &right)\n{\n    return !(left == right);\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/prefilled_tx.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/prefilled_tx.hpp>\n\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nprefilled_tx prefilled_tx::factory_from_data(\n    const uint32_t version, const data_chunk &data)\n{\n    prefilled_tx instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\nprefilled_tx prefilled_tx::factory_from_data(\n    const uint32_t version, std::istream &stream)\n{\n    prefilled_tx instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\nprefilled_tx prefilled_tx::factory_from_data(\n    const uint32_t version, reader &source)\n{\n    prefilled_tx instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nbool prefilled_tx::is_valid() const\n{\n    return (index < max_uint16) && transaction.is_valid();\n}\n\nvoid prefilled_tx::reset()\n{\n    index = 0;\n    transaction.reset();\n}\n\nbool prefilled_tx::from_data(uint32_t version,\n                                      const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(version, istream);\n}\n\nbool prefilled_tx::from_data(uint32_t version,\n                                      std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(version, source);\n}\n\nbool prefilled_tx::from_data(uint32_t version,\n                                      reader &source)\n{\n    reset();\n\n    index = source.read_variable_uint_little_endian();\n    auto result = static_cast<bool>(source);\n\n    if (result)\n        result = transaction.from_data(source);\n\n    if (!result)\n        reset();\n\n    return result;\n}\n\ndata_chunk prefilled_tx::to_data(uint32_t version) const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(version, ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version));\n    return data;\n}\n\nvoid prefilled_tx::to_data(uint32_t version,\n                                    std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(version, sink);\n}\n\nvoid prefilled_tx::to_data(uint32_t version,\n                                    writer &sink) const\n{\n    sink.write_variable_uint_little_endian(index);\n    transaction.to_data(sink);\n}\n\nuint64_t prefilled_tx::serialized_size(uint32_t version) const\n{\n    return variable_uint_size(index) + transaction.serialized_size();\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/reject.cpp",
    "content": "/*\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/reject.hpp>\n\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/message/block_msg.hpp>\n#include <UChain/coin/message/tx_msg.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string reject::command = \"reject\";\nconst uint32_t reject::version_minimum = version::level::bip61;\nconst uint32_t reject::version_maximum = version::level::maximum;\n\nreject reject::factory_from_data(uint32_t version,\n                                 const data_chunk &data)\n{\n    reject instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\nreject reject::factory_from_data(uint32_t version,\n                                 std::istream &stream)\n{\n    reject instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\nreject reject::factory_from_data(uint32_t version,\n                                 reader &source)\n{\n    reject instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nbool reject::is_valid() const\n{\n    return !message.empty() || (code != error_code::undefined) || !reason.empty() || (data != null_hash);\n}\n\nvoid reject::reset()\n{\n    message.clear();\n    message.shrink_to_fit();\n    code = error_code::undefined;\n    reason.clear();\n    reason.shrink_to_fit();\n    data.fill(0);\n}\n\nbool reject::from_data(uint32_t version, const data_chunk &data)\n{\n    boost::iostreams::stream<byte_source<data_chunk>> istream(data);\n    return from_data(version, istream);\n}\n\nbool reject::from_data(uint32_t version, std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(version, source);\n}\n\nbool reject::from_data(uint32_t version, reader &source)\n{\n    const auto insufficient_version = (version < reject::version_minimum);\n\n    reset();\n\n    message = source.read_string();\n    code = error_code_from_byte(source.read_byte());\n    reason = source.read_string();\n\n    if ((message == block_msg::command) ||\n        (message == tx_message::command))\n    {\n        data = source.read_hash();\n    }\n\n    const auto result = source && !insufficient_version;\n\n    if (!result)\n        reset();\n\n    return result;\n}\n\ndata_chunk reject::to_data(uint32_t version) const\n{\n    data_chunk data;\n    boost::iostreams::stream<byte_sink<data_chunk>> ostream(data);\n    to_data(version, ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version));\n    return data;\n}\n\nvoid reject::to_data(uint32_t version, std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(version, sink);\n}\n\nvoid reject::to_data(uint32_t version, writer &sink) const\n{\n    sink.write_string(message);\n    sink.write_byte(error_code_to_byte(code));\n    sink.write_string(reason);\n\n    if ((message == block_msg::command) ||\n        (message == tx_message::command))\n    {\n        sink.write_hash(data);\n    }\n}\n\nuint64_t reject::serialized_size(uint32_t version) const\n{\n    uint64_t size = 1 + variable_uint_size(message.size()) + message.size() +\n                    variable_uint_size(reason.size()) + reason.size();\n\n    if ((message == block_msg::command) ||\n        (message == tx_message::command))\n    {\n        size += hash_size;\n    }\n\n    return size;\n}\n\nreject::error_code reject::error_code_from_byte(uint8_t byte)\n{\n    switch (byte)\n    {\n    case 0x01:\n        return error_code::malformed;\n    case 0x10:\n        return error_code::invalid;\n    case 0x11:\n        return error_code::obsolete;\n    case 0x12:\n        return error_code::duplicate;\n    case 0x40:\n        return error_code::nonstandard;\n    case 0x41:\n        return error_code::dust;\n    case 0x42:\n        return error_code::insufficient_fee;\n    case 0x43:\n        return error_code::checkpoint;\n    default:\n        return error_code::undefined;\n    }\n}\n\nuint8_t reject::error_code_to_byte(const error_code code)\n{\n    switch (code)\n    {\n    case error_code::malformed:\n        return 0x01;\n    case error_code::invalid:\n        return 0x10;\n    case error_code::obsolete:\n        return 0x11;\n    case error_code::duplicate:\n        return 0x12;\n    case error_code::nonstandard:\n        return 0x40;\n    case error_code::dust:\n        return 0x41;\n    case error_code::insufficient_fee:\n        return 0x42;\n    case error_code::checkpoint:\n        return 0x43;\n    default:\n        return 0x00;\n    }\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/send_compact_blocks.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/send_compact_blocks.hpp>\n\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string send_compact_blocks::command = \"sendcmpct\";\nconst uint32_t send_compact_blocks::version_minimum = version::level::bip152;\nconst uint32_t send_compact_blocks::version_maximum = version::level::bip152;\n\nsend_compact_blocks send_compact_blocks::factory_from_data(\n    const uint32_t version, const data_chunk &data)\n{\n    send_compact_blocks instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\nsend_compact_blocks send_compact_blocks::factory_from_data(\n    const uint32_t version, std::istream &stream)\n{\n    send_compact_blocks instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\nsend_compact_blocks send_compact_blocks::factory_from_data(\n    const uint32_t version, reader &source)\n{\n    send_compact_blocks instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nbool send_compact_blocks::is_valid() const\n{\n    return true;\n}\n\nvoid send_compact_blocks::reset()\n{\n    high_bandwidth_mode = false;\n    version = 0;\n}\n\nbool send_compact_blocks::from_data(uint32_t version,\n                                    const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(version, istream);\n}\n\nbool send_compact_blocks::from_data(uint32_t version,\n                                    std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(version, source);\n}\n\nbool send_compact_blocks::from_data(uint32_t version,\n                                    reader &source)\n{\n    reset();\n    const auto insufficient_version = (version < send_compact_blocks::version_minimum);\n\n    const auto mode = source.read_byte();\n    auto result = static_cast<bool>(source);\n\n    if (mode > 1)\n        result &= false;\n\n    high_bandwidth_mode = (mode == 1);\n\n    this->version = source.read_8_bytes_little_endian();\n    result &= static_cast<bool>(source);\n\n    if (!result || insufficient_version)\n        reset();\n\n    return result && !insufficient_version;\n}\n\ndata_chunk send_compact_blocks::to_data(uint32_t version) const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(version, ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version));\n    return data;\n}\n\nvoid send_compact_blocks::to_data(uint32_t version,\n                                  std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(version, sink);\n}\n\nvoid send_compact_blocks::to_data(uint32_t version,\n                                  writer &sink) const\n{\n    sink.write_byte(high_bandwidth_mode ? 1 : 0);\n    sink.write_8_bytes_little_endian(this->version);\n}\n\nuint64_t send_compact_blocks::serialized_size(uint32_t version) const\n{\n    return send_compact_blocks::satoshi_fixed_size(version);\n}\n\nuint64_t send_compact_blocks::satoshi_fixed_size(uint32_t version)\n{\n    return 9;\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/send_headers.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/send_headers.hpp>\n\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string send_headers::command = \"sendheaders\";\nconst uint32_t send_headers::version_minimum = version::level::bip130;\nconst uint32_t send_headers::version_maximum = version::level::maximum;\n\nsend_headers send_headers::factory_from_data(uint32_t version,\n                                             const data_chunk &data)\n{\n    send_headers instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\nsend_headers send_headers::factory_from_data(uint32_t version,\n                                             std::istream &stream)\n{\n    send_headers instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\nsend_headers send_headers::factory_from_data(uint32_t version,\n                                             reader &source)\n{\n    send_headers instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nuint64_t send_headers::satoshi_fixed_size(uint32_t version)\n{\n    return 0;\n}\n\nsend_headers::send_headers()\n{\n    reset();\n}\n\nbool send_headers::is_valid() const\n{\n    return !version_unsupported_;\n}\n\nvoid send_headers::reset()\n{\n    version_unsupported_ = false;\n}\n\nbool send_headers::from_data(uint32_t version, const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(version, istream);\n}\n\nbool send_headers::from_data(uint32_t version, std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(version, source);\n}\n\nbool send_headers::from_data(uint32_t version, reader &source)\n{\n    reset();\n\n    if (version < send_headers::version_minimum)\n        version_unsupported_ = true;\n\n    return !version_unsupported_;\n}\n\ndata_chunk send_headers::to_data(uint32_t version) const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(version, ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version));\n    return data;\n}\n\nvoid send_headers::to_data(uint32_t version, std::ostream &stream) const\n{\n}\n\nuint64_t send_headers::serialized_size(uint32_t version) const\n{\n    return send_headers::satoshi_fixed_size(version);\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/verack.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/verack.hpp>\n\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/message/version.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string verack::command = \"verack\";\nconst uint32_t verack::version_minimum = version::level::minimum;\nconst uint32_t verack::version_maximum = version::level::maximum;\n\nverack verack::factory_from_data(uint32_t version,\n                                 const data_chunk &data)\n{\n    verack instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\nverack verack::factory_from_data(uint32_t version,\n                                 std::istream &stream)\n{\n    verack instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\nverack verack::factory_from_data(uint32_t version,\n                                 reader &source)\n{\n    verack instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nbool verack::is_valid() const\n{\n    return true;\n}\n\nvoid verack::reset()\n{\n}\n\nbool verack::from_data(uint32_t version, const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(version, istream);\n}\n\nbool verack::from_data(uint32_t version, std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(version, source);\n}\n\nbool verack::from_data(uint32_t version, reader &source)\n{\n    reset();\n    return source;\n}\n\ndata_chunk verack::to_data(uint32_t version) const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(version, ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version));\n    return data;\n}\n\nvoid verack::to_data(uint32_t version, std::ostream &stream) const\n{\n}\n\nuint64_t verack::serialized_size(uint32_t version) const\n{\n    return verack::satoshi_fixed_size(version);\n}\n\nuint64_t verack::satoshi_fixed_size(uint32_t version)\n{\n    return 0;\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/message/version.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/message/version.hpp>\n\n#include <algorithm>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace message\n{\n\nconst std::string version::command = \"version\";\nconst uint32_t message::version::version_minimum = level::minimum;\nconst uint32_t message::version::version_maximum = level::maximum;\n\nversion version::factory_from_data(uint32_t version,\n                                   const data_chunk &data)\n{\n    message::version instance;\n    instance.from_data(version, data);\n    return instance;\n}\n\nversion version::factory_from_data(uint32_t version,\n                                   std::istream &stream)\n{\n    message::version instance;\n    instance.from_data(version, stream);\n    return instance;\n}\n\nversion version::factory_from_data(uint32_t version,\n                                   reader &source)\n{\n    message::version instance;\n    instance.from_data(version, source);\n    return instance;\n}\n\nbool version::is_valid() const\n{\n    return (value != 0) || (services != 0) || (timestamp != 0) || address_recevier.is_valid() || address_sender.is_valid() || (nonce != 0) || !user_agent.empty() || (start_height != 0) || (relay != 0);\n}\n\nvoid version::reset()\n{\n    value = 0;\n    services = 0;\n    timestamp = 0;\n    address_recevier.reset();\n    address_sender.reset();\n    nonce = 0;\n    user_agent.clear();\n    user_agent.shrink_to_fit();\n    start_height = 0;\n    relay = false;\n}\n\nbool version::from_data(uint32_t version, const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(version, istream);\n}\n\nbool version::from_data(uint32_t version, std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(version, source);\n}\n\nbool version::from_data(uint32_t version, reader &source)\n{\n    reset();\n\n    value = source.read_4_bytes_little_endian();\n    const uint32_t effective_version = std::min(version, value);\n    services = source.read_8_bytes_little_endian();\n    timestamp = source.read_8_bytes_little_endian();\n    auto result = static_cast<bool>(source);\n    result = address_recevier.from_data(version, source, false);\n    result = result && address_sender.from_data(version, source, false);\n    nonce = source.read_8_bytes_little_endian();\n    user_agent = source.read_string();\n    start_height = source.read_4_bytes_little_endian();\n\n    // HACK: due to the partial implementation of Bitcoin Core BIP37.\n    if (effective_version >= level::bip61)\n        relay = (source.read_byte() != 0);\n\n    // HACK: disabled check due to inconsistent node implementation.\n    // The protocol expects duplication of the sender's services.\n    result &= (source /*&& services == address_sender.services*/);\n\n    if (!result)\n        reset();\n\n    return result;\n}\n\ndata_chunk version::to_data(uint32_t version) const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(version, ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size(version));\n    return data;\n}\n\nvoid version::to_data(uint32_t version, std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(version, sink);\n}\n\nvoid version::to_data(uint32_t version, writer &sink) const\n{\n    sink.write_4_bytes_little_endian(value);\n    const uint32_t effective_version = std::min(version, value);\n    sink.write_8_bytes_little_endian(services);\n    sink.write_8_bytes_little_endian(timestamp);\n    address_recevier.to_data(version, sink, false);\n    address_sender.to_data(version, sink, false);\n    sink.write_8_bytes_little_endian(nonce);\n    sink.write_string(user_agent);\n    sink.write_4_bytes_little_endian(start_height);\n\n    if (effective_version >= level::bip37)\n        sink.write_byte(relay ? 1 : 0);\n}\n\nuint64_t version::serialized_size(uint32_t version) const\n{\n    auto size =\n        sizeof(value) +\n        sizeof(services) +\n        sizeof(timestamp) +\n        address_recevier.serialized_size(version, false) +\n        address_sender.serialized_size(version, false) +\n        sizeof(nonce) +\n        variable_uint_size(user_agent.size()) + user_agent.size() +\n        sizeof(start_height);\n\n    if (value >= level::bip37)\n        size += sizeof(uint8_t);\n\n    return size;\n}\n\n} // namespace message\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/unicode/console_streambuf.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/unicode/console_streambuf.hpp>\n\n#include <cstddef>\n#include <iostream>\n#include <new>\n#include <streambuf>\n\n#ifdef _MSC_VER\n#include <windows.h>\n\n// Get Windows input handle.\nstatic LPVOID get_input_handle()\n{\n    auto handle = GetStdHandle(STD_INPUT_HANDLE);\n    if (handle == INVALID_HANDLE_VALUE || handle == nullptr)\n        throw std::ios_base::failure(\"Failed to get input handle.\");\n\n    return handle;\n}\n#endif\n\nnamespace libbitcoin\n{\n\n// This class/mathod is a no-op on non-windows platforms.\n// When working in Windows console set font to \"Lucida Console\".\n// This is the factory method to privately instantiate a singleton class.\nvoid console_streambuf::initialize(size_t size)\n{\n#ifdef _MSC_VER\n    // Set the console to operate in UTF-8 for this process.\n    if (SetConsoleCP(CP_UTF8) == FALSE)\n        throw std::ios_base::failure(\"Failed to set console to utf8.\");\n\n    DWORD console_mode;\n    if (GetConsoleMode(get_input_handle(), &console_mode) != FALSE)\n    {\n        // Hack for faulty std::wcin translation of non-ASCII keyboard input.\n        static console_streambuf buffer(*std::wcin.rdbuf(), size);\n        std::wcin.rdbuf(&buffer);\n    }\n#endif\n}\n\nconsole_streambuf::console_streambuf(\n    std::wstreambuf const &stream_buffer, size_t size)\n#ifdef _MSC_VER\n    : buffer_size_(size), buffer_(new wchar_t[buffer_size_]),\n      std::wstreambuf(stream_buffer)\n#else\n    : buffer_size_(0), buffer_(nullptr)\n#endif\n{\n}\n\nconsole_streambuf::~console_streambuf()\n{\n#ifdef _MSC_VER\n    delete[] buffer_;\n#endif\n}\n\nstd::streamsize console_streambuf::xsgetn(wchar_t *buffer,\n                                          std::streamsize size)\n{\n    std::streamsize read_size = 0;\n\n#ifdef _MSC_VER\n    DWORD read_bytes;\n    const auto result = ReadConsoleW(get_input_handle(), buffer,\n                                     static_cast<DWORD>(size), &read_bytes, nullptr);\n\n    if (result == FALSE)\n        throw std::iostream::failure(\"Failed to read from console.\");\n\n    read_size = static_cast<std::streamsize>(read_bytes);\n#endif\n\n    return read_size;\n}\n\nstd::wstreambuf::int_type console_streambuf::underflow()\n{\n#ifdef _MSC_VER\n    if (gptr() == nullptr || gptr() >= egptr())\n    {\n        const auto length = xsgetn(buffer_, buffer_size_);\n        if (length > 0)\n            setg(buffer_, buffer_, &buffer_[length]);\n    }\n\n    if (gptr() == nullptr || gptr() >= egptr())\n        return traits_type::eof();\n#endif\n\n    return traits_type::to_int_type(*gptr());\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/unicode/ifstream.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/unicode/ifstream.hpp>\n\n#include <fstream>\n#include <string>\n#include <UChain/coin/unicode/unicode.hpp>\n\nnamespace libbitcoin\n{\n\n// Construct bc::ifstream.\nifstream::ifstream(const std::string &path, std::ifstream::openmode mode)\n#ifdef _MSC_VER\n    : std::ifstream(bc::to_utf16(path), mode)\n#else\n    : std::ifstream(path, mode)\n#endif\n{\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/unicode/ofstream.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/unicode/ofstream.hpp>\n\n#include <fstream>\n#include <string>\n#include <UChain/coin/unicode/unicode.hpp>\n#include <boost/filesystem.hpp>\n\nnamespace libbitcoin\n{\n\n// Construct bc::ofstream.\nofstream::ofstream(const std::string &path, std::ofstream::openmode mode)\n#ifdef _MSC_VER\n    : std::ofstream(bc::to_utf16(path), mode), max_size_(LOG_MAX_SIZE), path_(path)\n#else\n    : std::ofstream(path, mode), max_size_(LOG_MAX_SIZE), path_(path)\n#endif\n{\n    current_size_ = boost::filesystem::file_size(path);\n}\n\nuint64_t ofstream::increment(uint64_t size)\n{\n    current_size_ += size;\n    return current_size_;\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/unicode/unicode.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/unicode/unicode.hpp>\n\n#include <cstddef>\n#include <cstring>\n#include <cwchar>\n#include <iostream>\n#include <mutex>\n#include <stdexcept>\n#include <string>\n#include <boost/locale.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/unicode/console_streambuf.hpp>\n#include <UChain/coin/unicode/unicode_istream.hpp>\n#include <UChain/coin/unicode/unicode_ostream.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/data.hpp>\n\n#ifdef _MSC_VER\n#include <fcntl.h>\n#include <io.h>\n#endif\n\nnamespace libbitcoin\n{\n\nusing namespace boost::locale;\n\n// The width of utf16 stdio buffers.\nconstexpr size_t utf16_buffer_size = 256;\n\n// Local definition for max number of bytes in a utf8 character.\nconstexpr size_t utf8_max_character_size = 4;\n\n// Ensure console_streambuf::initialize is called only once.\nstatic std::once_flag io_mutex;\n\n// Ensure validate_localization is called only once.\nstatic std::once_flag icu_mutex;\n\n// Static initializer for bc::cin.\nstatic std::istream &cin_stream()\n{\n    std::call_once(io_mutex, console_streambuf::initialize, utf16_buffer_size);\n    static unicode_istream input(std::cin, std::wcin, utf16_buffer_size);\n    return input;\n}\n\n// Static initializer for bc::cout.\nstatic std::ostream &cout_stream()\n{\n    std::call_once(io_mutex, console_streambuf::initialize, utf16_buffer_size);\n    static unicode_ostream output(std::cout, std::wcout, utf16_buffer_size);\n    return output;\n}\n\n// Static initializer for bc::cerr.\nstatic std::ostream &cerr_stream()\n{\n    std::call_once(io_mutex, console_streambuf::initialize, utf16_buffer_size);\n    static unicode_ostream error(std::cerr, std::wcerr, utf16_buffer_size);\n    return error;\n}\n\n// Use bc::cin in place of std::cin, etc.\n#ifdef __ANDROID__\nstd::istream &cin = std::cin;\nstd::ostream &cout = std::cout;\nstd::ostream &cerr = std::cerr;\n#else\nstd::istream &cin = cin_stream();\nstd::ostream &cout = cout_stream();\nstd::ostream &cerr = cerr_stream();\n#endif\n\n#ifdef WITH_ICU\n\n// The backend selection is ignored if invalid (in this case on Windows).\nstatic std::string normal_form(const std::string &value, norm_type form)\n{\n    auto backend = localization_backend_manager::global();\n    backend.select(BC_LOCALE_BACKEND);\n    const generator locale(backend);\n    return normalize(value, form, locale(BC_LOCALE_UTF8));\n}\n\n// One time verifier of the localization backend manager. This is\n// necessary because boost::normalize will fail silently to perform\n// normalization if the ICU dependency is missing.\nstatic void validate_localization()\n{\n    const auto ascii_space = \"> <\";\n    const auto ideographic_space = \">　<\";\n    const auto normal = normal_form(ideographic_space, norm_type::norm_nfkd);\n    if (normal != ascii_space)\n        throw std::runtime_error(\n            \"Unicode normalization test failed, a dependency may be missing.\");\n}\n\n// Normalize strings using unicode nfc normalization.\nstd::string to_normal_nfc_form(const std::string &value)\n{\n    std::call_once(icu_mutex, validate_localization);\n    return normal_form(value, norm_type::norm_nfc);\n}\n\n// Normalize strings using unicode nfkd normalization.\nstd::string to_normal_nfkd_form(const std::string &value)\n{\n    std::call_once(icu_mutex, validate_localization);\n    return normal_form(value, norm_type::norm_nfkd);\n}\n\n#endif\n\n// Convert wmain environment to utf8 main environment.\ndata_chunk to_utf8(wchar_t *environment[])\n{\n    int count;\n    for (count = 0; environment[count] != nullptr; count++)\n        ;\n    return to_utf8(count, environment);\n}\n\n// Convert wmain parameters to utf8 main parameters.\ndata_chunk to_utf8(int argc, wchar_t *argv[])\n{\n    auto arg_count = static_cast<size_t>(argc);\n\n    // Convert each arg and determine the payload size.\n    size_t payload_size = 0;\n    std::vector<std::string> collection(arg_count + 1);\n    for (size_t arg = 0; arg < arg_count; arg++)\n    {\n        collection[arg] = to_utf8(argv[arg]);\n        payload_size += collection[arg].size() + 1;\n    }\n\n    // Determine the index size.\n    auto index_size = static_cast<size_t>((arg_count + 1) * sizeof(void *));\n\n    // Allocate the new buffer.\n    auto buffer_size = index_size + payload_size;\n    data_chunk buffer(buffer_size, 0x00);\n    buffer.resize(buffer_size);\n\n    // Set pointers into index and payload buffer sections.\n    auto index = reinterpret_cast<char **>(&buffer[0]);\n    auto arguments = reinterpret_cast<char *>(&buffer[index_size]);\n\n    // Clone the converted collection into the new narrow argv.\n    for (size_t arg = 0; arg < arg_count; arg++)\n    {\n        index[arg] = arguments;\n        std::copy(collection[arg].begin(), collection[arg].end(), index[arg]);\n        arguments += collection[arg].size() + 1;\n    }\n\n    return buffer;\n}\n\n// Convert wstring to utf8 string.\nstd::string to_utf8(const std::wstring &wide)\n{\n    using namespace boost::locale;\n    return conv::utf_to_utf<char>(wide, conv::method_type::stop);\n}\n\n// Convert wchar_t buffer to utf8 char buffer.\nsize_t to_utf8(char out[], size_t out_bytes, const wchar_t in[],\n               size_t in_chars)\n{\n    BITCOIN_ASSERT(in != nullptr);\n    BITCOIN_ASSERT(out != nullptr);\n    BITCOIN_ASSERT(out_bytes >= utf8_max_character_size * in_chars);\n\n    if (in_chars == 0)\n        return 0;\n\n    size_t bytes = 0;\n\n    try\n    {\n        const auto narrow = to_utf8({in, &in[in_chars]});\n        bytes = narrow.size();\n\n        if (bytes <= out_bytes)\n            memcpy(out, narrow.data(), bytes);\n    }\n    catch (const boost::locale::conv::conversion_error &)\n    {\n        bytes = 0;\n    }\n\n    if (bytes == 0)\n        throw std::istream::failure(\"utf-16 to utf-8 conversion failure\");\n\n    if (bytes > out_bytes)\n        throw std::ios_base::failure(\"utf8 buffer is too small\");\n\n    return bytes;\n}\n\n// All non-leading bytes of utf8 have the same two bit prefix.\nstatic bool is_utf8_trailing_byte(char byte)\n{\n    // 10xxxxxx\n    return ((0xC0 & byte) == 0x80);\n}\n\n// Determine if the full sequence is a valid utf8 character.\nstatic bool is_utf8_character_sequence(const char sequence[], uint8_t bytes)\n{\n    BITCOIN_ASSERT(bytes <= utf8_max_character_size);\n\n    // See tools.ietf.org/html/rfc3629#section-3 for definition.\n    switch (bytes)\n    {\n    case 1:\n        // 0xxxxxxx\n        return ((0x80 & sequence[0]) == 0x00);\n    case 2:\n        // 110xxxxx 10xxxxxx\n        return ((0xE0 & sequence[0]) == 0xC0) &&\n               is_utf8_trailing_byte(sequence[1]);\n    case 3:\n        // 1110xxxx 10xxxxxx 10xxxxxx\n        return ((0xF0 & sequence[0]) == 0xE0) &&\n               is_utf8_trailing_byte(sequence[1]) &&\n               is_utf8_trailing_byte(sequence[2]);\n    case 4:\n        // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx\n        return ((0xF8 & sequence[0]) == 0xF0) &&\n               is_utf8_trailing_byte(sequence[1]) &&\n               is_utf8_trailing_byte(sequence[2]) &&\n               is_utf8_trailing_byte(sequence[3]);\n    default:;\n    }\n\n    return false;\n}\n\n// Determine if the text is terminated by a valid utf8 character.\nstatic bool is_terminal_utf8_character(const char text[], size_t size)\n{\n    BITCOIN_ASSERT(text != nullptr);\n\n    // Walk back up to the max length of a utf8 character.\n    for (uint8_t length = 1; length <= utf8_max_character_size &&\n                             length < size;\n         length++)\n    {\n        const auto start = size - length;\n        const auto sequence = &text[start];\n        if (is_utf8_character_sequence(sequence, length))\n            return true;\n    }\n\n    return false;\n}\n\n// This optimizes character split detection by taking advantage of utf8\n// character recognition so we don't have to convert in full up to 3 times.\n// This does not guaratee that the entire string is valid as utf8, just that a\n// returned offset follows the last byte of a utf8 terminal char if it exists.\nstatic uint8_t offset_to_terminal_utf8_character(const char text[], size_t size)\n{\n    BITCOIN_ASSERT(text != nullptr);\n\n    // Walk back up to the max length of a utf8 character.\n    for (uint8_t unread = 0; unread < utf8_max_character_size &&\n                             unread < size;\n         unread++)\n    {\n        const auto length = size - unread;\n        if (is_terminal_utf8_character(text, length))\n            return unread;\n    }\n\n    return 0;\n}\n\n// Convert utf8 char buffer to wchar_t buffer, with truncation handling.\nsize_t to_utf16(wchar_t out[], size_t out_chars, const char in[],\n                size_t in_bytes, uint8_t &truncated)\n{\n    BITCOIN_ASSERT(in != nullptr);\n    BITCOIN_ASSERT(out != nullptr);\n    BITCOIN_ASSERT(out_chars >= in_bytes);\n\n    // Calculate a character break offset of 0..4 bytes.\n    truncated = offset_to_terminal_utf8_character(in, in_bytes);\n\n    if (in_bytes == 0)\n        return 0;\n\n    size_t chars = 0;\n\n    try\n    {\n        const auto wide = to_utf16({in, &in[in_bytes - truncated]});\n        chars = wide.size();\n\n        if (chars <= out_chars)\n            wmemcpy(out, wide.data(), chars);\n    }\n    catch (const boost::locale::conv::conversion_error &)\n    {\n        chars = 0;\n    }\n\n    if (chars == 0)\n        throw std::ostream::failure(\"utf-8 to utf-16 conversion failure\");\n\n    if (chars > out_chars)\n        throw std::ios_base::failure(\"utf16 buffer is too small\");\n\n    return chars;\n}\n\n// Convert utf8 string to wstring.\nstd::wstring to_utf16(const std::string &narrow)\n{\n    using namespace boost::locale;\n    return conv::utf_to_utf<wchar_t>(narrow, conv::method_type::stop);\n}\n\nLCOV_EXCL_START(\"Untestable but visually-verifiable section.\")\n\nstatic void set_utf8_stdio(FILE *file)\n{\n#ifdef _MSC_VER\n    if (_setmode(_fileno(file), _O_U8TEXT) == -1)\n        throw std::runtime_error(\"Could not set STDIO to utf8 mode.\");\n#endif\n}\n\nstatic void set_binary_stdio(FILE *file)\n{\n#ifdef _MSC_VER\n    if (_setmode(_fileno(file), _O_BINARY) == -1)\n        throw std::runtime_error(\"Could not set STDIO to binary mode.\");\n#endif\n}\n\n// Set stdio to use UTF8 translation on Windows.\nvoid set_utf8_stdio()\n{\n    set_utf8_stdin();\n    set_utf8_stdout();\n    //set_utf8_stderr();\n}\n\n// Set stdio to use UTF8 translation on Windows.\nvoid set_utf8_stdin()\n{\n    set_utf8_stdio(stdin);\n}\n\n// Set stdio to use UTF8 translation on Windows.\nvoid set_utf8_stdout()\n{\n    set_utf8_stdio(stdout);\n}\n\n// Set stdio to use UTF8 translation on Windows.\nvoid set_utf8_stderr()\n{\n    set_utf8_stdio(stderr);\n}\n\n// Set stdio to use UTF8 translation on Windows.\nvoid set_binary_stdin()\n{\n    set_binary_stdio(stdin);\n}\n\n// Set stdio to use UTF8 translation on Windows.\nvoid set_binary_stdout()\n{\n    set_binary_stdio(stdout);\n}\n\nLCOV_EXCL_STOP()\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/unicode/unicode_istream.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/unicode/unicode_istream.hpp>\n\n#include <cstddef>\n#include <iostream>\n#include <UChain/coin/unicode/unicode_streambuf.hpp>\n\nnamespace libbitcoin\n{\n\nunicode_istream::unicode_istream(std::istream &narrow_stream,\n                                 std::wistream &wide_stream, size_t size)\n#ifdef _MSC_VER\n    : std::istream(new unicode_streambuf(wide_stream.rdbuf(), size))\n#else\n    : std::istream(narrow_stream.rdbuf())\n#endif\n{\n}\n\nunicode_istream::~unicode_istream()\n{\n#ifdef _MSC_VER\n  delete rdbuf();\n#endif\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/unicode/unicode_ostream.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/unicode/unicode_ostream.hpp>\n\n#include <cstddef>\n#include <iostream>\n#include <UChain/coin/unicode/unicode_streambuf.hpp>\n\nnamespace libbitcoin\n{\n\nunicode_ostream::unicode_ostream(std::ostream &narrow_stream,\n                                 std::wostream &wide_stream, size_t size)\n#ifdef _MSC_VER\n    : std::ostream(new unicode_streambuf(wide_stream.rdbuf(), size))\n#else\n    : std::ostream(narrow_stream.rdbuf())\n#endif\n{\n}\n\nunicode_ostream::~unicode_ostream()\n{\n#ifdef _MSC_VER\n  delete rdbuf();\n#endif\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/unicode/unicode_streambuf.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/unicode/unicode_streambuf.hpp>\n\n#include <cstddef>\n#include <cstring>\n#include <iostream>\n#include <streambuf>\n#include <UChain/coin/constants.hpp>\n#include <UChain/coin/unicode/unicode.hpp>\n#include <UChain/coin/utility/assert.hpp>\n\nnamespace libbitcoin\n{\n\n// Local definition for max number of bytes in a utf8 character.\nconstexpr size_t utf8_max_character_size = 4;\n\nunicode_streambuf::unicode_streambuf(std::wstreambuf *wide_buffer, size_t size)\n    : wide_size_(size), narrow_size_(wide_size_ * utf8_max_character_size),\n      narrow_(new char[narrow_size_]), wide_(new wchar_t[narrow_size_]),\n      wide_buffer_(wide_buffer)\n{\n    if (wide_size_ > (bc::max_uint64 / utf8_max_character_size))\n        throw std::ios_base::failure(\n            \"Wide buffer must be no more than one fourth of max uint64.\");\n\n    // Input buffer is not yet populated, reflect zero length buffer here.\n    setg(narrow_, narrow_, narrow_);\n\n    // Output buffer is underexposed by 1 byte to accomodate the overflow byte.\n    setp(narrow_, &narrow_[narrow_size_ - 1]);\n}\n\nunicode_streambuf::~unicode_streambuf()\n{\n    sync();\n    delete[] wide_;\n    delete[] narrow_;\n}\n\n// Read characters from input buffer.\n// This invokes wide_buffer_.xsgetn() which requires a patch for\n// console (keyboard) input on Windows, so ensure this class is\n// initialized with a patched std::wcin when std::wcin is used.\nstd::streambuf::int_type unicode_streambuf::underflow()\n{\n    // streamsize is signed.\n    BITCOIN_ASSERT(wide_size_ > 0 && wide_size_ <= bc::max_int64);\n    const auto size = static_cast<std::streamsize>(wide_size_);\n\n    // Read from the wide input buffer.\n    const auto read = static_cast<size_t>(wide_buffer_->sgetn(wide_, size));\n\n    // Handle read termination.\n    if (read == 0)\n        return traits_type::eof();\n\n    // Convert utf16 to utf8, returning bytes written.\n    const auto bytes = to_utf8(narrow_, narrow_size_, wide_, read);\n\n    // Reset gptr and egptr, eback never changes.\n    setg(narrow_, narrow_, &narrow_[bytes]);\n\n    // Return the first character in the input sequence.\n    return traits_type::to_int_type(*gptr());\n}\n\n// Write characters to output buffer.\n// We compensate for character-splitting. This is necessary because\n// MSVC does not support a UTF8 locale and as such streams interpret\n// narrow characters in the default locale. This implementation\n// assumes the stream will treat each byte of a multibyte narrow\n// chracter as an individual single byte character.\nstd::streambuf::int_type unicode_streambuf::overflow(\n    std::streambuf::int_type character)\n{\n    // Add a single explicitly read byte to the buffer.\n    // The narrow buffer is underexposed by 1 byte to accomodate this.\n    if (character != traits_type::eof())\n    {\n        *pptr() = static_cast<char>(character);\n        pbump(sizeof(char));\n    }\n\n    // This will be in the range 0..4, indicating the number of bytes that were\n    // not written in the conversion. A nonzero value results when the buffer\n    // terminates within a utf8 multiple byte character.\n    uint8_t unwritten = 0;\n\n    // Get the number of bytes in the buffer to convert.\n    const auto write = pptr() - pbase();\n\n    if (write > 0)\n    {\n        // Convert utf8 to utf16, returning chars written and bytes unread.\n        const auto chars = to_utf16(wide_, narrow_size_, narrow_, write,\n                                    unwritten);\n\n        // Write to the wide output buffer.\n        const auto written = wide_buffer_->sputn(wide_, chars);\n\n        // Handle write failure as an EOF.\n        if (static_cast<size_t>(written) != chars)\n        {\n            return traits_type::eof();\n        }\n    }\n\n    // Copy the fractional character to the beginning of the buffer.\n    memcpy(narrow_, &narrow_[write - unwritten], unwritten);\n\n    // Reset the pptr to the buffer start, leave pbase and epptr.\n    // We could use just pbump for this if it wasn't limited to 'int' width.\n    setp(narrow_, &narrow_[narrow_size_ - 1]);\n\n    // Reset pptr just after the fractional character.\n    pbump(unwritten);\n\n    // Return the overflow byte or EOF sentinel.\n    return character;\n};\n\n// Flush our output sequence.\nint unicode_streambuf::sync()\n{\n    const int success = 0;\n    const int failure = -1;\n\n    // We expect EOF to be returned, because we passed it.\n    if (overflow(traits_type::eof()) == traits_type::eof())\n        return success;\n\n    return failure;\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/utility/binary.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/utility/binary.hpp>\n\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <UChain/coin/constants.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/endian.hpp>\n\nnamespace libbitcoin\n{\n\nbinary::size_type binary::blocks_size(size_type bit_size)\n{\n    return bit_size == 0 ? 0 : (bit_size - 1) / bits_per_block + 1;\n}\n\nbool binary::is_base2(const std::string &text)\n{\n    for (const auto &character : text)\n        if (character != '0' && character != '1')\n            return false;\n\n    return true;\n}\n\nbinary::binary()\n    : final_block_excess_(0)\n{\n}\n\nbinary::binary(const binary &other)\n    : blocks_(other.blocks_), final_block_excess_(other.final_block_excess_)\n{\n}\n\nbinary::binary(const std::string &bit_string)\n    : binary()\n{\n    std::stringstream(bit_string) >> *this;\n}\n\nbinary::binary(size_type size, data_slice blocks)\n    : binary()\n{\n    // Copy blocks\n    blocks_.resize(blocks.size());\n    std::copy(blocks.begin(), blocks.end(), blocks_.begin());\n\n    // Pad with 00 for safety.\n    while (blocks_.size() * bits_per_block < size)\n        blocks_.push_back(0x00);\n\n    resize(size);\n}\n\nvoid binary::resize(size_type size)\n{\n    final_block_excess_ = 0;\n    blocks_.resize(blocks_size(size), 0);\n    const size_type offset = size % bits_per_block;\n\n    if (offset > 0)\n    {\n        BITCOIN_ASSERT((bits_per_block - offset) <= max_uint8);\n        final_block_excess_ = static_cast<uint8_t>(bits_per_block - offset);\n\n        uint8_t mask = 0xFF << final_block_excess_;\n        blocks_[blocks_.size() - 1] = blocks_[blocks_.size() - 1] & mask;\n    }\n}\n\nbool binary::operator[](size_type index) const\n{\n    BITCOIN_ASSERT(index < size());\n    const size_type block_index = index / bits_per_block;\n    const uint8_t block = blocks_[block_index];\n    const size_type offset = index - (block_index * bits_per_block);\n    const uint8_t bitmask = 1 << (bits_per_block - offset - 1);\n    return (block & bitmask) > 0;\n}\n\nconst data_chunk &binary::blocks() const\n{\n    return blocks_;\n}\n\nstd::string binary::encoded() const\n{\n    std::stringstream bits;\n    bits << *this;\n    return bits.str();\n}\n\nbinary::size_type binary::size() const\n{\n    return (blocks_.size() * bits_per_block) - final_block_excess_;\n}\n\nvoid binary::append(const binary &post)\n{\n    const size_type block_offset = size() / bits_per_block;\n    const size_type offset = size() % bits_per_block;\n\n    // overkill for byte alignment\n    binary duplicate(post.size(), post.blocks());\n    duplicate.shift_right(offset);\n\n    resize(size() + post.size());\n    data_chunk post_shift_blocks = duplicate.blocks();\n    for (size_type i = 0; i < post_shift_blocks.size(); i++)\n    {\n        blocks_[block_offset + i] = blocks_[block_offset + i] | post_shift_blocks[i];\n    }\n}\n\nvoid binary::prepend(const binary &prior)\n{\n    shift_right(prior.size());\n    data_chunk prior_blocks = prior.blocks();\n    for (size_type i = 0; i < prior_blocks.size(); i++)\n    {\n        blocks_[i] = blocks_[i] | prior_blocks[i];\n    }\n}\n\nvoid binary::shift_left(size_type distance)\n{\n    const size_type initial_size = size();\n    const size_type initial_block_count = blocks_.size();\n    size_type destination_size = 0;\n    if (distance < initial_size)\n        destination_size = initial_size - distance;\n\n    const size_type block_offset = distance / bits_per_block;\n    const size_type offset = distance % bits_per_block;\n\n    // shift\n    for (size_type i = 0; i < initial_block_count; i++)\n    {\n        uint8_t leading_bits = 0x00;\n        uint8_t trailing_bits = 0x00;\n\n        if ((offset != 0) && ((block_offset + i + 1) < initial_block_count))\n        {\n            trailing_bits = blocks_[block_offset + i + 1] >> (bits_per_block - offset);\n        }\n\n        if ((block_offset + i) < initial_block_count)\n        {\n            leading_bits = blocks_[block_offset + i] << offset;\n        }\n\n        blocks_[i] = leading_bits | trailing_bits;\n    }\n\n    resize(destination_size);\n}\n\nvoid binary::shift_right(size_type distance)\n{\n    const size_type initial_size = size();\n    const size_type initial_block_count = blocks_.size();\n    const size_type offset = distance % bits_per_block;\n    const size_type offset_blocks = distance / bits_per_block;\n    const size_type destination_size = initial_size + distance;\n    for (size_type i = 0; i < offset_blocks; i++)\n    {\n        blocks_.insert(blocks_.begin(), 0x00);\n    }\n\n    uint8_t previous = 0x00;\n    for (size_type i = 0; i < initial_block_count; i++)\n    {\n        uint8_t current = blocks_[offset_blocks + i];\n        uint8_t leading_bits = previous << (bits_per_block - offset);\n        uint8_t trailing_bits = current >> offset;\n        blocks_[offset_blocks + i] = leading_bits | trailing_bits;\n        previous = current;\n    }\n\n    resize(destination_size);\n\n    if (offset_blocks + initial_block_count < blocks_.size())\n    {\n        blocks_[blocks_.size() - 1] = previous << (bits_per_block - offset);\n    }\n}\n\nbinary binary::substring(size_type start, size_type length) const\n{\n    size_type current_size = size();\n    if (start > current_size)\n    {\n        start = current_size;\n    }\n\n    if ((length == max_size_t) || ((start + length) > current_size))\n    {\n        length = current_size - start;\n    }\n\n    binary result(current_size, blocks_);\n    result.shift_left(start);\n    result.resize(length);\n    return result;\n}\n\nbool binary::is_prefix_of(uint32_t field) const\n{\n    return is_prefix_of(to_little_endian(field));\n}\n\nbool binary::is_prefix_of(const binary &field) const\n{\n    return is_prefix_of(field.blocks());\n}\n\nbool binary::is_prefix_of(data_slice field) const\n{\n    const binary truncated_prefix(size(), field);\n    return *this == truncated_prefix;\n}\n\nbool binary::operator<(const binary &other) const\n{\n    return encoded() < other.encoded();\n}\n\nbool binary::operator==(const binary &other) const\n{\n    if (size() != other.size())\n        return false;\n\n    const auto self = *this;\n    for (binary::size_type i = 0; i < size(); ++i)\n        if (self[i] != other[i])\n            return false;\n\n    return true;\n}\n\nbool binary::operator!=(const binary &other) const\n{\n    return !(*this == other);\n}\n\nbinary &binary::operator=(const binary &other)\n{\n    blocks_ = other.blocks_;\n    final_block_excess_ = other.final_block_excess_;\n    return *this;\n}\n\nstd::istream &operator>>(std::istream &in, binary &to)\n{\n    std::string bitstring;\n    in >> bitstring;\n\n    to.resize(0);\n    uint8_t block = 0;\n    auto bit_iterator = binary::bits_per_block;\n\n    for (const char representation : bitstring)\n    {\n        if (representation != '0' && representation != '1')\n        {\n            to.blocks_.clear();\n            return in;\n        }\n\n        // Set bit to 1\n        if (representation == '1')\n        {\n            const uint8_t bitmask = 1 << (bit_iterator - 1);\n            block |= bitmask;\n        }\n\n        // Next bit\n        --bit_iterator;\n\n        if (bit_iterator == 0)\n        {\n            // Move to the next block.\n            to.blocks_.push_back(block);\n            block = 0;\n            bit_iterator = binary::bits_per_block;\n        }\n    }\n\n    // Block wasn't finished but push it back.\n    if (bit_iterator != binary::bits_per_block)\n        to.blocks_.push_back(block);\n\n    to.resize(bitstring.size());\n    return in;\n}\n\nstd::ostream &operator<<(std::ostream &out, const binary &of)\n{\n    for (binary::size_type i = 0; i < of.size(); ++i)\n        if (of[i])\n            out << '1';\n        else\n            out << '0';\n\n    return out;\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/utility/conditional_lock.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/utility/conditional_lock.hpp>\n\n#include <memory>\n#include <UChain/coin/utility/thread.hpp>\n\nnamespace libbitcoin\n{\n\nconditional_lock::conditional_lock(std::shared_ptr<shared_mutex> mutex_ptr)\n    : mutex_ptr_(mutex_ptr)\n{\n  if (mutex_ptr_)\n    mutex_ptr->lock();\n}\n\nconditional_lock::~conditional_lock()\n{\n  if (mutex_ptr_)\n    mutex_ptr_->unlock();\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/utility/deadline.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/utility/deadline.hpp>\n\n#include <functional>\n#include <UChain/coin/error.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/thread.hpp>\n#include <UChain/coin/utility/threadpool.hpp>\n\nnamespace libbitcoin\n{\n\nusing std::placeholders::_1;\n\n// This protects timer_ against concurrent access with no chance of deadlock.\n// This can be dereferenced with an outstanding callback because the timer\n// closure captures an instance of this class and the callback.\n// This is guaranteed to call handler exactly once unless canceled or reset.\ndeadline::deadline(threadpool &pool, const asio::duration duration)\n    : duration_(duration),\n      timer_(pool.service()),\n      CONSTRUCT_TRACK(deadline)\n{\n}\n\nvoid deadline::start(handler handle)\n{\n    start(handle, duration_);\n}\n\nvoid deadline::start(handler handle, const asio::duration duration)\n{\n    const auto timer_handler =\n        std::bind(&deadline::handle_timer,\n                  shared_from_this(), _1, handle);\n\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    unique_lock lock(mutex_);\n\n    timer_.cancel();\n    timer_.expires_from_now(duration);\n\n    // async_wait will not invoke the handler within this function.\n    timer_.async_wait(timer_handler);\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n// Cancellation calls handle_timer with asio::error::operation_aborted.\n// We do not handle the cancelation result code, which will return success\n// in the case of a race in which the timer is already canceled.\n// We don't use strand because cancel must not change context.\nvoid deadline::stop()\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    unique_lock lock(mutex_);\n\n    timer_.cancel();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n// If the timer expires the callback is fired with a success code.\n// If the timer fails the callback is fired with the normalized error code.\n// If the timer is canceled no call is made.\nvoid deadline::handle_timer(const boost_code &ec, handler handle) const\n{\n    if (!ec)\n        handle(error::success);\n    else if (ec != asio::error::operation_aborted)\n        handle(error::boost_to_error_code(ec));\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/utility/dispatcher.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/utility/dispatcher.hpp>\n\n#include <string>\n#include <UChain/coin/utility/threadpool.hpp>\n#include <UChain/coin/utility/work.hpp>\n\nnamespace libbitcoin\n{\n\ndispatcher::dispatcher(threadpool &pool, const std::string &name)\n    : heap_(pool, name)\n{\n}\n\nsize_t dispatcher::ordered_backlog()\n{\n    return heap_.ordered_backlog();\n}\n\nsize_t dispatcher::unordered_backlog()\n{\n    return heap_.unordered_backlog();\n}\n\nsize_t dispatcher::concurrent_backlog()\n{\n    return heap_.concurrent_backlog();\n}\n\nsize_t dispatcher::combined_backlog()\n{\n    return heap_.combined_backlog();\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/utility/istream_reader.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/utility/istream_reader.hpp>\n\n#include <UChain/coin/constants.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/endian.hpp>\n\nnamespace libbitcoin\n{\n\nistream_reader::istream_reader(std::istream &stream)\n    : stream_(stream)\n{\n}\n\nistream_reader::operator bool() const\n{\n    return (bool)stream_;\n}\n\nbool istream_reader::operator!() const\n{\n    return !stream_;\n}\n\nbool istream_reader::is_exhausted() const\n{\n    return stream_ && (stream_.peek() == std::istream::traits_type::eof());\n}\n\nuint8_t istream_reader::read_byte()\n{\n    uint8_t result;\n    stream_.read(reinterpret_cast<char *>(&result), sizeof result);\n    return result;\n}\n\nuint16_t istream_reader::read_2_bytes_little_endian()\n{\n    return read_little_endian<uint16_t>();\n}\n\nuint32_t istream_reader::read_4_bytes_little_endian()\n{\n    return read_little_endian<uint32_t>();\n}\n\nuint64_t istream_reader::read_8_bytes_little_endian()\n{\n    return read_little_endian<uint64_t>();\n}\n\nuint64_t istream_reader::read_variable_uint_little_endian()\n{\n    const auto length = read_byte();\n    if (length < 0xfd)\n        return length;\n    else if (length == 0xfd)\n        return read_2_bytes_little_endian();\n    else if (length == 0xfe)\n        return read_4_bytes_little_endian();\n\n    // length should be 0xff\n    return read_8_bytes_little_endian();\n}\n\nuint16_t istream_reader::read_2_bytes_big_endian()\n{\n    return read_big_endian<uint16_t>();\n}\n\nuint32_t istream_reader::read_4_bytes_big_endian()\n{\n    return read_big_endian<uint32_t>();\n}\n\nuint64_t istream_reader::read_8_bytes_big_endian()\n{\n    return read_big_endian<uint64_t>();\n}\n\nuint64_t istream_reader::read_variable_uint_big_endian()\n{\n    uint8_t length = read_byte();\n\n    if (length < 0xfd)\n        return length;\n    else if (length == 0xfd)\n        return read_2_bytes_big_endian();\n    else if (length == 0xfe)\n        return read_4_bytes_big_endian();\n\n    // length should be 0xff\n    return read_8_bytes_big_endian();\n}\n\ndata_chunk istream_reader::read_data(size_t size)\n{\n    data_chunk raw_bytes(size);\n\n    if (size > 0)\n    {\n        stream_.read(reinterpret_cast<char *>(raw_bytes.data()), size);\n        auto size = stream_.gcount();\n        BITCOIN_ASSERT(static_cast<size_t>(size) <= bc::max_size_t);\n        const auto read_size = static_cast<size_t>(size);\n\n        if (static_cast<size_t>(size) != read_size)\n            //          throw std::ios_base::failure(\n            //              \"read_data failed to read requested number of bytes\");\n            raw_bytes.resize(read_size);\n    }\n\n    return raw_bytes;\n}\n\nsize_t istream_reader::read_data(uint8_t *data, size_t size)\n{\n    size_t read_size = 0;\n\n    if (size > 0)\n    {\n        stream_.read(reinterpret_cast<char *>(data), size);\n        auto size = stream_.gcount();\n        BITCOIN_ASSERT(static_cast<size_t>(size) <= bc::max_size_t);\n        read_size = static_cast<size_t>(size);\n    }\n\n    return read_size;\n}\n\ndata_chunk istream_reader::read_data_to_eof()\n{\n    data_chunk raw_bytes;\n    while (stream_ && (stream_.peek() != std::istream::traits_type::eof()))\n        raw_bytes.push_back(read_byte());\n\n    return raw_bytes;\n}\n\nhash_digest istream_reader::read_hash()\n{\n    return read_bytes<hash_size>();\n}\n\nshort_hash istream_reader::read_short_hash()\n{\n    return read_bytes<short_hash_size>();\n}\n\nmini_hash istream_reader::read_mini_hash()\n{\n    return read_bytes<mini_hash_size>();\n}\n\nstd::string istream_reader::read_fixed_string(size_t length)\n{\n    auto string_bytes = read_data(length);\n    std::string result(string_bytes.begin(), string_bytes.end());\n\n    // Removes trailing 0s... Needed for string comparisons\n    return result.c_str();\n}\n\nstd::string istream_reader::read_string()\n{\n    const auto size = read_variable_uint_little_endian();\n    BITCOIN_ASSERT(size <= bc::max_size_t);\n    const auto read_size = static_cast<size_t>(size);\n    return read_fixed_string(read_size);\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/utility/log.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/utility/log.hpp>\n\n#include <iostream>\n#include <utility>\n#include <sstream>\n#include <string>\n#include <boost/date_time.hpp>\n#include <boost/format.hpp>\n#include <UChain/coin/unicode/unicode.hpp>\n\nnamespace libbitcoin\n{\n\nlog::log(level value, const std::string &domain)\n    : level_(value), domain_(domain)\n{\n}\n\n// g++ bug in initializer list.\n// It should be: stream_(std::move(other.stream_))\n// gcc.gnu.org/bugzilla/show_bug.cgi?id=54316\nlog::log(log &&other)\n    : level_(other.level_),\n      domain_(std::move(other.domain_)),\n      stream_(other.stream_.str())\n{\n}\n\nlog::~log()\n{\n    if (destinations_.count(level_) != 0)\n        destinations_[level_](level_, domain_, stream_.str());\n}\n\nvoid log::set_output_function(functor value)\n{\n    destinations_[level_] = value;\n}\n\nvoid log::clear()\n{\n    destinations_.clear();\n}\n\nlog log::trace(const std::string &domain)\n{\n    return log(level::trace, domain);\n}\n\nlog log::debug(const std::string &domain)\n{\n    return log(level::debug, domain);\n}\n\nlog log::info(const std::string &domain)\n{\n    return log(level::info, domain);\n}\n\nlog log::warning(const std::string &domain)\n{\n    return log(level::warning, domain);\n}\n\nlog log::error(const std::string &domain)\n{\n    return log(level::error, domain);\n}\n\nlog log::fatal(const std::string &domain)\n{\n    return log(level::fatal, domain);\n}\n\nstd::string log::to_text(level value)\n{\n    switch (value)\n    {\n    case level::trace:\n        return \"TRACE\";\n    case level::debug:\n        return \"DEBUG\";\n    case level::info:\n        return \"INFO\";\n    case level::warning:\n        return \"WARNING\";\n    case level::error:\n        return \"ERROR\";\n    case level::fatal:\n        return \"FATAL\";\n    case level::null:\n        return \"NULL\";\n    default:\n        return \"\";\n    }\n}\n\nvoid log::to_stream(std::ostream &out, level value, const std::string &domain,\n                    const std::string &body)\n{\n    std::ostringstream buffer;\n    buffer << to_text(value);\n    if (!domain.empty())\n        buffer << \" [\" << domain << \"]\";\n\n    buffer << \": \" << body << std::endl;\n\n    // Buffering prevents line interleaving across threads.\n    out << buffer.str();\n    out.flush();\n}\n\nvoid log::output_ignore(level, const std::string &, const std::string &)\n{\n}\n\nvoid log::output_cout(level value, const std::string &domain,\n                      const std::string &body)\n{\n    to_stream(bc::cout, value, domain, body);\n}\n\nvoid log::output_cerr(level value, const std::string &domain,\n                      const std::string &body)\n{\n    to_stream(bc::cerr, value, domain, body);\n}\n\nlog::destinations log::destinations_{\n#ifdef NDEBUG\n    std::make_pair(level::trace, output_ignore),\n    std::make_pair(level::debug, output_ignore),\n#else\n    std::make_pair(level::trace, output_cout),\n    std::make_pair(level::debug, output_cout),\n#endif\n    std::make_pair(level::info, output_cout),\n    std::make_pair(level::warning, output_cerr),\n    std::make_pair(level::error, output_cerr),\n    std::make_pair(level::fatal, output_cerr)};\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/utility/logging.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <functional>\n#include <iostream>\n#include <utility>\n#include <sstream>\n#include <string>\n#include <type_traits>\n#include <mutex>\n#include <boost/date_time.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/network/define.hpp>\n\nnamespace libbitcoin\n{\n\n// Guard against concurrent console writes.\nstatic std::mutex console_mutex;\n\n// Guard against concurrent file writes.\nstatic std::mutex file_mutex;\n\ntemplate <class T>\n// TODO:limit template type of instance\n// class = typename std::enable_if<std::is_base_of<std::basic_ostream&, T>::value>::type>\nstatic inline void do_logging(T &ofs, log::level level, const std::string &domain,\n                              const std::string &body)\n{\n    if (body.empty())\n    {\n        return;\n    }\n\n    namespace ptime = boost::posix_time;\n\n    static const auto form = \"%1% %2% [%3%] %4%\\n\";\n    const auto message = boost::format(form) %\n                         ptime::to_iso_string(ptime::second_clock::local_time()) %\n                         log::to_text(level) %\n                         domain %\n                         body;\n\n    {\n        // Critical Section\n        ///////////////////////////////////////////////////////////////////////\n        std::unique_lock<std::mutex> lock_file(file_mutex);\n        ofs << message;\n\n        // Cut up log file if over max_size\n        if (std::is_same<T, bc::ofstream>::value)\n        {\n            bc::ofstream &bo = dynamic_cast<bc::ofstream &>(ofs);\n            auto &current_size = bo.current_size();\n            current_size += message.size();\n            if (bo.current_size() > bo.max_size())\n            {\n                bo.close();\n                bo.open(bo.path(), std::ios::trunc | std::ios::out);\n                current_size = 0;\n            }\n        }\n\n        ofs.flush();\n        ///////////////////////////////////////////////////////////////////////\n    }\n}\n\nstatic void output_ignore(bc::ofstream &file, log::level level,\n                          const std::string &domain, const std::string &body)\n{\n}\n\nstatic void output_file(bc::ofstream &file, log::level level,\n                        const std::string &domain, const std::string &body)\n{\n    do_logging(file, level, domain, body);\n}\n\nstatic void output_both(bc::ofstream &file, std::ostream &output,\n                        log::level level, const std::string &domain, const std::string &body)\n{\n    do_logging(file, level, domain, body);\n    do_logging(output, level, domain, body);\n}\n\nstatic void error_file(bc::ofstream &file, log::level level,\n                       const std::string &domain, const std::string &body)\n{\n    do_logging(file, level, domain, body);\n}\n\nstatic void error_both(bc::ofstream &file, std::ostream &error,\n                       log::level level, const std::string &domain, const std::string &body)\n{\n    do_logging(file, level, domain, body);\n    do_logging(error, level, domain, body);\n}\n\nvoid initialize_logging(bc::ofstream &debug, bc::ofstream &error,\n                        std::ostream &output_stream, std::ostream &error_stream,\n                        std::string level)\n{\n    using namespace std::placeholders;\n\n    auto debug_log_level = log::level::debug;\n    if (level == \"INFO\" || level == \"info\")\n        debug_log_level = log::level::info;\n    else if (level == \"TRACE\" || level == \"trace\")\n        debug_log_level = log::level::trace;\n\n    // setup log level for debug_log\n    if (debug_log_level < log::level::debug)\n    {\n        // trace|debug|info => debug_log\n        log::trace(\"\").set_output_function(std::bind(output_file,\n                                                     std::ref(debug), _1, _2, _3));\n        log::debug(\"\").set_output_function(std::bind(output_file,\n                                                     std::ref(debug), _1, _2, _3));\n    }\n    else if (debug_log_level < log::level::info)\n    {\n        log::trace(\"\").set_output_function(std::bind(output_ignore,\n                                                     std::ref(debug), _1, _2, _3));\n        // debug|info => debug_log\n        log::debug(\"\").set_output_function(std::bind(output_file,\n                                                     std::ref(debug), _1, _2, _3));\n    }\n    else if (debug_log_level < log::level::warning)\n    {\n        // info => debug_log\n        log::trace(\"\").set_output_function(std::bind(output_ignore,\n                                                     std::ref(debug), _1, _2, _3));\n        log::debug(\"\").set_output_function(std::bind(output_ignore,\n                                                     std::ref(debug), _1, _2, _3));\n    }\n\n    // info => debug_log + console\n    log::info(\"\").set_output_function(std::bind(output_both,\n                                                std::ref(debug), std::ref(output_stream), _1, _2, _3));\n    // warning|error|fatal => error_log + console\n    log::warning(\"\").set_output_function(std::bind(error_file,\n                                                   std::ref(error), _1, _2, _3));\n    log::error(\"\").set_output_function(std::bind(error_both,\n                                                 std::ref(error), std::ref(error_stream), _1, _2, _3));\n    log::fatal(\"\").set_output_function(std::bind(error_both,\n                                                 std::ref(error), std::ref(error_stream), _1, _2, _3));\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/utility/monitor.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/utility/monitor.hpp>\n\n#include <cstddef>\n#include <string>\n#include <UChain/coin/utility/log.hpp>\n\nnamespace libbitcoin\n{\n\nmonitor::monitor(count_ptr counter, const std::string &name)\n    : counter_(counter), name_(name)\n{\n    trace(++(*counter_), \"+\");\n}\n\nmonitor::~monitor()\n{\n    trace(--(*counter_), \"-\");\n}\n\nvoid monitor::trace(size_t count, const std::string &action) const\n{\n#ifndef NDEBUG\n    ////log::debug(LOG_SYSTEM) << action << \" \" << name_ << \" {\" << count << \"}\";\n#endif\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/utility/ostream_writer.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\n\nostream_writer::ostream_writer(std::ostream &stream)\n    : stream_(stream)\n{\n}\n\nostream_writer::operator bool() const\n{\n    return (bool)stream_;\n}\n\nbool ostream_writer::operator!() const\n{\n    return !stream_;\n}\n\nvoid ostream_writer::write_byte(uint8_t value)\n{\n    stream_.put(value);\n}\n\nvoid ostream_writer::write_2_bytes_little_endian(uint16_t value)\n{\n    write_little_endian<uint16_t>(value);\n}\n\nvoid ostream_writer::write_4_bytes_little_endian(uint32_t value)\n{\n    write_little_endian<uint32_t>(value);\n}\n\nvoid ostream_writer::write_8_bytes_little_endian(uint64_t value)\n{\n    write_little_endian<uint64_t>(value);\n}\n\nvoid ostream_writer::write_variable_uint_little_endian(uint64_t value)\n{\n    if (value < 0xfd)\n    {\n        write_byte((uint8_t)value);\n    }\n    else if (value <= 0xffff)\n    {\n        write_byte(0xfd);\n        write_2_bytes_little_endian((uint16_t)value);\n    }\n    else if (value <= 0xffffffff)\n    {\n        write_byte(0xfe);\n        write_4_bytes_little_endian((uint32_t)value);\n    }\n    else\n    {\n        write_byte(0xff);\n        write_8_bytes_little_endian(value);\n    }\n}\n\nvoid ostream_writer::write_2_bytes_big_endian(uint16_t value)\n{\n    write_big_endian<uint16_t>(value);\n}\n\nvoid ostream_writer::write_4_bytes_big_endian(uint32_t value)\n{\n    write_big_endian<uint32_t>(value);\n}\n\nvoid ostream_writer::write_8_bytes_big_endian(uint64_t value)\n{\n    write_big_endian<uint64_t>(value);\n}\n\nvoid ostream_writer::write_variable_uint_big_endian(uint64_t value)\n{\n    if (value < 0xfd)\n    {\n        write_byte((uint8_t)value);\n    }\n    else if (value <= 0xffff)\n    {\n        write_byte(0xfd);\n        write_2_bytes_big_endian((uint16_t)value);\n    }\n    else if (value <= 0xffffffff)\n    {\n        write_byte(0xfe);\n        write_4_bytes_big_endian((uint32_t)value);\n    }\n    else\n    {\n        write_byte(0xff);\n        write_8_bytes_big_endian(value);\n    }\n}\n\nvoid ostream_writer::write_data(const data_chunk &data)\n{\n    write_data<const data_chunk>(data);\n}\n\nvoid ostream_writer::write_data(const uint8_t *data, size_t size)\n{\n    stream_.write(reinterpret_cast<const char *>(data), size);\n}\n\nvoid ostream_writer::write_hash(const hash_digest &value)\n{\n    stream_.write(reinterpret_cast<const char *>(value.data()), value.size());\n}\n\nvoid ostream_writer::write_short_hash(const short_hash &value)\n{\n    stream_.write(reinterpret_cast<const char *>(value.data()), value.size());\n}\n\nvoid ostream_writer::write_mini_hash(const mini_hash &value)\n{\n    stream_.write(reinterpret_cast<const char *>(value.data()), value.size());\n}\n\nvoid ostream_writer::write_fixed_string(const std::string &value, size_t size)\n{\n    const auto min_size = std::min(size, value.size());\n    data_chunk raw_string(size, 0);\n    std::copy_n(value.begin(), min_size, raw_string.begin());\n    write_data(raw_string);\n}\n\nvoid ostream_writer::write_string(const std::string &value)\n{\n    write_variable_uint_little_endian(value.size());\n    stream_.write(value.data(), value.size());\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/utility/png.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/utility/png.hpp>\n\n#include <cstddef>\n#include <cstdint>\n#include <iostream>\n#include <stdexcept>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/constants.hpp>\n#include <UChain/coin/formats/base_16.hpp>\n#include <UChain/coin/utility/color.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\n\n#ifdef WITH_PNG\n\nbool png::write_png(const data_chunk &data, uint32_t size, std::ostream &out)\n{\n    data_source istream(data);\n    return png::write_png(istream, size, out);\n}\n\nbool png::write_png(const data_chunk &data, uint32_t size,\n                    uint32_t dots_per_inch, uint32_t margin, uint32_t inches_per_meter,\n                    const color &foreground, const color &background, std::ostream &out)\n{\n    data_source istream(data);\n    return png::write_png(istream, size, dots_per_inch, margin,\n                          inches_per_meter, get_default_foreground(), get_default_background(),\n                          out);\n}\n\nbool png::write_png(std::istream &in, uint32_t size, std::ostream &out)\n{\n    return png::write_png(in, size, dots_per_inch, margin, inches_per_meter,\n                          get_default_foreground(), get_default_background(), out);\n}\n\nextern \"C\" void sink_write(png_structp png_ptr, png_bytep data,\n                           png_size_t length)\n{\n    static_assert(sizeof(length) <= sizeof(size_t), \"png_size_t too large\");\n    const auto size = static_cast<size_t>(length);\n\n    auto &sink = *reinterpret_cast<ostream_writer *>(png_get_io_ptr(png_ptr));\n    sink.write_data(reinterpret_cast<const uint8_t *>(data), size);\n}\n\nextern \"C\" void error_callback(png_structp png_ptr,\n                               png_const_charp error_message)\n{\n    throw std::runtime_error(error_message);\n}\n\nbool png::write_png(std::istream &in, uint32_t size, uint32_t dots_per_inch,\n                    uint32_t margin, uint32_t inches_per_meter, const color &foreground,\n                    const color &background, std::ostream &out)\n{\n    if (size == 0)\n        return false;\n\n    uint32_t version, width;\n    istream_reader source(in);\n    source.read_data(reinterpret_cast<uint8_t *>(&version), sizeof(uint32_t));\n    source.read_data(reinterpret_cast<uint8_t *>(&width), sizeof(uint32_t));\n\n    if (bc::max_size_t / width < width)\n        return false;\n\n    const auto area = width * width;\n    auto data = source.read_data(area);\n\n    try\n    {\n        static constexpr int32_t bit_depth = 1;\n        static constexpr int32_t bits_per_byte = 8;\n        static constexpr uint8_t margin_value = 0xff;\n\n        // TODO: unguarded overflow conditions.\n        const auto margin_size = margin * size;\n        const auto realwidth = (width + margin * 2) * size;\n        const auto row_size = (realwidth + 7) / bits_per_byte;\n\n        data_chunk row;\n        row.reserve(row_size);\n\n        auto png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr,\n                                               nullptr, nullptr);\n        if (png_ptr == nullptr)\n            return false;\n\n        auto info_ptr = png_create_info_struct(png_ptr);\n        if (info_ptr == nullptr)\n            return false;\n\n        png_color raw_palette;\n        auto palette = &raw_palette;\n        palette[0].red = foreground.red;\n        palette[0].green = foreground.green;\n        palette[0].blue = foreground.blue;\n        palette[1].red = background.red;\n        palette[1].green = background.green;\n        palette[1].blue = background.blue;\n\n        png_byte alpha_values[2];\n        alpha_values[0] = foreground.alpha;\n        alpha_values[1] = background.alpha;\n\n        png_set_PLTE(png_ptr, info_ptr, palette, 2);\n        png_set_tRNS(png_ptr, info_ptr, alpha_values, 2, nullptr);\n\n        ostream_writer sink(out);\n        png_set_write_fn(png_ptr, &sink, sink_write, nullptr);\n        png_set_error_fn(png_ptr, nullptr, error_callback, nullptr);\n\n        png_set_IHDR(png_ptr, info_ptr, realwidth, realwidth, bit_depth,\n                     PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,\n                     PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);\n\n        png_set_pHYs(png_ptr, info_ptr, dots_per_inch * inches_per_meter,\n                     dots_per_inch * inches_per_meter, PNG_RESOLUTION_METER);\n\n        png_write_info(png_ptr, info_ptr);\n\n        // write top margin\n        row.assign(row_size, margin_value);\n        for (auto y = 0; y < margin_size; y++)\n            png_write_row(png_ptr, row.data());\n\n        // write data\n        uint8_t *row_ptr = nullptr;\n        auto data_ptr = data.data();\n        for (auto y = 0; y < width; y++)\n        {\n            // TODO: unguarded overflow conditions.\n            auto bit = bits_per_byte - 1;\n            row.assign(row_size, margin_value);\n            row_ptr = row.data();\n            row_ptr += margin_size / bits_per_byte;\n            bit = (bits_per_byte - 1) - (margin_size % bits_per_byte);\n\n            for (auto x = 0; x < width; x++)\n            {\n                for (auto xx = 0; xx < size; xx++)\n                {\n                    *row_ptr ^= (*data_ptr & 1) << bit;\n                    bit--;\n                    if (bit < 0)\n                    {\n                        row_ptr++;\n                        bit = bits_per_byte - 1;\n                    }\n                }\n\n                data_ptr++;\n            }\n\n            for (auto yy = 0; yy < size; yy++)\n                png_write_row(png_ptr, row.data());\n        }\n\n        // write bottom margin\n        row.assign(row_size, margin_value);\n        for (auto y = 0; y < margin_size; y++)\n            png_write_row(png_ptr, row.data());\n\n        png_write_end(png_ptr, info_ptr);\n        png_destroy_write_struct(&png_ptr, &info_ptr);\n\n        out.flush();\n    }\n    catch (const std::runtime_error &error)\n    {\n        return false;\n    }\n\n    return true;\n}\n\n#endif\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/utility/random.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/utility/random.hpp>\n\n//#include <chrono>\n#include <cstdint>\n#include <stdexcept>\n#ifdef __MINGW32__\n#include <boost/random/random_device.hpp>\n#else\n#include <random>\n#endif\n#include <UChain/coin/utility/asio.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\n\n// DO NOT USE srand() and rand() on MSVC as srand must be called per thread.\n// As a result it is difficult to use safely.\n\n// Not fully testable due to lack of random engine injection.\n// This may be truly random depending on the underlying device.\nuint64_t pseudo_random()\n{\n#ifdef __MINGW32__\n    boost::random_device device;\n#else\n    std::random_device device;\n#endif\n    std::uniform_int_distribution<uint64_t> distribution;\n    return distribution(device);\n}\n\n// Not fully testable due to lack of random engine injection.\n// This may be truly random depending on the underlying device.\nuint64_t nonzero_pseudo_random()\n{\n    for (auto index = 0; index < 100; ++index)\n    {\n        const auto value = pseudo_random();\n        if (value > 0)\n            return value;\n    }\n\n    // If above doesn't return something is seriously wrong with the RNG.\n    throw std::runtime_error(\"The RNG produces 100 consecutive zero values.\");\n}\n\n// Not fully testable due to lack of random engine injection.\n// This may be truly random depending on the underlying device.\nvoid pseudo_random_fill(data_chunk &chunk)\n{\n#ifdef __MINGW32__\n    boost::random_device device;\n#else\n    std::random_device device;\n#endif\n    std::uniform_int_distribution<uint16_t> distribution;\n    for (uint8_t &byte : chunk)\n    {\n        // uniform_int_distribution is undefined for sizes < 16 bits,\n        // so we generate a 16 bit value and reduce it to 8 bits.\n        byte = distribution(device) % std::numeric_limits<uint8_t>::max();\n    }\n}\n\n// Randomly select a time duration in the range:\n// [(expiration - expiration / ratio) .. expiration]\n// Not fully testable due to lack of random engine injection.\nasio::duration pseudo_randomize(const asio::duration &expiration, uint8_t ratio)\n{\n    if (ratio == 0)\n        return expiration;\n\n    // Uses milliseconds level resolution.\n    const auto max_expire = std::chrono::duration_cast<asio::milliseconds>(\n                                expiration)\n                                .count();\n\n    // [10 secs, 4] => 10000 / 4 => 2500\n    const auto divisor = max_expire / ratio;\n\n    if (divisor == 0)\n        return expiration;\n\n    // [0..2^64) % 2500 => [0..2500]\n    const auto random_offset = static_cast<int>(bc::pseudo_random() % divisor);\n\n    // (10000 - [0..2500]) => [7500..10000]\n    const auto expires = max_expire - random_offset;\n\n    // [7.5..10] second duration.\n    return asio::milliseconds(expires);\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/utility/resource_lock.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/utility/resource_lock.hpp>\n\n#include <boost/filesystem.hpp>\n#include <boost/interprocess/exceptions.hpp>\n#include <UChain/coin/unicode/ifstream.hpp>\n#include <UChain/coin/unicode/ofstream.hpp>\n#include <UChain/coin/utility/assert.hpp>\n\nnamespace libbitcoin\n{\n\nstatic void touch_file(const resource_lock::file_path &path)\n{\n    bc::ofstream file(path.string(), std::ofstream::app);\n    file.close();\n}\n\nresource_lock::resource_lock(const file_path &lock_path)\n    : lock_path_(lock_path)\n{\n}\n\nbool resource_lock::lock()\n{\n    // If file exists then lock is already acquired.\n    if (boost::filesystem::exists(lock_path_))\n    {\n        return false;\n    }\n\n    // Touch the lock file to ensure its existence.\n    touch_file(lock_path_);\n\n    // BOOST:\n    // Opens a file lock. Throws interprocess_exception if the file does not\n    // exist or there are no operating system resources. The file lock is\n    // destroyed on its destruct and does not throw.\n    try\n    {\n        lock_ = std::make_shared<boost_file_lock>(lock_path_.string().c_str());\n        return lock_->try_lock();\n    }\n    catch (const boost::interprocess::interprocess_exception &)\n    {\n        lock_ = nullptr;\n        return false;\n    }\n\n    // Should not arrive here!\n    BITCOIN_ASSERT_MSG(false, \"Reached unreachable code path.\");\n    return false;\n}\nbool resource_lock::unlock()\n{\n    boost::system::error_code ec;\n    boost::filesystem::remove(lock_path_, ec);\n    return !ec;\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/utility/scope_lock.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/utility/scope_lock.hpp>\n\n#include <memory>\n#include <UChain/coin/utility/thread.hpp>\n\nnamespace libbitcoin\n{\n\nscope_lock::scope_lock(shared_mutex &mutex)\n    : mutex_(mutex)\n{\n  mutex_.lock();\n}\n\nscope_lock::~scope_lock()\n{\n  mutex_.unlock();\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/utility/string.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/utility/string.hpp>\n\n#include <string>\n#include <vector>\n#include <boost/algorithm/string.hpp>\n\nnamespace libbitcoin\n{\n\nstd::string join(const std::vector<std::string> &words,\n                 const std::string &delimiter)\n{\n    return boost::join(words, delimiter);\n}\n\n// Note that use of token_compress_on may cause unexpected results when\n// working with CSV-style lists that accept empty elements.\nstd::vector<std::string> split(const std::string &sentence,\n                               const std::string &delimiter, bool trim)\n{\n    std::vector<std::string> words;\n    const auto compress = boost::token_compress_on;\n    const auto delimit = boost::is_any_of(delimiter);\n\n    if (trim)\n    {\n        const auto trimmed = boost::trim_copy(sentence);\n        boost::split(words, trimmed, delimit, compress);\n    }\n    else\n        boost::split(words, sentence, delimit, compress);\n\n    return words;\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/utility/thread.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/utility/thread.hpp>\n\n#include <stdexcept>\n\n#ifdef _WIN32\n#include <windows.h>\n#else\n#include <unistd.h>\n#include <pthread.h>\n#include <sys/resource.h>\n#include <sys/types.h>\n#ifndef PRIO_MAX\n#define PRIO_MAX 20\n#endif\n#define THREAD_PRIORITY_ABOVE_NORMAL (-2)\n#define THREAD_PRIORITY_NORMAL 0\n#define THREAD_PRIORITY_BELOW_NORMAL 2\n#define THREAD_PRIORITY_LOWEST PRIO_MAX\n#endif\n\nnamespace libbitcoin\n{\n\n// Privately map the class enum thread priority value to an interger.\nstatic int get_thread_priority(thread_priority priority)\n{\n    switch (priority)\n    {\n    case thread_priority::high:\n        return THREAD_PRIORITY_ABOVE_NORMAL;\n    case thread_priority::normal:\n        return THREAD_PRIORITY_NORMAL;\n    case thread_priority::low:\n        return THREAD_PRIORITY_BELOW_NORMAL;\n    case thread_priority::lowest:\n        return THREAD_PRIORITY_LOWEST;\n    default:\n        throw std::invalid_argument(\"priority\");\n    }\n}\n\n// Set the thread priority (or process if thread priority is not avaliable).\nvoid set_thread_priority(thread_priority priority)\n{\n    const auto prioritization = get_thread_priority(priority);\n\n#if defined(_WIN32)\n    SetThreadPriority(GetCurrentThread(), prioritization);\n#elif defined(PRIO_THREAD)\n    sucnriority(PRIO_THREAD, pthread_self(), prioritization);\n#else\n    setpriority(PRIO_PROCESS, getpid(), prioritization);\n#endif\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/utility/threadpool.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/utility/threadpool.hpp>\n\n#include <memory>\n#include <new>\n#include <thread>\n#include <UChain/coin/utility/asio.hpp>\n#include <UChain/coin/utility/thread.hpp>\n\nnamespace libbitcoin\n{\n\nthreadpool::threadpool(size_t number_threads, thread_priority priority)\n{\n    spawn(number_threads, priority);\n}\n\nthreadpool::~threadpool()\n{\n    shutdown();\n    join();\n}\n\nvoid threadpool::spawn(size_t number_threads, thread_priority priority)\n{\n    for (size_t i = 0; i < number_threads; ++i)\n        spawn_once(priority);\n}\n\nvoid threadpool::spawn_once(thread_priority priority)\n{\n    // In C++14 work should use a unique_ptr.\n    // Work prevents the service from running out of work and terminating.\n    if (!work_)\n        work_ = std::make_shared<asio::service::work>(service_);\n\n    const auto action = [this, priority] {\n        set_thread_priority(priority);\n        service_.run();\n    };\n\n    threads_.push_back(asio::thread(action));\n}\n\nvoid threadpool::abort()\n{\n    service_.stop();\n}\n\nvoid threadpool::shutdown()\n{\n    work_ = nullptr;\n}\n\nvoid threadpool::join()\n{\n    for (auto &thread : threads_)\n        if (thread.joinable())\n            thread.join();\n\n    // This allows the pool to be cleanly restarted by calling spawn.\n    threads_.clear();\n    service_.reset();\n}\n\nasio::service &threadpool::service()\n{\n    return service_;\n}\n\nconst asio::service &threadpool::service() const\n{\n    return service_;\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/utility/time.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/utility/time.hpp>\n#include <chrono>\n\nnamespace libbitcoin\n{ //namespace libbitcoin\n\nint64_t unix_millisecond()\n{\n    using namespace std::chrono;\n    auto ms = duration_cast<milliseconds>(\n        system_clock::now().time_since_epoch());\n    return ms.count();\n}\n\n} //namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/utility/variable_uint_size.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/utility/variable_uint_size.hpp>\n\nnamespace libbitcoin\n{\n\nsize_t variable_uint_size(uint64_t value)\n{\n    if (value < 0xfd)\n        return 1;\n    else if (value <= 0xffff)\n        return 3;\n    else if (value <= 0xffffffff)\n        return 5;\n    else\n        return 9;\n}\n\nsize_t variable_string_size(const std::string &str)\n{\n    size_t length = str.size();\n    length += variable_uint_size(length);\n    return length;\n}\n\nstd::string limit_size_string(const std::string &str, size_t limit_size)\n{\n    if (str.size() > limit_size)\n    {\n        return str.substr(0, limit_size);\n    }\n\n    return str;\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/utility/work.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/utility/work.hpp>\n\n#include <memory>\n#include <string>\n#include <UChain/coin/utility/delegates.hpp>\n#include <UChain/coin/utility/threadpool.hpp>\n\nnamespace libbitcoin\n{\n\nwork::work(threadpool &pool, const std::string &name)\n    : ordered_(std::make_shared<monitor::count>(0)),\n      unordered_(std::make_shared<monitor::count>(0)),\n      concurrent_(std::make_shared<monitor::count>(0)),\n      service_(pool.service()),\n      strand_(service_),\n      name_(name)\n{\n}\n\nsize_t work::ordered_backlog()\n{\n    return ordered_->load();\n}\n\nsize_t work::unordered_backlog()\n{\n    return unordered_->load();\n}\n\nsize_t work::concurrent_backlog()\n{\n    return concurrent_->load();\n}\n\nsize_t work::combined_backlog()\n{\n    return ordered_backlog() + unordered_backlog() + concurrent_backlog();\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/wallet/bitcoin_uri.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/wallet/bitcoin_uri.hpp>\n\n#include <cstddef>\n#include <cstdint>\n#include <iostream>\n#include <map>\n#include <boost/program_options.hpp>\n#include <UChain/coin/formats/base_10.hpp>\n#include <UChain/coin/wallet/payment_address.hpp>\n#include <UChain/coin/wallet/stealth_address.hpp>\n#include <UChain/coin/wallet/uri.hpp>\n#include <UChain/coin/wallet/uri_reader.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\nstatic const auto bitcoin_scheme = \"bitcoin\";\nstatic const auto parameter_amount = \"amount\";\nstatic const auto parameter_label = \"label\";\nstatic const auto parameter_message = \"message\";\nstatic const auto parameter_r = \"r\";\nstatic const auto parameter_req_ = \"req-\";\nstatic constexpr size_t parameter_req_length = 4;\n\nbitcoin_uri::bitcoin_uri()\n    : strict_(true)\n{\n}\n\nbitcoin_uri::bitcoin_uri(const bitcoin_uri &other)\n    : strict_(other.strict_), scheme_(other.scheme_), address_(other.address_),\n      query_(other.query_)\n{\n}\n\nbitcoin_uri::bitcoin_uri(const std::string &uri, bool strict)\n    : bitcoin_uri(uri_reader::parse<bitcoin_uri>(uri, strict))\n{\n}\n\n// Cast operators.\n// ----------------------------------------------------------------------------\n\nbitcoin_uri::operator const bool() const\n{\n    // An uninitialized URI returns false.\n    return !address_.empty() || !query_.empty() || !scheme_.empty();\n}\n\n// Serializer.\n// ----------------------------------------------------------------------------\n\nstd::string bitcoin_uri::encoded() const\n{\n    // Bitcoin URIs don't use the authority or fragment components.\n    uri out;\n    out.set_scheme(bitcoin_scheme);\n    out.set_path(address_);\n    out.encode_query(query_);\n    return out.encoded();\n}\n\n// Property getters.\n// ----------------------------------------------------------------------------\n\nuint64_t bitcoin_uri::amount() const\n{\n    uint64_t satoshis;\n    decode_base10(satoshis, parameter(parameter_amount), btc_decimal_places);\n    return satoshis;\n}\n\nstd::string bitcoin_uri::label() const\n{\n    return parameter(parameter_label);\n}\n\nstd::string bitcoin_uri::message() const\n{\n    return parameter(parameter_message);\n}\n\nstd::string bitcoin_uri::r() const\n{\n    return parameter(parameter_r);\n}\n\npayment_address bitcoin_uri::payment() const\n{\n    return payment_address(address_);\n}\n\nstealth_address bitcoin_uri::stealth() const\n{\n    return stealth_address(address_);\n}\n\nstd::string bitcoin_uri::parameter(const std::string &key) const\n{\n    const auto value = query_.find(key);\n    return value == query_.end() ? std::string() : value->second;\n}\n\nstd::string bitcoin_uri::address() const\n{\n    return address_;\n}\n\n// Property setters.\n// ----------------------------------------------------------------------------\n\nvoid bitcoin_uri::set_amount(uint64_t satoshis)\n{\n    const auto amount = encode_base10(satoshis, btc_decimal_places);\n    query_[parameter_amount] = amount;\n}\n\nvoid bitcoin_uri::set_label(const std::string &label)\n{\n    query_[parameter_label] = label;\n}\n\nvoid bitcoin_uri::set_message(const std::string &message)\n{\n    query_[parameter_message] = message;\n}\n\nvoid bitcoin_uri::set_r(const std::string &r)\n{\n    query_[parameter_r] = r;\n}\n\nbool bitcoin_uri::set_address(const std::string &address)\n{\n    payment_address payment(address);\n    if (payment)\n    {\n        address_ = address;\n        return true;\n    }\n\n    stealth_address stealth(address);\n    if (stealth)\n    {\n        address_ = address;\n        return true;\n    }\n\n    return false;\n}\n\nvoid bitcoin_uri::set_address(const payment_address &payment)\n{\n    address_ = payment.encoded();\n}\n\nvoid bitcoin_uri::set_address(const stealth_address &stealth)\n{\n    address_ = stealth.encoded();\n}\n\nbool bitcoin_uri::set_amount(const std::string &satoshis)\n{\n    uint64_t decoded;\n    if (!decode_base10(decoded, satoshis, btc_decimal_places, strict_))\n        return false;\n\n    // Normalize the encoding for string-based getter (parameter).\n    set_amount(decoded);\n    return true;\n}\n\n// uri_reader implementation.\n// ----------------------------------------------------------------------------\n\nvoid bitcoin_uri::set_strict(bool strict)\n{\n    strict_ = strict;\n}\n\nbool bitcoin_uri::set_scheme(const std::string &scheme)\n{\n    if (scheme == bitcoin_scheme)\n    {\n        scheme_ = scheme;\n        return true;\n    }\n\n    return false;\n}\n\nbool bitcoin_uri::set_authority(const std::string &authority)\n{\n    // Using \"bitcoin://\" instead of \"bitcoin:\" is a common mistake, so we\n    // allow the authority in place of the path when not strict.\n    return !strict_ && set_path(authority);\n}\n\nbool bitcoin_uri::set_path(const std::string &path)\n{\n    // Guard against the path having been set via authority (or second set).\n    return address_.empty() && set_address(path);\n}\n\nbool bitcoin_uri::set_fragment(const std::string &fragment)\n{\n    return false;\n}\n\nbool bitcoin_uri::set_parameter(const std::string &key,\n                                const std::string &value)\n{\n    const auto required = [](const std::string &key) {\n        return key.substr(0, parameter_req_length) == parameter_req_;\n    };\n\n    if (key == parameter_amount)\n        return set_amount(value);\n\n    if (key == parameter_label)\n        set_label(value);\n    else if (key == parameter_message)\n        set_message(value);\n    else if (key == parameter_r)\n        set_r(value);\n\n    // Fail on any required parameter that we don't support.\n    return !required(key);\n}\n\n// Operators.\n// ----------------------------------------------------------------------------\n\nbitcoin_uri &bitcoin_uri::operator=(const bitcoin_uri &other)\n{\n    strict_ = other.strict_;\n    scheme_ = other.scheme_;\n    address_ = other.address_;\n    query_ = other.query_;\n    return *this;\n}\n\nbool bitcoin_uri::operator<(const bitcoin_uri &other) const\n{\n    return encoded() < other.encoded();\n}\n\nbool bitcoin_uri::operator==(const bitcoin_uri &other) const\n{\n    return strict_ == other.strict_ && scheme_ == other.scheme_ &&\n           address_ == other.address_ && query_ == other.query_;\n}\n\nbool bitcoin_uri::operator!=(const bitcoin_uri &other) const\n{\n    return !(*this == other);\n}\n\n// This is always strict.\nstd::istream &operator>>(std::istream &in, bitcoin_uri &to)\n{\n    std::string value;\n    in >> value;\n    to = bitcoin_uri(value);\n\n    if (!to)\n    {\n        using namespace boost::program_options;\n        BOOST_THROW_EXCEPTION(invalid_option_value(value));\n    }\n\n    return in;\n}\n\nstd::ostream &operator<<(std::ostream &out, const bitcoin_uri &from)\n{\n    out << from.encoded();\n    return out;\n}\n\n} // namespace wallet\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/wallet/dictionary.cpp",
    "content": "﻿/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/wallet/dictionary.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\nnamespace language\n{\n\nconst dictionary en =\n    {\n        {\"abandon\",\n         \"ability\",\n         \"able\",\n         \"about\",\n         \"above\",\n         \"absent\",\n         \"absorb\",\n         \"abstract\",\n         \"absurd\",\n         \"abuse\",\n         \"access\",\n         \"accident\",\n         \"account\",\n         \"accuse\",\n         \"achieve\",\n         \"acid\",\n         \"acoustic\",\n         \"acquire\",\n         \"across\",\n         \"act\",\n         \"action\",\n         \"actor\",\n         \"actress\",\n         \"actual\",\n         \"adapt\",\n         \"add\",\n         \"addict\",\n         \"address\",\n         \"adjust\",\n         \"admit\",\n         \"adult\",\n         \"advance\",\n         \"advice\",\n         \"aerobic\",\n         \"affair\",\n         \"afford\",\n         \"afraid\",\n         \"again\",\n         \"age\",\n         \"agent\",\n         \"agree\",\n         \"ahead\",\n         \"aim\",\n         \"air\",\n         \"airport\",\n         \"aisle\",\n         \"alarm\",\n         \"album\",\n         \"alcohol\",\n         \"alert\",\n         \"alien\",\n         \"all\",\n         \"alley\",\n         \"allow\",\n         \"almost\",\n         \"alone\",\n         \"alpha\",\n         \"already\",\n         \"also\",\n         \"alter\",\n         \"always\",\n         \"amateur\",\n         \"amazing\",\n         \"among\",\n         \"amount\",\n         \"amused\",\n         \"analyst\",\n         \"anchor\",\n         \"ancient\",\n         \"anger\",\n         \"angle\",\n         \"angry\",\n         \"animal\",\n         \"ankle\",\n         \"announce\",\n         \"annual\",\n         \"another\",\n         \"answer\",\n         \"antenna\",\n         \"antique\",\n         \"anxiety\",\n         \"any\",\n         \"apart\",\n         \"apology\",\n         \"appear\",\n         \"apple\",\n         \"approve\",\n         \"april\",\n         \"arch\",\n         \"arctic\",\n         \"area\",\n         \"arena\",\n         \"argue\",\n         \"arm\",\n         \"armed\",\n         \"armor\",\n         \"army\",\n         \"around\",\n         \"arrange\",\n         \"arrest\",\n         \"arrive\",\n         \"arrow\",\n         \"art\",\n         \"artefact\",\n         \"artist\",\n         \"artwork\",\n         \"ask\",\n         \"aspect\",\n         \"assault\",\n         \"token\",\n         \"assist\",\n         \"assume\",\n         \"asthma\",\n         \"athlete\",\n         \"atom\",\n         \"attack\",\n         \"attend\",\n         \"attitude\",\n         \"attract\",\n         \"auction\",\n         \"audit\",\n         \"august\",\n         \"aunt\",\n         \"author\",\n         \"auto\",\n         \"autumn\",\n         \"average\",\n         \"avocado\",\n         \"avoid\",\n         \"awake\",\n         \"aware\",\n         \"away\",\n         \"awesome\",\n         \"awful\",\n         \"awkward\",\n         \"axis\",\n         \"baby\",\n         \"bachelor\",\n         \"bacon\",\n         \"badge\",\n         \"bag\",\n         \"balance\",\n         \"balcony\",\n         \"ball\",\n         \"bamboo\",\n         \"banana\",\n         \"banner\",\n         \"bar\",\n         \"barely\",\n         \"bargain\",\n         \"barrel\",\n         \"base\",\n         \"basic\",\n         \"basket\",\n         \"battle\",\n         \"beach\",\n         \"bean\",\n         \"beauty\",\n         \"because\",\n         \"become\",\n         \"beef\",\n         \"before\",\n         \"begin\",\n         \"behave\",\n         \"behind\",\n         \"believe\",\n         \"below\",\n         \"belt\",\n         \"bench\",\n         \"benefit\",\n         \"best\",\n         \"betray\",\n         \"better\",\n         \"between\",\n         \"beyond\",\n         \"bicycle\",\n         \"bid\",\n         \"bike\",\n         \"bind\",\n         \"biology\",\n         \"bird\",\n         \"birth\",\n         \"bitter\",\n         \"black\",\n         \"blade\",\n         \"blame\",\n         \"blanket\",\n         \"blast\",\n         \"bleak\",\n         \"bless\",\n         \"blind\",\n         \"blood\",\n         \"blossom\",\n         \"blouse\",\n         \"blue\",\n         \"blur\",\n         \"blush\",\n         \"board\",\n         \"boat\",\n         \"body\",\n         \"boil\",\n         \"bomb\",\n         \"bone\",\n         \"bonus\",\n         \"book\",\n         \"boost\",\n         \"border\",\n         \"boring\",\n         \"borrow\",\n         \"boss\",\n         \"bottom\",\n         \"bounce\",\n         \"box\",\n         \"boy\",\n         \"bracket\",\n         \"brain\",\n         \"brand\",\n         \"brass\",\n         \"brave\",\n         \"bread\",\n         \"breeze\",\n         \"brick\",\n         \"bridge\",\n         \"brief\",\n         \"bright\",\n         \"bring\",\n         \"brisk\",\n         \"broccoli\",\n         \"broken\",\n         \"bronze\",\n         \"broom\",\n         \"brother\",\n         \"brown\",\n         \"brush\",\n         \"bubble\",\n         \"buddy\",\n         \"budget\",\n         \"buffalo\",\n         \"build\",\n         \"bulb\",\n         \"bulk\",\n         \"bullet\",\n         \"bundle\",\n         \"bunker\",\n         \"burden\",\n         \"burger\",\n         \"burst\",\n         \"bus\",\n         \"business\",\n         \"busy\",\n         \"butter\",\n         \"buyer\",\n         \"buzz\",\n         \"cabbage\",\n         \"cabin\",\n         \"cable\",\n         \"cactus\",\n         \"cage\",\n         \"cake\",\n         \"call\",\n         \"calm\",\n         \"camera\",\n         \"camp\",\n         \"can\",\n         \"canal\",\n         \"cancel\",\n         \"candy\",\n         \"cannon\",\n         \"canoe\",\n         \"canvas\",\n         \"canyon\",\n         \"capable\",\n         \"capital\",\n         \"captain\",\n         \"car\",\n         \"carbon\",\n         \"candidate\",\n         \"cargo\",\n         \"carpet\",\n         \"carry\",\n         \"cart\",\n         \"case\",\n         \"cash\",\n         \"casino\",\n         \"castle\",\n         \"casual\",\n         \"cat\",\n         \"catalog\",\n         \"catch\",\n         \"category\",\n         \"cattle\",\n         \"caught\",\n         \"cause\",\n         \"caution\",\n         \"cave\",\n         \"ceiling\",\n         \"celery\",\n         \"cement\",\n         \"census\",\n         \"century\",\n         \"cereal\",\n         \"certain\",\n         \"chair\",\n         \"chalk\",\n         \"champion\",\n         \"change\",\n         \"chaos\",\n         \"chapter\",\n         \"charge\",\n         \"chase\",\n         \"chat\",\n         \"cheap\",\n         \"check\",\n         \"cheese\",\n         \"chef\",\n         \"cherry\",\n         \"chest\",\n         \"chicken\",\n         \"chief\",\n         \"child\",\n         \"chimney\",\n         \"choice\",\n         \"choose\",\n         \"chronic\",\n         \"chuckle\",\n         \"chunk\",\n         \"churn\",\n         \"cigar\",\n         \"cinnamon\",\n         \"circle\",\n         \"citizen\",\n         \"city\",\n         \"civil\",\n         \"claim\",\n         \"clap\",\n         \"clarify\",\n         \"claw\",\n         \"clay\",\n         \"clean\",\n         \"clerk\",\n         \"clever\",\n         \"click\",\n         \"client\",\n         \"cliff\",\n         \"climb\",\n         \"clinic\",\n         \"clip\",\n         \"clock\",\n         \"clog\",\n         \"close\",\n         \"cloth\",\n         \"cloud\",\n         \"clown\",\n         \"club\",\n         \"clump\",\n         \"cluster\",\n         \"clutch\",\n         \"coach\",\n         \"coast\",\n         \"coconut\",\n         \"code\",\n         \"coffee\",\n         \"coil\",\n         \"coin\",\n         \"collect\",\n         \"color\",\n         \"column\",\n         \"combine\",\n         \"come\",\n         \"comfort\",\n         \"comic\",\n         \"common\",\n         \"company\",\n         \"concert\",\n         \"conduct\",\n         \"confirm\",\n         \"congress\",\n         \"connect\",\n         \"consider\",\n         \"control\",\n         \"convince\",\n         \"cook\",\n         \"cool\",\n         \"copper\",\n         \"copy\",\n         \"coral\",\n         \"core\",\n         \"corn\",\n         \"correct\",\n         \"cost\",\n         \"cotton\",\n         \"couch\",\n         \"country\",\n         \"couple\",\n         \"course\",\n         \"cousin\",\n         \"cover\",\n         \"coyote\",\n         \"crack\",\n         \"cradle\",\n         \"craft\",\n         \"cram\",\n         \"crane\",\n         \"crash\",\n         \"crater\",\n         \"crawl\",\n         \"crazy\",\n         \"cream\",\n         \"credit\",\n         \"creek\",\n         \"crew\",\n         \"cricket\",\n         \"crime\",\n         \"crisp\",\n         \"critic\",\n         \"crop\",\n         \"cross\",\n         \"crouch\",\n         \"crowd\",\n         \"crucial\",\n         \"cruel\",\n         \"cruise\",\n         \"crumble\",\n         \"crunch\",\n         \"crush\",\n         \"cry\",\n         \"crystal\",\n         \"cube\",\n         \"culture\",\n         \"cup\",\n         \"cupboard\",\n         \"curious\",\n         \"current\",\n         \"curtain\",\n         \"curve\",\n         \"cushion\",\n         \"custom\",\n         \"cute\",\n         \"cycle\",\n         \"dad\",\n         \"damage\",\n         \"damp\",\n         \"dance\",\n         \"danger\",\n         \"daring\",\n         \"dash\",\n         \"daughter\",\n         \"dawn\",\n         \"day\",\n         \"deal\",\n         \"debate\",\n         \"debris\",\n         \"decade\",\n         \"december\",\n         \"decide\",\n         \"decline\",\n         \"decorate\",\n         \"decrease\",\n         \"deer\",\n         \"defense\",\n         \"define\",\n         \"defy\",\n         \"degree\",\n         \"delay\",\n         \"deliver\",\n         \"demand\",\n         \"demise\",\n         \"denial\",\n         \"dentist\",\n         \"deny\",\n         \"depart\",\n         \"depend\",\n         \"deposit\",\n         \"depth\",\n         \"deputy\",\n         \"derive\",\n         \"describe\",\n         \"desert\",\n         \"design\",\n         \"desk\",\n         \"despair\",\n         \"destroy\",\n         \"detail\",\n         \"detect\",\n         \"develop\",\n         \"device\",\n         \"devote\",\n         \"diagram\",\n         \"dial\",\n         \"diamond\",\n         \"diary\",\n         \"dice\",\n         \"diesel\",\n         \"diet\",\n         \"differ\",\n         \"digital\",\n         \"dignity\",\n         \"dilemma\",\n         \"dinner\",\n         \"dinosaur\",\n         \"direct\",\n         \"dirt\",\n         \"disagree\",\n         \"discover\",\n         \"disease\",\n         \"dish\",\n         \"dismiss\",\n         \"disorder\",\n         \"display\",\n         \"distance\",\n         \"divert\",\n         \"divide\",\n         \"divorce\",\n         \"dizzy\",\n         \"doctor\",\n         \"document\",\n         \"dog\",\n         \"doll\",\n         \"dolphin\",\n         \"domain\",\n         \"donate\",\n         \"donkey\",\n         \"donor\",\n         \"door\",\n         \"dose\",\n         \"double\",\n         \"dove\",\n         \"draft\",\n         \"dragon\",\n         \"drama\",\n         \"drastic\",\n         \"draw\",\n         \"dream\",\n         \"dress\",\n         \"drift\",\n         \"drill\",\n         \"drink\",\n         \"drip\",\n         \"drive\",\n         \"drop\",\n         \"drum\",\n         \"dry\",\n         \"duck\",\n         \"dumb\",\n         \"dune\",\n         \"during\",\n         \"dust\",\n         \"dutch\",\n         \"duty\",\n         \"dwarf\",\n         \"dynamic\",\n         \"eager\",\n         \"eagle\",\n         \"early\",\n         \"earn\",\n         \"earth\",\n         \"easily\",\n         \"east\",\n         \"easy\",\n         \"echo\",\n         \"ecology\",\n         \"economy\",\n         \"edge\",\n         \"edit\",\n         \"educate\",\n         \"effort\",\n         \"egg\",\n         \"eight\",\n         \"either\",\n         \"elbow\",\n         \"elder\",\n         \"electric\",\n         \"elegant\",\n         \"element\",\n         \"elephant\",\n         \"elevator\",\n         \"elite\",\n         \"else\",\n         \"embark\",\n         \"embody\",\n         \"embrace\",\n         \"emerge\",\n         \"emotion\",\n         \"employ\",\n         \"empower\",\n         \"empty\",\n         \"enable\",\n         \"enact\",\n         \"end\",\n         \"endless\",\n         \"endorse\",\n         \"enemy\",\n         \"energy\",\n         \"enforce\",\n         \"engage\",\n         \"engine\",\n         \"enhance\",\n         \"enjoy\",\n         \"enlist\",\n         \"enough\",\n         \"enrich\",\n         \"enroll\",\n         \"ensure\",\n         \"enter\",\n         \"entire\",\n         \"entry\",\n         \"envelope\",\n         \"episode\",\n         \"equal\",\n         \"equip\",\n         \"era\",\n         \"erase\",\n         \"erode\",\n         \"erosion\",\n         \"error\",\n         \"erupt\",\n         \"escape\",\n         \"essay\",\n         \"essence\",\n         \"estate\",\n         \"eternal\",\n         \"ethics\",\n         \"evidence\",\n         \"evil\",\n         \"evoke\",\n         \"evolve\",\n         \"exact\",\n         \"example\",\n         \"excess\",\n         \"exchange\",\n         \"excite\",\n         \"exclude\",\n         \"excuse\",\n         \"execute\",\n         \"exercise\",\n         \"exhaust\",\n         \"exhibit\",\n         \"exile\",\n         \"exist\",\n         \"exit\",\n         \"exotic\",\n         \"expand\",\n         \"expect\",\n         \"expire\",\n         \"explain\",\n         \"expose\",\n         \"express\",\n         \"extend\",\n         \"extra\",\n         \"eye\",\n         \"eyebrow\",\n         \"fabric\",\n         \"face\",\n         \"faculty\",\n         \"fade\",\n         \"faint\",\n         \"faith\",\n         \"fall\",\n         \"false\",\n         \"fame\",\n         \"family\",\n         \"famous\",\n         \"fan\",\n         \"fancy\",\n         \"fantasy\",\n         \"farm\",\n         \"fashion\",\n         \"fat\",\n         \"fatal\",\n         \"father\",\n         \"fatigue\",\n         \"fault\",\n         \"favorite\",\n         \"feature\",\n         \"february\",\n         \"federal\",\n         \"fee\",\n         \"feed\",\n         \"feel\",\n         \"female\",\n         \"fence\",\n         \"festival\",\n         \"fetch\",\n         \"fever\",\n         \"few\",\n         \"fiber\",\n         \"fiction\",\n         \"field\",\n         \"figure\",\n         \"file\",\n         \"film\",\n         \"filter\",\n         \"final\",\n         \"find\",\n         \"fine\",\n         \"finger\",\n         \"finish\",\n         \"fire\",\n         \"firm\",\n         \"first\",\n         \"fiscal\",\n         \"fish\",\n         \"fit\",\n         \"fitness\",\n         \"fix\",\n         \"flag\",\n         \"flame\",\n         \"flash\",\n         \"flat\",\n         \"flavor\",\n         \"flee\",\n         \"flight\",\n         \"flip\",\n         \"float\",\n         \"flock\",\n         \"floor\",\n         \"flower\",\n         \"fluid\",\n         \"flush\",\n         \"fly\",\n         \"foam\",\n         \"focus\",\n         \"fog\",\n         \"foil\",\n         \"fold\",\n         \"follow\",\n         \"food\",\n         \"foot\",\n         \"force\",\n         \"forest\",\n         \"forget\",\n         \"fork\",\n         \"fortune\",\n         \"forum\",\n         \"forward\",\n         \"fossil\",\n         \"foster\",\n         \"found\",\n         \"fox\",\n         \"fragile\",\n         \"frame\",\n         \"frequent\",\n         \"fresh\",\n         \"friend\",\n         \"fringe\",\n         \"frog\",\n         \"front\",\n         \"frost\",\n         \"frown\",\n         \"frozen\",\n         \"fruit\",\n         \"fuel\",\n         \"fun\",\n         \"funny\",\n         \"furnace\",\n         \"fury\",\n         \"future\",\n         \"gadget\",\n         \"gain\",\n         \"galaxy\",\n         \"gallery\",\n         \"game\",\n         \"gap\",\n         \"garage\",\n         \"garbage\",\n         \"garden\",\n         \"garlic\",\n         \"garment\",\n         \"gas\",\n         \"gasp\",\n         \"gate\",\n         \"gather\",\n         \"gauge\",\n         \"gaze\",\n         \"general\",\n         \"genius\",\n         \"genre\",\n         \"gentle\",\n         \"genuine\",\n         \"gesture\",\n         \"ghost\",\n         \"giant\",\n         \"gift\",\n         \"giggle\",\n         \"ginger\",\n         \"giraffe\",\n         \"girl\",\n         \"give\",\n         \"glad\",\n         \"glance\",\n         \"glare\",\n         \"glass\",\n         \"glide\",\n         \"glimpse\",\n         \"globe\",\n         \"gloom\",\n         \"glory\",\n         \"glove\",\n         \"glow\",\n         \"glue\",\n         \"goat\",\n         \"goddess\",\n         \"gold\",\n         \"good\",\n         \"goose\",\n         \"gorilla\",\n         \"gospel\",\n         \"gossip\",\n         \"govern\",\n         \"gown\",\n         \"grab\",\n         \"grace\",\n         \"grain\",\n         \"grant\",\n         \"grape\",\n         \"grass\",\n         \"gravity\",\n         \"great\",\n         \"green\",\n         \"grid\",\n         \"grief\",\n         \"grit\",\n         \"grocery\",\n         \"group\",\n         \"grow\",\n         \"grunt\",\n         \"guard\",\n         \"guess\",\n         \"guide\",\n         \"guilt\",\n         \"guitar\",\n         \"gun\",\n         \"gym\",\n         \"habit\",\n         \"hair\",\n         \"half\",\n         \"hammer\",\n         \"hamster\",\n         \"hand\",\n         \"happy\",\n         \"harbor\",\n         \"hard\",\n         \"harsh\",\n         \"harvest\",\n         \"hat\",\n         \"have\",\n         \"hawk\",\n         \"hazard\",\n         \"head\",\n         \"health\",\n         \"heart\",\n         \"heavy\",\n         \"hedgehog\",\n         \"height\",\n         \"hello\",\n         \"helmet\",\n         \"help\",\n         \"hen\",\n         \"hero\",\n         \"hidden\",\n         \"high\",\n         \"hill\",\n         \"hint\",\n         \"hip\",\n         \"hire\",\n         \"history\",\n         \"hobby\",\n         \"hockey\",\n         \"hold\",\n         \"hole\",\n         \"holiday\",\n         \"hollow\",\n         \"home\",\n         \"honey\",\n         \"hood\",\n         \"hope\",\n         \"horn\",\n         \"horror\",\n         \"horse\",\n         \"hospital\",\n         \"host\",\n         \"hotel\",\n         \"hour\",\n         \"hover\",\n         \"hub\",\n         \"huge\",\n         \"human\",\n         \"humble\",\n         \"humor\",\n         \"hundred\",\n         \"hungry\",\n         \"hunt\",\n         \"hurdle\",\n         \"hurry\",\n         \"hurt\",\n         \"husband\",\n         \"hybrid\",\n         \"ice\",\n         \"icon\",\n         \"idea\",\n         \"identify\",\n         \"idle\",\n         \"ignore\",\n         \"ill\",\n         \"illegal\",\n         \"illness\",\n         \"image\",\n         \"imitate\",\n         \"immense\",\n         \"immune\",\n         \"impact\",\n         \"impose\",\n         \"improve\",\n         \"impulse\",\n         \"inch\",\n         \"include\",\n         \"income\",\n         \"increase\",\n         \"index\",\n         \"indicate\",\n         \"indoor\",\n         \"industry\",\n         \"infant\",\n         \"inflict\",\n         \"inform\",\n         \"inhale\",\n         \"inherit\",\n         \"initial\",\n         \"inject\",\n         \"injury\",\n         \"inmate\",\n         \"inner\",\n         \"innocent\",\n         \"input\",\n         \"inquiry\",\n         \"insane\",\n         \"insect\",\n         \"inside\",\n         \"inspire\",\n         \"install\",\n         \"intact\",\n         \"interest\",\n         \"into\",\n         \"invest\",\n         \"invite\",\n         \"involve\",\n         \"iron\",\n         \"island\",\n         \"isolate\",\n         \"issue\",\n         \"item\",\n         \"ivory\",\n         \"jacket\",\n         \"jaguar\",\n         \"jar\",\n         \"jazz\",\n         \"jealous\",\n         \"jeans\",\n         \"jelly\",\n         \"jewel\",\n         \"job\",\n         \"join\",\n         \"joke\",\n         \"journey\",\n         \"joy\",\n         \"judge\",\n         \"juice\",\n         \"jump\",\n         \"jungle\",\n         \"junior\",\n         \"junk\",\n         \"just\",\n         \"kangaroo\",\n         \"keen\",\n         \"keep\",\n         \"ketchup\",\n         \"key\",\n         \"kick\",\n         \"kid\",\n         \"kidney\",\n         \"kind\",\n         \"kingdom\",\n         \"kiss\",\n         \"kit\",\n         \"kitchen\",\n         \"kite\",\n         \"kitten\",\n         \"kiwi\",\n         \"knee\",\n         \"knife\",\n         \"knock\",\n         \"know\",\n         \"lab\",\n         \"label\",\n         \"labor\",\n         \"ladder\",\n         \"lady\",\n         \"lake\",\n         \"lamp\",\n         \"language\",\n         \"laptop\",\n         \"large\",\n         \"later\",\n         \"latin\",\n         \"laugh\",\n         \"laundry\",\n         \"lava\",\n         \"law\",\n         \"lawn\",\n         \"lawsuit\",\n         \"layer\",\n         \"lazy\",\n         \"leader\",\n         \"leaf\",\n         \"learn\",\n         \"leave\",\n         \"lecture\",\n         \"left\",\n         \"leg\",\n         \"legal\",\n         \"legend\",\n         \"leisure\",\n         \"lemon\",\n         \"lend\",\n         \"length\",\n         \"lens\",\n         \"leopard\",\n         \"lesson\",\n         \"letter\",\n         \"level\",\n         \"liar\",\n         \"liberty\",\n         \"library\",\n         \"license\",\n         \"life\",\n         \"lift\",\n         \"light\",\n         \"like\",\n         \"limb\",\n         \"limit\",\n         \"link\",\n         \"lion\",\n         \"liquid\",\n         \"list\",\n         \"little\",\n         \"live\",\n         \"lizard\",\n         \"load\",\n         \"loan\",\n         \"lobster\",\n         \"local\",\n         \"lock\",\n         \"logic\",\n         \"lonely\",\n         \"long\",\n         \"loop\",\n         \"lottery\",\n         \"loud\",\n         \"lounge\",\n         \"love\",\n         \"loyal\",\n         \"lucky\",\n         \"luggage\",\n         \"lumber\",\n         \"lunar\",\n         \"lunch\",\n         \"luxury\",\n         \"lyrics\",\n         \"machine\",\n         \"mad\",\n         \"magic\",\n         \"magnet\",\n         \"maid\",\n         \"mail\",\n         \"main\",\n         \"major\",\n         \"make\",\n         \"mammal\",\n         \"man\",\n         \"manage\",\n         \"mandate\",\n         \"mango\",\n         \"mansion\",\n         \"manual\",\n         \"maple\",\n         \"marble\",\n         \"march\",\n         \"margin\",\n         \"marine\",\n         \"market\",\n         \"marriage\",\n         \"mask\",\n         \"mass\",\n         \"master\",\n         \"match\",\n         \"material\",\n         \"math\",\n         \"matrix\",\n         \"matter\",\n         \"maximum\",\n         \"maze\",\n         \"meadow\",\n         \"mean\",\n         \"measure\",\n         \"meat\",\n         \"mechanic\",\n         \"medal\",\n         \"media\",\n         \"melody\",\n         \"melt\",\n         \"member\",\n         \"memory\",\n         \"mention\",\n         \"menu\",\n         \"mercy\",\n         \"merge\",\n         \"merit\",\n         \"merry\",\n         \"mesh\",\n         \"message\",\n         \"metal\",\n         \"method\",\n         \"middle\",\n         \"midnight\",\n         \"milk\",\n         \"million\",\n         \"mimic\",\n         \"mind\",\n         \"minimum\",\n         \"minor\",\n         \"minute\",\n         \"miracle\",\n         \"mirror\",\n         \"misery\",\n         \"miss\",\n         \"mistake\",\n         \"mix\",\n         \"mixed\",\n         \"mixture\",\n         \"mobile\",\n         \"model\",\n         \"modify\",\n         \"mom\",\n         \"moment\",\n         \"monitor\",\n         \"monkey\",\n         \"monster\",\n         \"month\",\n         \"moon\",\n         \"moral\",\n         \"more\",\n         \"morning\",\n         \"mosquito\",\n         \"mother\",\n         \"motion\",\n         \"motor\",\n         \"mountain\",\n         \"mouse\",\n         \"move\",\n         \"movie\",\n         \"much\",\n         \"muffin\",\n         \"mule\",\n         \"multiply\",\n         \"muscle\",\n         \"museum\",\n         \"mushroom\",\n         \"music\",\n         \"must\",\n         \"mutual\",\n         \"myself\",\n         \"mystery\",\n         \"myth\",\n         \"naive\",\n         \"name\",\n         \"napkin\",\n         \"narrow\",\n         \"nasty\",\n         \"nation\",\n         \"nature\",\n         \"near\",\n         \"neck\",\n         \"need\",\n         \"negative\",\n         \"neglect\",\n         \"neither\",\n         \"nephew\",\n         \"nerve\",\n         \"nest\",\n         \"net\",\n         \"network\",\n         \"neutral\",\n         \"never\",\n         \"news\",\n         \"next\",\n         \"nice\",\n         \"night\",\n         \"noble\",\n         \"noise\",\n         \"nominee\",\n         \"noodle\",\n         \"normal\",\n         \"north\",\n         \"nose\",\n         \"notable\",\n         \"note\",\n         \"nothing\",\n         \"notice\",\n         \"novel\",\n         \"now\",\n         \"nuclear\",\n         \"number\",\n         \"nurse\",\n         \"nut\",\n         \"oak\",\n         \"obey\",\n         \"object\",\n         \"oblige\",\n         \"obscure\",\n         \"observe\",\n         \"obtain\",\n         \"obvious\",\n         \"occur\",\n         \"ocean\",\n         \"october\",\n         \"odor\",\n         \"off\",\n         \"offer\",\n         \"office\",\n         \"often\",\n         \"oil\",\n         \"okay\",\n         \"old\",\n         \"olive\",\n         \"olympic\",\n         \"omit\",\n         \"once\",\n         \"one\",\n         \"onion\",\n         \"online\",\n         \"only\",\n         \"open\",\n         \"opera\",\n         \"opinion\",\n         \"oppose\",\n         \"option\",\n         \"orange\",\n         \"orbit\",\n         \"orchard\",\n         \"order\",\n         \"ordinary\",\n         \"organ\",\n         \"orient\",\n         \"original\",\n         \"orphan\",\n         \"ostrich\",\n         \"other\",\n         \"outdoor\",\n         \"outer\",\n         \"output\",\n         \"outside\",\n         \"oval\",\n         \"oven\",\n         \"over\",\n         \"own\",\n         \"owner\",\n         \"oxygen\",\n         \"oyster\",\n         \"ozone\",\n         \"pact\",\n         \"paddle\",\n         \"page\",\n         \"pair\",\n         \"palace\",\n         \"palm\",\n         \"panda\",\n         \"panel\",\n         \"panic\",\n         \"panther\",\n         \"paper\",\n         \"parade\",\n         \"parent\",\n         \"park\",\n         \"parrot\",\n         \"party\",\n         \"pass\",\n         \"patch\",\n         \"path\",\n         \"patient\",\n         \"patrol\",\n         \"pattern\",\n         \"pause\",\n         \"pave\",\n         \"payment\",\n         \"peace\",\n         \"peanut\",\n         \"pear\",\n         \"peasant\",\n         \"pelican\",\n         \"pen\",\n         \"penalty\",\n         \"pencil\",\n         \"people\",\n         \"pepper\",\n         \"perfect\",\n         \"permit\",\n         \"person\",\n         \"pet\",\n         \"phone\",\n         \"photo\",\n         \"phrase\",\n         \"physical\",\n         \"piano\",\n         \"picnic\",\n         \"picture\",\n         \"piece\",\n         \"pig\",\n         \"pigeon\",\n         \"pill\",\n         \"pilot\",\n         \"pink\",\n         \"pioneer\",\n         \"pipe\",\n         \"pistol\",\n         \"pitch\",\n         \"pizza\",\n         \"place\",\n         \"planet\",\n         \"plastic\",\n         \"plate\",\n         \"play\",\n         \"please\",\n         \"pledge\",\n         \"pluck\",\n         \"plug\",\n         \"plunge\",\n         \"poem\",\n         \"poet\",\n         \"point\",\n         \"polar\",\n         \"pole\",\n         \"police\",\n         \"pond\",\n         \"pony\",\n         \"pool\",\n         \"popular\",\n         \"portion\",\n         \"position\",\n         \"possible\",\n         \"post\",\n         \"potato\",\n         \"pottery\",\n         \"poverty\",\n         \"powder\",\n         \"power\",\n         \"practice\",\n         \"praise\",\n         \"predict\",\n         \"prefer\",\n         \"prepare\",\n         \"present\",\n         \"pretty\",\n         \"prevent\",\n         \"price\",\n         \"pride\",\n         \"primary\",\n         \"print\",\n         \"priority\",\n         \"prison\",\n         \"private\",\n         \"prize\",\n         \"problem\",\n         \"process\",\n         \"produce\",\n         \"profit\",\n         \"program\",\n         \"project\",\n         \"promote\",\n         \"proof\",\n         \"property\",\n         \"prosper\",\n         \"protect\",\n         \"proud\",\n         \"provide\",\n         \"public\",\n         \"pudding\",\n         \"pull\",\n         \"pulp\",\n         \"pulse\",\n         \"pumpkin\",\n         \"punch\",\n         \"pupil\",\n         \"puppy\",\n         \"purchase\",\n         \"purity\",\n         \"purpose\",\n         \"purse\",\n         \"push\",\n         \"put\",\n         \"puzzle\",\n         \"pyramid\",\n         \"quality\",\n         \"quantum\",\n         \"quarter\",\n         \"question\",\n         \"quick\",\n         \"quit\",\n         \"quiz\",\n         \"quote\",\n         \"rabbit\",\n         \"raccoon\",\n         \"race\",\n         \"rack\",\n         \"radar\",\n         \"radio\",\n         \"rail\",\n         \"rain\",\n         \"raise\",\n         \"rally\",\n         \"ramp\",\n         \"ranch\",\n         \"random\",\n         \"range\",\n         \"rapid\",\n         \"rare\",\n         \"rate\",\n         \"rather\",\n         \"raven\",\n         \"raw\",\n         \"razor\",\n         \"ready\",\n         \"real\",\n         \"reason\",\n         \"rebel\",\n         \"rebuild\",\n         \"recall\",\n         \"receive\",\n         \"recipe\",\n         \"record\",\n         \"recycle\",\n         \"reduce\",\n         \"reflect\",\n         \"reform\",\n         \"refuse\",\n         \"region\",\n         \"regret\",\n         \"regular\",\n         \"reject\",\n         \"relax\",\n         \"release\",\n         \"relief\",\n         \"rely\",\n         \"remain\",\n         \"remember\",\n         \"remind\",\n         \"remove\",\n         \"render\",\n         \"renew\",\n         \"rent\",\n         \"reopen\",\n         \"repair\",\n         \"repeat\",\n         \"replace\",\n         \"report\",\n         \"require\",\n         \"rescue\",\n         \"resemble\",\n         \"resist\",\n         \"resource\",\n         \"response\",\n         \"result\",\n         \"retire\",\n         \"retreat\",\n         \"return\",\n         \"reunion\",\n         \"reveal\",\n         \"review\",\n         \"reward\",\n         \"rhythm\",\n         \"rib\",\n         \"ribbon\",\n         \"rice\",\n         \"rich\",\n         \"ride\",\n         \"ridge\",\n         \"rifle\",\n         \"right\",\n         \"rigid\",\n         \"ring\",\n         \"riot\",\n         \"ripple\",\n         \"risk\",\n         \"ritual\",\n         \"rival\",\n         \"river\",\n         \"road\",\n         \"roast\",\n         \"robot\",\n         \"robust\",\n         \"rocket\",\n         \"romance\",\n         \"roof\",\n         \"rookie\",\n         \"room\",\n         \"rose\",\n         \"rotate\",\n         \"rough\",\n         \"round\",\n         \"route\",\n         \"royal\",\n         \"rubber\",\n         \"rude\",\n         \"rug\",\n         \"rule\",\n         \"run\",\n         \"runway\",\n         \"rural\",\n         \"sad\",\n         \"saddle\",\n         \"sadness\",\n         \"safe\",\n         \"sail\",\n         \"salad\",\n         \"salmon\",\n         \"salon\",\n         \"salt\",\n         \"salute\",\n         \"same\",\n         \"sample\",\n         \"sand\",\n         \"satisfy\",\n         \"satoshi\",\n         \"sauce\",\n         \"sausage\",\n         \"save\",\n         \"say\",\n         \"scale\",\n         \"scan\",\n         \"scare\",\n         \"scatter\",\n         \"scene\",\n         \"scheme\",\n         \"school\",\n         \"science\",\n         \"scissors\",\n         \"scorpion\",\n         \"scout\",\n         \"scrap\",\n         \"screen\",\n         \"script\",\n         \"scrub\",\n         \"sea\",\n         \"search\",\n         \"season\",\n         \"seat\",\n         \"second\",\n         \"secret\",\n         \"section\",\n         \"security\",\n         \"seed\",\n         \"seek\",\n         \"segment\",\n         \"select\",\n         \"sell\",\n         \"seminar\",\n         \"senior\",\n         \"sense\",\n         \"sentence\",\n         \"series\",\n         \"service\",\n         \"session\",\n         \"settle\",\n         \"setup\",\n         \"seven\",\n         \"shadow\",\n         \"shaft\",\n         \"shallow\",\n         \"share\",\n         \"shed\",\n         \"shell\",\n         \"sheriff\",\n         \"shield\",\n         \"shift\",\n         \"shine\",\n         \"ship\",\n         \"shiver\",\n         \"shock\",\n         \"shoe\",\n         \"shoot\",\n         \"shop\",\n         \"short\",\n         \"shoulder\",\n         \"shove\",\n         \"shrimp\",\n         \"shrug\",\n         \"shuffle\",\n         \"shy\",\n         \"sibling\",\n         \"sick\",\n         \"side\",\n         \"siege\",\n         \"sight\",\n         \"sign\",\n         \"silent\",\n         \"silk\",\n         \"silly\",\n         \"silver\",\n         \"similar\",\n         \"simple\",\n         \"since\",\n         \"sing\",\n         \"siren\",\n         \"sister\",\n         \"situate\",\n         \"six\",\n         \"size\",\n         \"skate\",\n         \"sketch\",\n         \"ski\",\n         \"skill\",\n         \"skin\",\n         \"skirt\",\n         \"skull\",\n         \"slab\",\n         \"slam\",\n         \"sleep\",\n         \"slender\",\n         \"slice\",\n         \"slide\",\n         \"slight\",\n         \"slim\",\n         \"slogan\",\n         \"slot\",\n         \"slow\",\n         \"slush\",\n         \"small\",\n         \"smart\",\n         \"smile\",\n         \"smoke\",\n         \"smooth\",\n         \"snack\",\n         \"snake\",\n         \"snap\",\n         \"sniff\",\n         \"snow\",\n         \"soap\",\n         \"soccer\",\n         \"social\",\n         \"sock\",\n         \"soda\",\n         \"soft\",\n         \"solar\",\n         \"soldier\",\n         \"solid\",\n         \"solution\",\n         \"solve\",\n         \"someone\",\n         \"song\",\n         \"soon\",\n         \"sorry\",\n         \"sort\",\n         \"soul\",\n         \"sound\",\n         \"soup\",\n         \"source\",\n         \"south\",\n         \"space\",\n         \"spare\",\n         \"spatial\",\n         \"spawn\",\n         \"speak\",\n         \"special\",\n         \"speed\",\n         \"spell\",\n         \"spend\",\n         \"sphere\",\n         \"spice\",\n         \"spider\",\n         \"spike\",\n         \"spin\",\n         \"spirit\",\n         \"split\",\n         \"spoil\",\n         \"sponsor\",\n         \"spoon\",\n         \"sport\",\n         \"spot\",\n         \"spray\",\n         \"spread\",\n         \"spring\",\n         \"spy\",\n         \"square\",\n         \"squeeze\",\n         \"squirrel\",\n         \"stable\",\n         \"stadium\",\n         \"staff\",\n         \"stage\",\n         \"stairs\",\n         \"stamp\",\n         \"stand\",\n         \"start\",\n         \"state\",\n         \"stay\",\n         \"steak\",\n         \"steel\",\n         \"stem\",\n         \"step\",\n         \"stereo\",\n         \"stick\",\n         \"still\",\n         \"sting\",\n         \"stock\",\n         \"stomach\",\n         \"stone\",\n         \"stool\",\n         \"story\",\n         \"stove\",\n         \"strategy\",\n         \"street\",\n         \"strike\",\n         \"strong\",\n         \"struggle\",\n         \"student\",\n         \"stuff\",\n         \"stumble\",\n         \"style\",\n         \"subject\",\n         \"submit\",\n         \"subway\",\n         \"success\",\n         \"such\",\n         \"sudden\",\n         \"suffer\",\n         \"sugar\",\n         \"suggest\",\n         \"suit\",\n         \"summer\",\n         \"sun\",\n         \"sunny\",\n         \"sunset\",\n         \"super\",\n         \"supply\",\n         \"supreme\",\n         \"sure\",\n         \"surface\",\n         \"surge\",\n         \"surprise\",\n         \"surround\",\n         \"survey\",\n         \"suspect\",\n         \"sustain\",\n         \"swallow\",\n         \"swamp\",\n         \"swap\",\n         \"swarm\",\n         \"swear\",\n         \"sweet\",\n         \"swift\",\n         \"swim\",\n         \"swing\",\n         \"switch\",\n         \"sword\",\n         \"symbol\",\n         \"symptom\",\n         \"syrup\",\n         \"system\",\n         \"table\",\n         \"tackle\",\n         \"tag\",\n         \"tail\",\n         \"talent\",\n         \"talk\",\n         \"tank\",\n         \"tape\",\n         \"target\",\n         \"task\",\n         \"taste\",\n         \"tattoo\",\n         \"taxi\",\n         \"teach\",\n         \"team\",\n         \"tell\",\n         \"ten\",\n         \"tenant\",\n         \"tennis\",\n         \"tent\",\n         \"term\",\n         \"test\",\n         \"text\",\n         \"thank\",\n         \"that\",\n         \"theme\",\n         \"then\",\n         \"theory\",\n         \"there\",\n         \"they\",\n         \"thing\",\n         \"this\",\n         \"thought\",\n         \"three\",\n         \"thrive\",\n         \"throw\",\n         \"thumb\",\n         \"thunder\",\n         \"ticket\",\n         \"tide\",\n         \"tiger\",\n         \"tilt\",\n         \"timber\",\n         \"time\",\n         \"tiny\",\n         \"tip\",\n         \"tired\",\n         \"tissue\",\n         \"title\",\n         \"toast\",\n         \"tobacco\",\n         \"today\",\n         \"toddler\",\n         \"toe\",\n         \"together\",\n         \"toilet\",\n         \"token\",\n         \"tomato\",\n         \"tomorrow\",\n         \"tone\",\n         \"tongue\",\n         \"tonight\",\n         \"tool\",\n         \"tooth\",\n         \"top\",\n         \"topic\",\n         \"topple\",\n         \"torch\",\n         \"tornado\",\n         \"tortoise\",\n         \"toss\",\n         \"total\",\n         \"tourist\",\n         \"toward\",\n         \"tower\",\n         \"town\",\n         \"toy\",\n         \"track\",\n         \"trade\",\n         \"traffic\",\n         \"tragic\",\n         \"train\",\n         \"transfer\",\n         \"trap\",\n         \"trash\",\n         \"travel\",\n         \"tray\",\n         \"treat\",\n         \"tree\",\n         \"trend\",\n         \"trial\",\n         \"tribe\",\n         \"trick\",\n         \"trigger\",\n         \"trim\",\n         \"trip\",\n         \"trophy\",\n         \"trouble\",\n         \"truck\",\n         \"true\",\n         \"truly\",\n         \"trumpet\",\n         \"trust\",\n         \"truth\",\n         \"try\",\n         \"tube\",\n         \"tuition\",\n         \"tumble\",\n         \"tuna\",\n         \"tunnel\",\n         \"turkey\",\n         \"turn\",\n         \"turtle\",\n         \"twelve\",\n         \"twenty\",\n         \"twice\",\n         \"twin\",\n         \"twist\",\n         \"two\",\n         \"type\",\n         \"typical\",\n         \"ugly\",\n         \"umbrella\",\n         \"unable\",\n         \"unaware\",\n         \"uncle\",\n         \"uncover\",\n         \"under\",\n         \"undo\",\n         \"unfair\",\n         \"unfold\",\n         \"unhappy\",\n         \"uniform\",\n         \"unique\",\n         \"unit\",\n         \"universe\",\n         \"unknown\",\n         \"unlock\",\n         \"until\",\n         \"unusual\",\n         \"unveil\",\n         \"update\",\n         \"upgrade\",\n         \"uphold\",\n         \"upon\",\n         \"upper\",\n         \"upset\",\n         \"urban\",\n         \"urge\",\n         \"usage\",\n         \"use\",\n         \"used\",\n         \"useful\",\n         \"useless\",\n         \"usual\",\n         \"utility\",\n         \"vacant\",\n         \"vacuum\",\n         \"vague\",\n         \"valid\",\n         \"valley\",\n         \"valve\",\n         \"van\",\n         \"vanish\",\n         \"vapor\",\n         \"various\",\n         \"vast\",\n         \"vault\",\n         \"vehicle\",\n         \"velvet\",\n         \"vendor\",\n         \"venture\",\n         \"venue\",\n         \"verb\",\n         \"verify\",\n         \"version\",\n         \"very\",\n         \"vessel\",\n         \"veteran\",\n         \"viable\",\n         \"vibrant\",\n         \"vicious\",\n         \"victory\",\n         \"video\",\n         \"view\",\n         \"village\",\n         \"vintage\",\n         \"violin\",\n         \"virtual\",\n         \"virus\",\n         \"visa\",\n         \"visit\",\n         \"visual\",\n         \"vital\",\n         \"vivid\",\n         \"vocal\",\n         \"voice\",\n         \"void\",\n         \"volcano\",\n         \"volume\",\n         \"vote\",\n         \"voyage\",\n         \"wage\",\n         \"wagon\",\n         \"wait\",\n         \"walk\",\n         \"wall\",\n         \"walnut\",\n         \"want\",\n         \"warfare\",\n         \"warm\",\n         \"warrior\",\n         \"wash\",\n         \"wasp\",\n         \"waste\",\n         \"water\",\n         \"wave\",\n         \"way\",\n         \"wealth\",\n         \"weapon\",\n         \"wear\",\n         \"weasel\",\n         \"weather\",\n         \"web\",\n         \"wedding\",\n         \"weekend\",\n         \"weird\",\n         \"welcome\",\n         \"west\",\n         \"wet\",\n         \"whale\",\n         \"what\",\n         \"wheat\",\n         \"wheel\",\n         \"when\",\n         \"where\",\n         \"whip\",\n         \"whisper\",\n         \"wide\",\n         \"width\",\n         \"wife\",\n         \"wild\",\n         \"will\",\n         \"win\",\n         \"window\",\n         \"wine\",\n         \"wing\",\n         \"wink\",\n         \"winner\",\n         \"winter\",\n         \"wire\",\n         \"wisdom\",\n         \"wise\",\n         \"wish\",\n         \"witness\",\n         \"wolf\",\n         \"woman\",\n         \"wonder\",\n         \"wood\",\n         \"wool\",\n         \"word\",\n         \"work\",\n         \"world\",\n         \"worry\",\n         \"worth\",\n         \"wrap\",\n         \"wreck\",\n         \"wrestle\",\n         \"wrist\",\n         \"write\",\n         \"wrong\",\n         \"yard\",\n         \"year\",\n         \"yellow\",\n         \"you\",\n         \"young\",\n         \"youth\",\n         \"zebra\",\n         \"zero\",\n         \"zone\",\n         \"zoo\"}};\n\nconst dictionary es =\n    {\n        {\"ábaco\",\n         \"abdomen\",\n         \"abeja\",\n         \"abierto\",\n         \"abogado\",\n         \"abono\",\n         \"aborto\",\n         \"abrazo\",\n         \"abrir\",\n         \"abuelo\",\n         \"abuso\",\n         \"acabar\",\n         \"academia\",\n         \"acceso\",\n         \"acción\",\n         \"aceite\",\n         \"acelga\",\n         \"acento\",\n         \"aceptar\",\n         \"ácido\",\n         \"aclarar\",\n         \"acné\",\n         \"acoger\",\n         \"acoso\",\n         \"activo\",\n         \"acto\",\n         \"actriz\",\n         \"actuar\",\n         \"acudir\",\n         \"acuerdo\",\n         \"acusar\",\n         \"adicto\",\n         \"admitir\",\n         \"adoptar\",\n         \"adorno\",\n         \"aduana\",\n         \"adulto\",\n         \"aéreo\",\n         \"afectar\",\n         \"afición\",\n         \"afinar\",\n         \"afirmar\",\n         \"ágil\",\n         \"agitar\",\n         \"agonía\",\n         \"agosto\",\n         \"agotar\",\n         \"agregar\",\n         \"agrio\",\n         \"agua\",\n         \"agudo\",\n         \"águila\",\n         \"aguja\",\n         \"ahogo\",\n         \"ahorro\",\n         \"aire\",\n         \"aislar\",\n         \"ajedrez\",\n         \"ajeno\",\n         \"ajuste\",\n         \"alacrán\",\n         \"alambre\",\n         \"alarma\",\n         \"alba\",\n         \"álbum\",\n         \"alcalde\",\n         \"aldea\",\n         \"alegre\",\n         \"alejar\",\n         \"alerta\",\n         \"aleta\",\n         \"alfiler\",\n         \"alga\",\n         \"algodón\",\n         \"aliado\",\n         \"aliento\",\n         \"alivio\",\n         \"alma\",\n         \"almeja\",\n         \"almíbar\",\n         \"altar\",\n         \"alteza\",\n         \"altivo\",\n         \"alto\",\n         \"altura\",\n         \"alumno\",\n         \"alzar\",\n         \"amable\",\n         \"amante\",\n         \"amapola\",\n         \"amargo\",\n         \"amasar\",\n         \"ámbar\",\n         \"ámbito\",\n         \"ameno\",\n         \"amigo\",\n         \"amistad\",\n         \"amor\",\n         \"amparo\",\n         \"amplio\",\n         \"ancho\",\n         \"anciano\",\n         \"ancla\",\n         \"andar\",\n         \"andén\",\n         \"anemia\",\n         \"ángulo\",\n         \"anillo\",\n         \"ánimo\",\n         \"anís\",\n         \"anotar\",\n         \"antena\",\n         \"antiguo\",\n         \"antojo\",\n         \"anual\",\n         \"anular\",\n         \"anuncio\",\n         \"añadir\",\n         \"añejo\",\n         \"año\",\n         \"apagar\",\n         \"aparato\",\n         \"apetito\",\n         \"apio\",\n         \"aplicar\",\n         \"apodo\",\n         \"aporte\",\n         \"apoyo\",\n         \"aprender\",\n         \"aprobar\",\n         \"apuesta\",\n         \"apuro\",\n         \"arado\",\n         \"araña\",\n         \"arar\",\n         \"árbitro\",\n         \"árbol\",\n         \"arbusto\",\n         \"archivo\",\n         \"arco\",\n         \"arder\",\n         \"ardilla\",\n         \"arduo\",\n         \"área\",\n         \"árido\",\n         \"aries\",\n         \"armonía\",\n         \"arnés\",\n         \"aroma\",\n         \"arpa\",\n         \"arpón\",\n         \"arreglo\",\n         \"arroz\",\n         \"arruga\",\n         \"arte\",\n         \"artista\",\n         \"asa\",\n         \"asado\",\n         \"asalto\",\n         \"ascenso\",\n         \"asegurar\",\n         \"aseo\",\n         \"asesor\",\n         \"asiento\",\n         \"asilo\",\n         \"asistir\",\n         \"asno\",\n         \"asombro\",\n         \"áspero\",\n         \"astilla\",\n         \"astro\",\n         \"astuto\",\n         \"asumir\",\n         \"asunto\",\n         \"atajo\",\n         \"ataque\",\n         \"atar\",\n         \"atento\",\n         \"ateo\",\n         \"ático\",\n         \"atleta\",\n         \"átomo\",\n         \"atraer\",\n         \"atroz\",\n         \"atún\",\n         \"audaz\",\n         \"audio\",\n         \"auge\",\n         \"aula\",\n         \"aumento\",\n         \"ausente\",\n         \"autor\",\n         \"aval\",\n         \"avance\",\n         \"avaro\",\n         \"ave\",\n         \"avellana\",\n         \"avena\",\n         \"avestruz\",\n         \"avión\",\n         \"aviso\",\n         \"ayer\",\n         \"ayuda\",\n         \"ayuno\",\n         \"azafrán\",\n         \"azar\",\n         \"azote\",\n         \"azúcar\",\n         \"azufre\",\n         \"azul\",\n         \"baba\",\n         \"babor\",\n         \"bache\",\n         \"bahía\",\n         \"baile\",\n         \"bajar\",\n         \"balanza\",\n         \"balcón\",\n         \"balde\",\n         \"bambú\",\n         \"banco\",\n         \"banda\",\n         \"baño\",\n         \"barba\",\n         \"barco\",\n         \"barniz\",\n         \"barro\",\n         \"báscula\",\n         \"bastón\",\n         \"basura\",\n         \"batalla\",\n         \"batería\",\n         \"batir\",\n         \"batuta\",\n         \"baúl\",\n         \"bazar\",\n         \"bebé\",\n         \"bebida\",\n         \"bello\",\n         \"besar\",\n         \"beso\",\n         \"bestia\",\n         \"bicho\",\n         \"bien\",\n         \"bingo\",\n         \"blanco\",\n         \"bloque\",\n         \"blusa\",\n         \"boa\",\n         \"bobina\",\n         \"bobo\",\n         \"boca\",\n         \"bocina\",\n         \"boda\",\n         \"bodega\",\n         \"boina\",\n         \"bola\",\n         \"bolero\",\n         \"bolsa\",\n         \"bomba\",\n         \"bondad\",\n         \"bonito\",\n         \"bono\",\n         \"bonsái\",\n         \"borde\",\n         \"borrar\",\n         \"bosque\",\n         \"bote\",\n         \"botín\",\n         \"bóveda\",\n         \"bozal\",\n         \"bravo\",\n         \"brazo\",\n         \"brecha\",\n         \"breve\",\n         \"brillo\",\n         \"brinco\",\n         \"brisa\",\n         \"broca\",\n         \"broma\",\n         \"bronce\",\n         \"brote\",\n         \"bruja\",\n         \"brusco\",\n         \"bruto\",\n         \"buceo\",\n         \"bucle\",\n         \"bueno\",\n         \"buey\",\n         \"bufanda\",\n         \"bufón\",\n         \"búho\",\n         \"buitre\",\n         \"bulto\",\n         \"burbuja\",\n         \"burla\",\n         \"burro\",\n         \"buscar\",\n         \"butaca\",\n         \"buzón\",\n         \"caballo\",\n         \"cabeza\",\n         \"cabina\",\n         \"cabra\",\n         \"cacao\",\n         \"cadáver\",\n         \"cadena\",\n         \"caer\",\n         \"café\",\n         \"caída\",\n         \"caimán\",\n         \"caja\",\n         \"cajón\",\n         \"cal\",\n         \"calamar\",\n         \"calcio\",\n         \"caldo\",\n         \"calidad\",\n         \"calle\",\n         \"calma\",\n         \"calor\",\n         \"calvo\",\n         \"cama\",\n         \"cambio\",\n         \"camello\",\n         \"camino\",\n         \"campo\",\n         \"cáncer\",\n         \"candil\",\n         \"canela\",\n         \"canguro\",\n         \"canica\",\n         \"canto\",\n         \"caña\",\n         \"cañón\",\n         \"caoba\",\n         \"caos\",\n         \"capaz\",\n         \"capitán\",\n         \"capote\",\n         \"captar\",\n         \"capucha\",\n         \"cara\",\n         \"carbón\",\n         \"cárcel\",\n         \"careta\",\n         \"carga\",\n         \"cariño\",\n         \"carne\",\n         \"carpeta\",\n         \"carro\",\n         \"carta\",\n         \"casa\",\n         \"casco\",\n         \"casero\",\n         \"caspa\",\n         \"castor\",\n         \"catorce\",\n         \"catre\",\n         \"caudal\",\n         \"causa\",\n         \"cazo\",\n         \"cebolla\",\n         \"ceder\",\n         \"cedro\",\n         \"celda\",\n         \"célebre\",\n         \"celoso\",\n         \"célula\",\n         \"cemento\",\n         \"ceniza\",\n         \"centro\",\n         \"cerca\",\n         \"cerdo\",\n         \"cereza\",\n         \"cero\",\n         \"cerrar\",\n         \"certeza\",\n         \"césped\",\n         \"cetro\",\n         \"chacal\",\n         \"chaleco\",\n         \"champú\",\n         \"chancla\",\n         \"chapa\",\n         \"charla\",\n         \"chico\",\n         \"chiste\",\n         \"chivo\",\n         \"choque\",\n         \"choza\",\n         \"chuleta\",\n         \"chupar\",\n         \"ciclón\",\n         \"ciego\",\n         \"cielo\",\n         \"cien\",\n         \"cierto\",\n         \"cifra\",\n         \"cigarro\",\n         \"cima\",\n         \"cinco\",\n         \"cine\",\n         \"cinta\",\n         \"ciprés\",\n         \"circo\",\n         \"ciruela\",\n         \"cisne\",\n         \"cita\",\n         \"ciudad\",\n         \"clamor\",\n         \"clan\",\n         \"claro\",\n         \"clase\",\n         \"clave\",\n         \"cliente\",\n         \"clima\",\n         \"clínica\",\n         \"cobre\",\n         \"cocción\",\n         \"cochino\",\n         \"cocina\",\n         \"coco\",\n         \"código\",\n         \"codo\",\n         \"cofre\",\n         \"coger\",\n         \"cohete\",\n         \"cojín\",\n         \"cojo\",\n         \"cola\",\n         \"colcha\",\n         \"colegio\",\n         \"colgar\",\n         \"colina\",\n         \"collar\",\n         \"colmo\",\n         \"columna\",\n         \"combate\",\n         \"comer\",\n         \"comida\",\n         \"cómodo\",\n         \"compra\",\n         \"conde\",\n         \"conejo\",\n         \"conga\",\n         \"conocer\",\n         \"consejo\",\n         \"contar\",\n         \"copa\",\n         \"copia\",\n         \"corazón\",\n         \"corbata\",\n         \"corcho\",\n         \"cordón\",\n         \"corona\",\n         \"correr\",\n         \"coser\",\n         \"cosmos\",\n         \"costa\",\n         \"cráneo\",\n         \"cráter\",\n         \"crear\",\n         \"crecer\",\n         \"creído\",\n         \"crema\",\n         \"cría\",\n         \"crimen\",\n         \"cripta\",\n         \"crisis\",\n         \"cromo\",\n         \"crónica\",\n         \"croqueta\",\n         \"crudo\",\n         \"cruz\",\n         \"cuadro\",\n         \"cuarto\",\n         \"cuatro\",\n         \"cubo\",\n         \"cubrir\",\n         \"cuchara\",\n         \"cuello\",\n         \"cuento\",\n         \"cuerda\",\n         \"cuesta\",\n         \"cueva\",\n         \"cuidar\",\n         \"culebra\",\n         \"culpa\",\n         \"culto\",\n         \"cumbre\",\n         \"cumplir\",\n         \"cuna\",\n         \"cuneta\",\n         \"cuota\",\n         \"cupón\",\n         \"cúpula\",\n         \"curar\",\n         \"curioso\",\n         \"curso\",\n         \"curva\",\n         \"cutis\",\n         \"dama\",\n         \"danza\",\n         \"dar\",\n         \"dardo\",\n         \"dátil\",\n         \"deber\",\n         \"débil\",\n         \"década\",\n         \"decir\",\n         \"dedo\",\n         \"defensa\",\n         \"definir\",\n         \"dejar\",\n         \"delfín\",\n         \"delgado\",\n         \"delito\",\n         \"demora\",\n         \"denso\",\n         \"dental\",\n         \"deporte\",\n         \"derecho\",\n         \"derrota\",\n         \"desayuno\",\n         \"deseo\",\n         \"desfile\",\n         \"desnudo\",\n         \"destino\",\n         \"desvío\",\n         \"detalle\",\n         \"detener\",\n         \"deuda\",\n         \"día\",\n         \"diablo\",\n         \"diadema\",\n         \"diamante\",\n         \"diana\",\n         \"diario\",\n         \"dibujo\",\n         \"dictar\",\n         \"diente\",\n         \"dieta\",\n         \"diez\",\n         \"difícil\",\n         \"digno\",\n         \"dilema\",\n         \"diluir\",\n         \"dinero\",\n         \"directo\",\n         \"dirigir\",\n         \"disco\",\n         \"diseño\",\n         \"disfraz\",\n         \"diva\",\n         \"divino\",\n         \"doble\",\n         \"doce\",\n         \"dolor\",\n         \"domingo\",\n         \"don\",\n         \"donar\",\n         \"dorado\",\n         \"dormir\",\n         \"dorso\",\n         \"dos\",\n         \"dosis\",\n         \"dragón\",\n         \"droga\",\n         \"ducha\",\n         \"duda\",\n         \"duelo\",\n         \"dueño\",\n         \"dulce\",\n         \"dúo\",\n         \"duque\",\n         \"durar\",\n         \"dureza\",\n         \"duro\",\n         \"ébano\",\n         \"ebrio\",\n         \"echar\",\n         \"eco\",\n         \"ecuador\",\n         \"edad\",\n         \"edición\",\n         \"edificio\",\n         \"editor\",\n         \"educar\",\n         \"efecto\",\n         \"eficaz\",\n         \"eje\",\n         \"ejemplo\",\n         \"elefante\",\n         \"elegir\",\n         \"elemento\",\n         \"elevar\",\n         \"elipse\",\n         \"élite\",\n         \"elixir\",\n         \"elogio\",\n         \"eludir\",\n         \"embudo\",\n         \"emitir\",\n         \"emoción\",\n         \"empate\",\n         \"empeño\",\n         \"empleo\",\n         \"empresa\",\n         \"enano\",\n         \"encargo\",\n         \"enchufe\",\n         \"encía\",\n         \"enemigo\",\n         \"enero\",\n         \"enfado\",\n         \"enfermo\",\n         \"engaño\",\n         \"enigma\",\n         \"enlace\",\n         \"enorme\",\n         \"enredo\",\n         \"ensayo\",\n         \"enseñar\",\n         \"entero\",\n         \"entrar\",\n         \"envase\",\n         \"envío\",\n         \"época\",\n         \"equipo\",\n         \"erizo\",\n         \"escala\",\n         \"escena\",\n         \"escolar\",\n         \"escribir\",\n         \"escudo\",\n         \"esencia\",\n         \"esfera\",\n         \"esfuerzo\",\n         \"espada\",\n         \"espejo\",\n         \"espía\",\n         \"esposa\",\n         \"espuma\",\n         \"esquí\",\n         \"estar\",\n         \"este\",\n         \"estilo\",\n         \"estufa\",\n         \"etapa\",\n         \"eterno\",\n         \"ética\",\n         \"etnia\",\n         \"evadir\",\n         \"evaluar\",\n         \"evento\",\n         \"evitar\",\n         \"exacto\",\n         \"examen\",\n         \"exceso\",\n         \"excusa\",\n         \"exento\",\n         \"exigir\",\n         \"exilio\",\n         \"existir\",\n         \"éxito\",\n         \"experto\",\n         \"explicar\",\n         \"exponer\",\n         \"extremo\",\n         \"fábrica\",\n         \"fábula\",\n         \"fachada\",\n         \"fácil\",\n         \"factor\",\n         \"faena\",\n         \"faja\",\n         \"falda\",\n         \"fallo\",\n         \"falso\",\n         \"faltar\",\n         \"fama\",\n         \"familia\",\n         \"famoso\",\n         \"faraón\",\n         \"farmacia\",\n         \"farol\",\n         \"farsa\",\n         \"fase\",\n         \"fatiga\",\n         \"fauna\",\n         \"favor\",\n         \"fax\",\n         \"febrero\",\n         \"fecha\",\n         \"feliz\",\n         \"feo\",\n         \"feria\",\n         \"feroz\",\n         \"fértil\",\n         \"fervor\",\n         \"festín\",\n         \"fiable\",\n         \"fianza\",\n         \"fiar\",\n         \"fibra\",\n         \"ficción\",\n         \"ficha\",\n         \"fideo\",\n         \"fiebre\",\n         \"fiel\",\n         \"fiera\",\n         \"fiesta\",\n         \"figura\",\n         \"fijar\",\n         \"fijo\",\n         \"fila\",\n         \"filete\",\n         \"filial\",\n         \"filtro\",\n         \"fin\",\n         \"finca\",\n         \"fingir\",\n         \"finito\",\n         \"firma\",\n         \"flaco\",\n         \"flauta\",\n         \"flecha\",\n         \"flor\",\n         \"flota\",\n         \"fluir\",\n         \"flujo\",\n         \"flúor\",\n         \"fobia\",\n         \"foca\",\n         \"fogata\",\n         \"fogón\",\n         \"folio\",\n         \"folleto\",\n         \"fondo\",\n         \"forma\",\n         \"forro\",\n         \"fortuna\",\n         \"forzar\",\n         \"fosa\",\n         \"foto\",\n         \"fracaso\",\n         \"frágil\",\n         \"franja\",\n         \"frase\",\n         \"fraude\",\n         \"freír\",\n         \"freno\",\n         \"fresa\",\n         \"frío\",\n         \"frito\",\n         \"fruta\",\n         \"fuego\",\n         \"fuente\",\n         \"fuerza\",\n         \"fuga\",\n         \"fumar\",\n         \"función\",\n         \"funda\",\n         \"furgón\",\n         \"furia\",\n         \"fusil\",\n         \"fútbol\",\n         \"futuro\",\n         \"gacela\",\n         \"gafas\",\n         \"gaita\",\n         \"gajo\",\n         \"gala\",\n         \"galería\",\n         \"gallo\",\n         \"gamba\",\n         \"ganar\",\n         \"gancho\",\n         \"ganga\",\n         \"ganso\",\n         \"garaje\",\n         \"garza\",\n         \"gasolina\",\n         \"gastar\",\n         \"gato\",\n         \"gavilán\",\n         \"gemelo\",\n         \"gemir\",\n         \"gen\",\n         \"género\",\n         \"genio\",\n         \"gente\",\n         \"geranio\",\n         \"gerente\",\n         \"germen\",\n         \"gesto\",\n         \"gigante\",\n         \"gimnasio\",\n         \"girar\",\n         \"giro\",\n         \"glaciar\",\n         \"globo\",\n         \"gloria\",\n         \"gol\",\n         \"golfo\",\n         \"goloso\",\n         \"golpe\",\n         \"goma\",\n         \"gordo\",\n         \"gorila\",\n         \"gorra\",\n         \"gota\",\n         \"goteo\",\n         \"gozar\",\n         \"grada\",\n         \"gráfico\",\n         \"grano\",\n         \"grasa\",\n         \"gratis\",\n         \"grave\",\n         \"grieta\",\n         \"grillo\",\n         \"gripe\",\n         \"gris\",\n         \"grito\",\n         \"grosor\",\n         \"grúa\",\n         \"grueso\",\n         \"grumo\",\n         \"grupo\",\n         \"guante\",\n         \"guapo\",\n         \"guardia\",\n         \"guerra\",\n         \"guía\",\n         \"guiño\",\n         \"guion\",\n         \"guiso\",\n         \"guitarra\",\n         \"gusano\",\n         \"gustar\",\n         \"haber\",\n         \"hábil\",\n         \"hablar\",\n         \"hacer\",\n         \"hacha\",\n         \"hada\",\n         \"hallar\",\n         \"hamaca\",\n         \"harina\",\n         \"haz\",\n         \"hazaña\",\n         \"hebilla\",\n         \"hebra\",\n         \"hecho\",\n         \"helado\",\n         \"helio\",\n         \"hembra\",\n         \"herir\",\n         \"hermano\",\n         \"héroe\",\n         \"hervir\",\n         \"hielo\",\n         \"hierro\",\n         \"hígado\",\n         \"higiene\",\n         \"hijo\",\n         \"himno\",\n         \"historia\",\n         \"hocico\",\n         \"hogar\",\n         \"hoguera\",\n         \"hoja\",\n         \"hombre\",\n         \"hongo\",\n         \"honor\",\n         \"honra\",\n         \"hora\",\n         \"hormiga\",\n         \"horno\",\n         \"hostil\",\n         \"hoyo\",\n         \"hueco\",\n         \"huelga\",\n         \"huerta\",\n         \"hueso\",\n         \"huevo\",\n         \"huida\",\n         \"huir\",\n         \"humano\",\n         \"húmedo\",\n         \"humilde\",\n         \"humo\",\n         \"hundir\",\n         \"huracán\",\n         \"hurto\",\n         \"icono\",\n         \"ideal\",\n         \"idioma\",\n         \"ídolo\",\n         \"iglesia\",\n         \"iglú\",\n         \"igual\",\n         \"ilegal\",\n         \"ilusión\",\n         \"imagen\",\n         \"imán\",\n         \"imitar\",\n         \"impar\",\n         \"imperio\",\n         \"imponer\",\n         \"impulso\",\n         \"incapaz\",\n         \"índice\",\n         \"inerte\",\n         \"infiel\",\n         \"informe\",\n         \"ingenio\",\n         \"inicio\",\n         \"inmenso\",\n         \"inmune\",\n         \"innato\",\n         \"insecto\",\n         \"instante\",\n         \"interés\",\n         \"íntimo\",\n         \"intuir\",\n         \"inútil\",\n         \"invierno\",\n         \"ira\",\n         \"iris\",\n         \"ironía\",\n         \"isla\",\n         \"islote\",\n         \"jabalí\",\n         \"jabón\",\n         \"jamón\",\n         \"jarabe\",\n         \"jardín\",\n         \"jarra\",\n         \"jaula\",\n         \"jazmín\",\n         \"jefe\",\n         \"jeringa\",\n         \"jinete\",\n         \"jornada\",\n         \"joroba\",\n         \"joven\",\n         \"joya\",\n         \"juerga\",\n         \"jueves\",\n         \"juez\",\n         \"jugador\",\n         \"jugo\",\n         \"juguete\",\n         \"juicio\",\n         \"junco\",\n         \"jungla\",\n         \"junio\",\n         \"juntar\",\n         \"júpiter\",\n         \"jurar\",\n         \"justo\",\n         \"juvenil\",\n         \"juzgar\",\n         \"kilo\",\n         \"koala\",\n         \"labio\",\n         \"lacio\",\n         \"lacra\",\n         \"lado\",\n         \"ladrón\",\n         \"lagarto\",\n         \"lágrima\",\n         \"laguna\",\n         \"laico\",\n         \"lamer\",\n         \"lámina\",\n         \"lámpara\",\n         \"lana\",\n         \"lancha\",\n         \"langosta\",\n         \"lanza\",\n         \"lápiz\",\n         \"largo\",\n         \"larva\",\n         \"lástima\",\n         \"lata\",\n         \"látex\",\n         \"latir\",\n         \"laurel\",\n         \"lavar\",\n         \"lazo\",\n         \"leal\",\n         \"lección\",\n         \"leche\",\n         \"lector\",\n         \"leer\",\n         \"legión\",\n         \"legumbre\",\n         \"lejano\",\n         \"lengua\",\n         \"lento\",\n         \"leña\",\n         \"león\",\n         \"leopardo\",\n         \"lesión\",\n         \"letal\",\n         \"letra\",\n         \"leve\",\n         \"leyenda\",\n         \"libertad\",\n         \"libro\",\n         \"licor\",\n         \"líder\",\n         \"lidiar\",\n         \"lienzo\",\n         \"liga\",\n         \"ligero\",\n         \"lima\",\n         \"límite\",\n         \"limón\",\n         \"limpio\",\n         \"lince\",\n         \"lindo\",\n         \"línea\",\n         \"lingote\",\n         \"lino\",\n         \"linterna\",\n         \"líquido\",\n         \"liso\",\n         \"lista\",\n         \"litera\",\n         \"litio\",\n         \"litro\",\n         \"llaga\",\n         \"llama\",\n         \"llanto\",\n         \"llave\",\n         \"llegar\",\n         \"llenar\",\n         \"llevar\",\n         \"llorar\",\n         \"llover\",\n         \"lluvia\",\n         \"lobo\",\n         \"loción\",\n         \"loco\",\n         \"locura\",\n         \"lógica\",\n         \"logro\",\n         \"lombriz\",\n         \"lomo\",\n         \"lonja\",\n         \"lote\",\n         \"lucha\",\n         \"lucir\",\n         \"lugar\",\n         \"lujo\",\n         \"luna\",\n         \"lunes\",\n         \"lupa\",\n         \"lustro\",\n         \"luto\",\n         \"luz\",\n         \"maceta\",\n         \"macho\",\n         \"madera\",\n         \"madre\",\n         \"maduro\",\n         \"maestro\",\n         \"mafia\",\n         \"magia\",\n         \"mago\",\n         \"maíz\",\n         \"maldad\",\n         \"maleta\",\n         \"malla\",\n         \"malo\",\n         \"mamá\",\n         \"mambo\",\n         \"mamut\",\n         \"manco\",\n         \"mando\",\n         \"manejar\",\n         \"manga\",\n         \"maniquí\",\n         \"manjar\",\n         \"mano\",\n         \"manso\",\n         \"manta\",\n         \"mañana\",\n         \"mapa\",\n         \"máquina\",\n         \"mar\",\n         \"marco\",\n         \"marea\",\n         \"marfil\",\n         \"margen\",\n         \"marido\",\n         \"mármol\",\n         \"marrón\",\n         \"martes\",\n         \"marzo\",\n         \"masa\",\n         \"máscara\",\n         \"masivo\",\n         \"matar\",\n         \"materia\",\n         \"matiz\",\n         \"matriz\",\n         \"máximo\",\n         \"mayor\",\n         \"mazorca\",\n         \"mecha\",\n         \"medalla\",\n         \"medio\",\n         \"médula\",\n         \"mejilla\",\n         \"mejor\",\n         \"melena\",\n         \"melón\",\n         \"memoria\",\n         \"menor\",\n         \"mensaje\",\n         \"mente\",\n         \"menú\",\n         \"mercado\",\n         \"merengue\",\n         \"mérito\",\n         \"mes\",\n         \"mesón\",\n         \"meta\",\n         \"meter\",\n         \"método\",\n         \"metro\",\n         \"mezcla\",\n         \"miedo\",\n         \"miel\",\n         \"miembro\",\n         \"miga\",\n         \"mil\",\n         \"milagro\",\n         \"militar\",\n         \"millón\",\n         \"mimo\",\n         \"mina\",\n         \"minero\",\n         \"mínimo\",\n         \"minuto\",\n         \"miope\",\n         \"mirar\",\n         \"misa\",\n         \"miseria\",\n         \"misil\",\n         \"mismo\",\n         \"mitad\",\n         \"mito\",\n         \"mochila\",\n         \"moción\",\n         \"moda\",\n         \"modelo\",\n         \"moho\",\n         \"mojar\",\n         \"molde\",\n         \"moler\",\n         \"molino\",\n         \"momento\",\n         \"momia\",\n         \"monarca\",\n         \"moneda\",\n         \"monja\",\n         \"monto\",\n         \"moño\",\n         \"morada\",\n         \"morder\",\n         \"moreno\",\n         \"morir\",\n         \"morro\",\n         \"morsa\",\n         \"mortal\",\n         \"mosca\",\n         \"mostrar\",\n         \"motivo\",\n         \"mover\",\n         \"móvil\",\n         \"mozo\",\n         \"mucho\",\n         \"mudar\",\n         \"mueble\",\n         \"muela\",\n         \"muerte\",\n         \"muestra\",\n         \"mugre\",\n         \"mujer\",\n         \"mula\",\n         \"muleta\",\n         \"multa\",\n         \"mundo\",\n         \"muñeca\",\n         \"mural\",\n         \"muro\",\n         \"músculo\",\n         \"museo\",\n         \"musgo\",\n         \"música\",\n         \"muslo\",\n         \"nácar\",\n         \"nación\",\n         \"nadar\",\n         \"naipe\",\n         \"naranja\",\n         \"nariz\",\n         \"narrar\",\n         \"nasal\",\n         \"natal\",\n         \"nativo\",\n         \"natural\",\n         \"náusea\",\n         \"naval\",\n         \"nave\",\n         \"navidad\",\n         \"necio\",\n         \"néctar\",\n         \"negar\",\n         \"negocio\",\n         \"negro\",\n         \"neón\",\n         \"nervio\",\n         \"neto\",\n         \"neutro\",\n         \"nevar\",\n         \"nevera\",\n         \"nicho\",\n         \"nido\",\n         \"niebla\",\n         \"nieto\",\n         \"niñez\",\n         \"niño\",\n         \"nítido\",\n         \"nivel\",\n         \"nobleza\",\n         \"noche\",\n         \"nómina\",\n         \"noria\",\n         \"norma\",\n         \"norte\",\n         \"nota\",\n         \"noticia\",\n         \"novato\",\n         \"novela\",\n         \"novio\",\n         \"nube\",\n         \"nuca\",\n         \"núcleo\",\n         \"nudillo\",\n         \"nudo\",\n         \"nuera\",\n         \"nueve\",\n         \"nuez\",\n         \"nulo\",\n         \"número\",\n         \"nutria\",\n         \"oasis\",\n         \"obeso\",\n         \"obispo\",\n         \"objeto\",\n         \"obra\",\n         \"obrero\",\n         \"observar\",\n         \"obtener\",\n         \"obvio\",\n         \"oca\",\n         \"ocaso\",\n         \"océano\",\n         \"ochenta\",\n         \"ocho\",\n         \"ocio\",\n         \"ocre\",\n         \"octavo\",\n         \"octubre\",\n         \"oculto\",\n         \"ocupar\",\n         \"ocurrir\",\n         \"odiar\",\n         \"odio\",\n         \"odisea\",\n         \"oeste\",\n         \"ofensa\",\n         \"oferta\",\n         \"oficio\",\n         \"ofrecer\",\n         \"ogro\",\n         \"oído\",\n         \"oír\",\n         \"ojo\",\n         \"ola\",\n         \"oleada\",\n         \"olfato\",\n         \"olivo\",\n         \"olla\",\n         \"olmo\",\n         \"olor\",\n         \"olvido\",\n         \"ombligo\",\n         \"onda\",\n         \"onza\",\n         \"opaco\",\n         \"opción\",\n         \"ópera\",\n         \"opinar\",\n         \"oponer\",\n         \"optar\",\n         \"óptica\",\n         \"opuesto\",\n         \"oración\",\n         \"orador\",\n         \"oral\",\n         \"órbita\",\n         \"orca\",\n         \"orden\",\n         \"oreja\",\n         \"órgano\",\n         \"orgía\",\n         \"orgullo\",\n         \"oriente\",\n         \"origen\",\n         \"orilla\",\n         \"oro\",\n         \"orquesta\",\n         \"oruga\",\n         \"osadía\",\n         \"oscuro\",\n         \"osezno\",\n         \"oso\",\n         \"ostra\",\n         \"otoño\",\n         \"otro\",\n         \"oveja\",\n         \"óvulo\",\n         \"óxido\",\n         \"oxígeno\",\n         \"oyente\",\n         \"ozono\",\n         \"pacto\",\n         \"padre\",\n         \"paella\",\n         \"página\",\n         \"pago\",\n         \"país\",\n         \"pájaro\",\n         \"palabra\",\n         \"palco\",\n         \"paleta\",\n         \"pálido\",\n         \"palma\",\n         \"paloma\",\n         \"palpar\",\n         \"pan\",\n         \"panal\",\n         \"pánico\",\n         \"pantera\",\n         \"pañuelo\",\n         \"papá\",\n         \"papel\",\n         \"papilla\",\n         \"paquete\",\n         \"parar\",\n         \"parcela\",\n         \"pared\",\n         \"parir\",\n         \"paro\",\n         \"párpado\",\n         \"parque\",\n         \"párrafo\",\n         \"parte\",\n         \"pasar\",\n         \"paseo\",\n         \"pasión\",\n         \"paso\",\n         \"pasta\",\n         \"pata\",\n         \"patio\",\n         \"patria\",\n         \"pausa\",\n         \"pauta\",\n         \"pavo\",\n         \"payaso\",\n         \"peatón\",\n         \"pecado\",\n         \"pecera\",\n         \"pecho\",\n         \"pedal\",\n         \"pedir\",\n         \"pegar\",\n         \"peine\",\n         \"pelar\",\n         \"peldaño\",\n         \"pelea\",\n         \"peligro\",\n         \"pellejo\",\n         \"pelo\",\n         \"peluca\",\n         \"pena\",\n         \"pensar\",\n         \"peñón\",\n         \"peón\",\n         \"peor\",\n         \"pepino\",\n         \"pequeño\",\n         \"pera\",\n         \"percha\",\n         \"perder\",\n         \"pereza\",\n         \"perfil\",\n         \"perico\",\n         \"perla\",\n         \"permiso\",\n         \"perro\",\n         \"persona\",\n         \"pesa\",\n         \"pesca\",\n         \"pésimo\",\n         \"pestaña\",\n         \"pétalo\",\n         \"petróleo\",\n         \"pez\",\n         \"pezuña\",\n         \"picar\",\n         \"pichón\",\n         \"pie\",\n         \"piedra\",\n         \"pierna\",\n         \"pieza\",\n         \"pijama\",\n         \"pilar\",\n         \"piloto\",\n         \"pimienta\",\n         \"pino\",\n         \"pintor\",\n         \"pinza\",\n         \"piña\",\n         \"piojo\",\n         \"pipa\",\n         \"pirata\",\n         \"pisar\",\n         \"piscina\",\n         \"piso\",\n         \"pista\",\n         \"pitón\",\n         \"pizca\",\n         \"placa\",\n         \"plan\",\n         \"plata\",\n         \"playa\",\n         \"plaza\",\n         \"pleito\",\n         \"pleno\",\n         \"plomo\",\n         \"pluma\",\n         \"plural\",\n         \"pobre\",\n         \"poco\",\n         \"poder\",\n         \"podio\",\n         \"poema\",\n         \"poesía\",\n         \"poeta\",\n         \"polen\",\n         \"policía\",\n         \"pollo\",\n         \"polvo\",\n         \"pomada\",\n         \"pomelo\",\n         \"pomo\",\n         \"pompa\",\n         \"poner\",\n         \"porción\",\n         \"portal\",\n         \"posada\",\n         \"poseer\",\n         \"posible\",\n         \"poste\",\n         \"potencia\",\n         \"potro\",\n         \"pozo\",\n         \"prado\",\n         \"precoz\",\n         \"pregunta\",\n         \"premio\",\n         \"prensa\",\n         \"preso\",\n         \"previo\",\n         \"primo\",\n         \"príncipe\",\n         \"prisión\",\n         \"privar\",\n         \"proa\",\n         \"probar\",\n         \"proceso\",\n         \"producto\",\n         \"proeza\",\n         \"profesor\",\n         \"programa\",\n         \"prole\",\n         \"promesa\",\n         \"pronto\",\n         \"propio\",\n         \"próximo\",\n         \"prueba\",\n         \"público\",\n         \"puchero\",\n         \"pudor\",\n         \"pueblo\",\n         \"puerta\",\n         \"puesto\",\n         \"pulga\",\n         \"pulir\",\n         \"pulmón\",\n         \"pulpo\",\n         \"pulso\",\n         \"puma\",\n         \"punto\",\n         \"puñal\",\n         \"puño\",\n         \"pupa\",\n         \"pupila\",\n         \"puré\",\n         \"quedar\",\n         \"queja\",\n         \"quemar\",\n         \"querer\",\n         \"queso\",\n         \"quieto\",\n         \"química\",\n         \"quince\",\n         \"quitar\",\n         \"rábano\",\n         \"rabia\",\n         \"rabo\",\n         \"ración\",\n         \"radical\",\n         \"raíz\",\n         \"rama\",\n         \"rampa\",\n         \"rancho\",\n         \"rango\",\n         \"rapaz\",\n         \"rápido\",\n         \"rapto\",\n         \"rasgo\",\n         \"raspa\",\n         \"rato\",\n         \"rayo\",\n         \"raza\",\n         \"razón\",\n         \"reacción\",\n         \"realidad\",\n         \"rebaño\",\n         \"rebote\",\n         \"recaer\",\n         \"receta\",\n         \"rechazo\",\n         \"recoger\",\n         \"recreo\",\n         \"recto\",\n         \"recurso\",\n         \"red\",\n         \"redondo\",\n         \"reducir\",\n         \"reflejo\",\n         \"reforma\",\n         \"refrán\",\n         \"refugio\",\n         \"regalo\",\n         \"regir\",\n         \"regla\",\n         \"regreso\",\n         \"rehén\",\n         \"reino\",\n         \"reír\",\n         \"reja\",\n         \"relato\",\n         \"relevo\",\n         \"relieve\",\n         \"relleno\",\n         \"reloj\",\n         \"remar\",\n         \"remedio\",\n         \"remo\",\n         \"rencor\",\n         \"rendir\",\n         \"renta\",\n         \"reparto\",\n         \"repetir\",\n         \"reposo\",\n         \"reptil\",\n         \"res\",\n         \"rescate\",\n         \"resina\",\n         \"respeto\",\n         \"resto\",\n         \"resumen\",\n         \"retiro\",\n         \"retorno\",\n         \"retrato\",\n         \"reunir\",\n         \"revés\",\n         \"revista\",\n         \"rey\",\n         \"rezar\",\n         \"rico\",\n         \"riego\",\n         \"rienda\",\n         \"riesgo\",\n         \"rifa\",\n         \"rígido\",\n         \"rigor\",\n         \"rincón\",\n         \"riñón\",\n         \"río\",\n         \"riqueza\",\n         \"risa\",\n         \"ritmo\",\n         \"rito\",\n         \"rizo\",\n         \"roble\",\n         \"roce\",\n         \"rociar\",\n         \"rodar\",\n         \"rodeo\",\n         \"rodilla\",\n         \"roer\",\n         \"rojizo\",\n         \"rojo\",\n         \"romero\",\n         \"romper\",\n         \"ron\",\n         \"ronco\",\n         \"ronda\",\n         \"ropa\",\n         \"ropero\",\n         \"rosa\",\n         \"rosca\",\n         \"rostro\",\n         \"rotar\",\n         \"rubí\",\n         \"rubor\",\n         \"rudo\",\n         \"rueda\",\n         \"rugir\",\n         \"ruido\",\n         \"ruina\",\n         \"ruleta\",\n         \"rulo\",\n         \"rumbo\",\n         \"rumor\",\n         \"ruptura\",\n         \"ruta\",\n         \"rutina\",\n         \"sábado\",\n         \"saber\",\n         \"sabio\",\n         \"sable\",\n         \"sacar\",\n         \"sagaz\",\n         \"sagrado\",\n         \"sala\",\n         \"saldo\",\n         \"salero\",\n         \"salir\",\n         \"salmón\",\n         \"salón\",\n         \"salsa\",\n         \"salto\",\n         \"salud\",\n         \"salvar\",\n         \"samba\",\n         \"sanción\",\n         \"sandía\",\n         \"sanear\",\n         \"sangre\",\n         \"sanidad\",\n         \"sano\",\n         \"santo\",\n         \"sapo\",\n         \"saque\",\n         \"sardina\",\n         \"sartén\",\n         \"sastre\",\n         \"satán\",\n         \"sauna\",\n         \"saxofón\",\n         \"sección\",\n         \"seco\",\n         \"secreto\",\n         \"secta\",\n         \"sed\",\n         \"seguir\",\n         \"seis\",\n         \"sello\",\n         \"selva\",\n         \"semana\",\n         \"semilla\",\n         \"senda\",\n         \"sensor\",\n         \"señal\",\n         \"señor\",\n         \"separar\",\n         \"sepia\",\n         \"sequía\",\n         \"ser\",\n         \"serie\",\n         \"sermón\",\n         \"servir\",\n         \"sesenta\",\n         \"sesión\",\n         \"seta\",\n         \"setenta\",\n         \"severo\",\n         \"sexo\",\n         \"sexto\",\n         \"sidra\",\n         \"siesta\",\n         \"siete\",\n         \"siglo\",\n         \"signo\",\n         \"sílaba\",\n         \"silbar\",\n         \"silencio\",\n         \"silla\",\n         \"símbolo\",\n         \"simio\",\n         \"sirena\",\n         \"sistema\",\n         \"sitio\",\n         \"situar\",\n         \"sobre\",\n         \"socio\",\n         \"sodio\",\n         \"sol\",\n         \"solapa\",\n         \"soldado\",\n         \"soledad\",\n         \"sólido\",\n         \"soltar\",\n         \"solución\",\n         \"sombra\",\n         \"sondeo\",\n         \"sonido\",\n         \"sonoro\",\n         \"sonrisa\",\n         \"sopa\",\n         \"soplar\",\n         \"soporte\",\n         \"sordo\",\n         \"sorpresa\",\n         \"sorteo\",\n         \"sostén\",\n         \"sótano\",\n         \"suave\",\n         \"subir\",\n         \"suceso\",\n         \"sudor\",\n         \"suegra\",\n         \"suelo\",\n         \"sueño\",\n         \"suerte\",\n         \"sufrir\",\n         \"sujeto\",\n         \"sultán\",\n         \"sumar\",\n         \"superar\",\n         \"suplir\",\n         \"suponer\",\n         \"supremo\",\n         \"sur\",\n         \"surco\",\n         \"sureño\",\n         \"surgir\",\n         \"susto\",\n         \"sutil\",\n         \"tabaco\",\n         \"tabique\",\n         \"tabla\",\n         \"tabú\",\n         \"taco\",\n         \"tacto\",\n         \"tajo\",\n         \"talar\",\n         \"talco\",\n         \"talento\",\n         \"talla\",\n         \"talón\",\n         \"tamaño\",\n         \"tambor\",\n         \"tango\",\n         \"tanque\",\n         \"tapa\",\n         \"tapete\",\n         \"tapia\",\n         \"tapón\",\n         \"taquilla\",\n         \"tarde\",\n         \"tarea\",\n         \"tarifa\",\n         \"tarjeta\",\n         \"tarot\",\n         \"tarro\",\n         \"tarta\",\n         \"tatuaje\",\n         \"tauro\",\n         \"taza\",\n         \"tazón\",\n         \"teatro\",\n         \"techo\",\n         \"tecla\",\n         \"técnica\",\n         \"tejado\",\n         \"tejer\",\n         \"tejido\",\n         \"tela\",\n         \"teléfono\",\n         \"tema\",\n         \"temor\",\n         \"templo\",\n         \"tenaz\",\n         \"tender\",\n         \"tener\",\n         \"tenis\",\n         \"tenso\",\n         \"teoría\",\n         \"terapia\",\n         \"terco\",\n         \"término\",\n         \"ternura\",\n         \"terror\",\n         \"tesis\",\n         \"tesoro\",\n         \"testigo\",\n         \"tetera\",\n         \"texto\",\n         \"tez\",\n         \"tibio\",\n         \"tiburón\",\n         \"tiempo\",\n         \"tienda\",\n         \"tierra\",\n         \"tieso\",\n         \"tigre\",\n         \"tijera\",\n         \"tilde\",\n         \"timbre\",\n         \"tímido\",\n         \"timo\",\n         \"tinta\",\n         \"tío\",\n         \"típico\",\n         \"tipo\",\n         \"tira\",\n         \"tirón\",\n         \"titán\",\n         \"títere\",\n         \"título\",\n         \"tiza\",\n         \"toalla\",\n         \"tobillo\",\n         \"tocar\",\n         \"tocino\",\n         \"todo\",\n         \"toga\",\n         \"toldo\",\n         \"tomar\",\n         \"tono\",\n         \"tonto\",\n         \"topar\",\n         \"tope\",\n         \"toque\",\n         \"tórax\",\n         \"torero\",\n         \"tormenta\",\n         \"torneo\",\n         \"toro\",\n         \"torpedo\",\n         \"torre\",\n         \"torso\",\n         \"tortuga\",\n         \"tos\",\n         \"tosco\",\n         \"toser\",\n         \"tóxico\",\n         \"trabajo\",\n         \"tractor\",\n         \"traer\",\n         \"tráfico\",\n         \"trago\",\n         \"traje\",\n         \"tramo\",\n         \"trance\",\n         \"trato\",\n         \"trauma\",\n         \"trazar\",\n         \"trébol\",\n         \"tregua\",\n         \"treinta\",\n         \"tren\",\n         \"trepar\",\n         \"tres\",\n         \"tribu\",\n         \"trigo\",\n         \"tripa\",\n         \"triste\",\n         \"triunfo\",\n         \"trofeo\",\n         \"trompa\",\n         \"tronco\",\n         \"tropa\",\n         \"trote\",\n         \"trozo\",\n         \"truco\",\n         \"trueno\",\n         \"trufa\",\n         \"tubería\",\n         \"tubo\",\n         \"tuerto\",\n         \"tumba\",\n         \"tumor\",\n         \"túnel\",\n         \"túnica\",\n         \"turbina\",\n         \"turismo\",\n         \"turno\",\n         \"tutor\",\n         \"ubicar\",\n         \"úlcera\",\n         \"umbral\",\n         \"unidad\",\n         \"unir\",\n         \"universo\",\n         \"uno\",\n         \"untar\",\n         \"uña\",\n         \"urbano\",\n         \"urbe\",\n         \"urgente\",\n         \"urna\",\n         \"usar\",\n         \"usuario\",\n         \"útil\",\n         \"utopía\",\n         \"uva\",\n         \"vaca\",\n         \"vacío\",\n         \"vacuna\",\n         \"vagar\",\n         \"vago\",\n         \"vaina\",\n         \"vajilla\",\n         \"vale\",\n         \"válido\",\n         \"valle\",\n         \"valor\",\n         \"válvula\",\n         \"vampiro\",\n         \"vara\",\n         \"variar\",\n         \"varón\",\n         \"vaso\",\n         \"vecino\",\n         \"vector\",\n         \"vehículo\",\n         \"veinte\",\n         \"vejez\",\n         \"vela\",\n         \"velero\",\n         \"veloz\",\n         \"vena\",\n         \"vencer\",\n         \"venda\",\n         \"veneno\",\n         \"vengar\",\n         \"venir\",\n         \"venta\",\n         \"venus\",\n         \"ver\",\n         \"verano\",\n         \"verbo\",\n         \"verde\",\n         \"vereda\",\n         \"verja\",\n         \"verso\",\n         \"verter\",\n         \"vía\",\n         \"viaje\",\n         \"vibrar\",\n         \"vicio\",\n         \"víctima\",\n         \"vida\",\n         \"vídeo\",\n         \"vidrio\",\n         \"viejo\",\n         \"viernes\",\n         \"vigor\",\n         \"vil\",\n         \"villa\",\n         \"vinagre\",\n         \"vino\",\n         \"viñedo\",\n         \"violín\",\n         \"viral\",\n         \"virgo\",\n         \"virtud\",\n         \"visor\",\n         \"víspera\",\n         \"vista\",\n         \"vitamina\",\n         \"viudo\",\n         \"vivaz\",\n         \"vivero\",\n         \"vivir\",\n         \"vivo\",\n         \"volcán\",\n         \"volumen\",\n         \"volver\",\n         \"voraz\",\n         \"votar\",\n         \"voto\",\n         \"voz\",\n         \"vuelo\",\n         \"vulgar\",\n         \"yacer\",\n         \"yate\",\n         \"yegua\",\n         \"yema\",\n         \"yerno\",\n         \"yeso\",\n         \"yodo\",\n         \"yoga\",\n         \"yogur\",\n         \"zafiro\",\n         \"zanja\",\n         \"zapato\",\n         \"zarza\",\n         \"zona\",\n         \"zorro\",\n         \"zumo\",\n         \"zurdo\"}};\n\nconst dictionary ja =\n    {\n        {\"あいこくしん\",\n         \"あいさつ\",\n         \"あいだ\",\n         \"あおぞら\",\n         \"あかちゃん\",\n         \"あきる\",\n         \"あけがた\",\n         \"あける\",\n         \"あこがれる\",\n         \"あさい\",\n         \"あさひ\",\n         \"あしあと\",\n         \"あじわう\",\n         \"あずかる\",\n         \"あずき\",\n         \"あそぶ\",\n         \"あたえる\",\n         \"あたためる\",\n         \"あたりまえ\",\n         \"あたる\",\n         \"あつい\",\n         \"あつかう\",\n         \"あっしゅく\",\n         \"あつまり\",\n         \"あつめる\",\n         \"あてな\",\n         \"あてはまる\",\n         \"あひる\",\n         \"あぶら\",\n         \"あぶる\",\n         \"あふれる\",\n         \"あまい\",\n         \"あまど\",\n         \"あまやかす\",\n         \"あまり\",\n         \"あみもの\",\n         \"あめりか\",\n         \"あやまる\",\n         \"あゆむ\",\n         \"あらいぐま\",\n         \"あらし\",\n         \"あらすじ\",\n         \"あらためる\",\n         \"あらゆる\",\n         \"あらわす\",\n         \"ありがとう\",\n         \"あわせる\",\n         \"あわてる\",\n         \"あんい\",\n         \"あんがい\",\n         \"あんこ\",\n         \"あんぜん\",\n         \"あんてい\",\n         \"あんない\",\n         \"あんまり\",\n         \"いいだす\",\n         \"いおん\",\n         \"いがい\",\n         \"いがく\",\n         \"いきおい\",\n         \"いきなり\",\n         \"いきもの\",\n         \"いきる\",\n         \"いくじ\",\n         \"いくぶん\",\n         \"いけばな\",\n         \"いけん\",\n         \"いこう\",\n         \"いこく\",\n         \"いこつ\",\n         \"いさましい\",\n         \"いさん\",\n         \"いしき\",\n         \"いじゅう\",\n         \"いじょう\",\n         \"いじわる\",\n         \"いずみ\",\n         \"いずれ\",\n         \"いせい\",\n         \"いせえび\",\n         \"いせかい\",\n         \"いせき\",\n         \"いぜん\",\n         \"いそうろう\",\n         \"いそがしい\",\n         \"いだい\",\n         \"いだく\",\n         \"いたずら\",\n         \"いたみ\",\n         \"いたりあ\",\n         \"いちおう\",\n         \"いちじ\",\n         \"いちど\",\n         \"いちば\",\n         \"いちぶ\",\n         \"いちりゅう\",\n         \"いつか\",\n         \"いっしゅん\",\n         \"いっせい\",\n         \"いっそう\",\n         \"いったん\",\n         \"いっち\",\n         \"いってい\",\n         \"いっぽう\",\n         \"いてざ\",\n         \"いてん\",\n         \"いどう\",\n         \"いとこ\",\n         \"いない\",\n         \"いなか\",\n         \"いねむり\",\n         \"いのち\",\n         \"いのる\",\n         \"いはつ\",\n         \"いばる\",\n         \"いはん\",\n         \"いびき\",\n         \"いひん\",\n         \"いふく\",\n         \"いへん\",\n         \"いほう\",\n         \"いみん\",\n         \"いもうと\",\n         \"いもたれ\",\n         \"いもり\",\n         \"いやがる\",\n         \"いやす\",\n         \"いよかん\",\n         \"いよく\",\n         \"いらい\",\n         \"いらすと\",\n         \"いりぐち\",\n         \"いりょう\",\n         \"いれい\",\n         \"いれもの\",\n         \"いれる\",\n         \"いろえんぴつ\",\n         \"いわい\",\n         \"いわう\",\n         \"いわかん\",\n         \"いわば\",\n         \"いわゆる\",\n         \"いんげんまめ\",\n         \"いんさつ\",\n         \"いんしょう\",\n         \"いんよう\",\n         \"うえき\",\n         \"うえる\",\n         \"うおざ\",\n         \"うがい\",\n         \"うかぶ\",\n         \"うかべる\",\n         \"うきわ\",\n         \"うくらいな\",\n         \"うくれれ\",\n         \"うけたまわる\",\n         \"うけつけ\",\n         \"うけとる\",\n         \"うけもつ\",\n         \"うける\",\n         \"うごかす\",\n         \"うごく\",\n         \"うこん\",\n         \"うさぎ\",\n         \"うしなう\",\n         \"うしろがみ\",\n         \"うすい\",\n         \"うすぎ\",\n         \"うすぐらい\",\n         \"うすめる\",\n         \"うせつ\",\n         \"うちあわせ\",\n         \"うちがわ\",\n         \"うちき\",\n         \"うちゅう\",\n         \"うっかり\",\n         \"うつくしい\",\n         \"うったえる\",\n         \"うつる\",\n         \"うどん\",\n         \"うなぎ\",\n         \"うなじ\",\n         \"うなずく\",\n         \"うなる\",\n         \"うねる\",\n         \"うのう\",\n         \"うぶげ\",\n         \"うぶごえ\",\n         \"うまれる\",\n         \"うめる\",\n         \"うもう\",\n         \"うやまう\",\n         \"うよく\",\n         \"うらがえす\",\n         \"うらぐち\",\n         \"うらない\",\n         \"うりあげ\",\n         \"うりきれ\",\n         \"うるさい\",\n         \"うれしい\",\n         \"うれゆき\",\n         \"うれる\",\n         \"うろこ\",\n         \"うわき\",\n         \"うわさ\",\n         \"うんこう\",\n         \"うんちん\",\n         \"うんてん\",\n         \"うんどう\",\n         \"えいえん\",\n         \"えいが\",\n         \"えいきょう\",\n         \"えいご\",\n         \"えいせい\",\n         \"えいぶん\",\n         \"えいよう\",\n         \"えいわ\",\n         \"えおり\",\n         \"えがお\",\n         \"えがく\",\n         \"えきたい\",\n         \"えくせる\",\n         \"えしゃく\",\n         \"えすて\",\n         \"えつらん\",\n         \"えのぐ\",\n         \"えほうまき\",\n         \"えほん\",\n         \"えまき\",\n         \"えもじ\",\n         \"えもの\",\n         \"えらい\",\n         \"えらぶ\",\n         \"えりあ\",\n         \"えんえん\",\n         \"えんかい\",\n         \"えんぎ\",\n         \"えんげき\",\n         \"えんしゅう\",\n         \"えんぜつ\",\n         \"えんそく\",\n         \"えんちょう\",\n         \"えんとつ\",\n         \"おいかける\",\n         \"おいこす\",\n         \"おいしい\",\n         \"おいつく\",\n         \"おうえん\",\n         \"おうさま\",\n         \"おうじ\",\n         \"おうせつ\",\n         \"おうたい\",\n         \"おうふく\",\n         \"おうべい\",\n         \"おうよう\",\n         \"おえる\",\n         \"おおい\",\n         \"おおう\",\n         \"おおどおり\",\n         \"おおや\",\n         \"おおよそ\",\n         \"おかえり\",\n         \"おかず\",\n         \"おがむ\",\n         \"おかわり\",\n         \"おぎなう\",\n         \"おきる\",\n         \"おくさま\",\n         \"おくじょう\",\n         \"おくりがな\",\n         \"おくる\",\n         \"おくれる\",\n         \"おこす\",\n         \"おこなう\",\n         \"おこる\",\n         \"おさえる\",\n         \"おさない\",\n         \"おさめる\",\n         \"おしいれ\",\n         \"おしえる\",\n         \"おじぎ\",\n         \"おじさん\",\n         \"おしゃれ\",\n         \"おそらく\",\n         \"おそわる\",\n         \"おたがい\",\n         \"おたく\",\n         \"おだやか\",\n         \"おちつく\",\n         \"おっと\",\n         \"おつり\",\n         \"おでかけ\",\n         \"おとしもの\",\n         \"おとなしい\",\n         \"おどり\",\n         \"おどろかす\",\n         \"おばさん\",\n         \"おまいり\",\n         \"おめでとう\",\n         \"おもいで\",\n         \"おもう\",\n         \"おもたい\",\n         \"おもちゃ\",\n         \"おやつ\",\n         \"おやゆび\",\n         \"およぼす\",\n         \"おらんだ\",\n         \"おろす\",\n         \"おんがく\",\n         \"おんけい\",\n         \"おんしゃ\",\n         \"おんせん\",\n         \"おんだん\",\n         \"おんちゅう\",\n         \"おんどけい\",\n         \"かあつ\",\n         \"かいが\",\n         \"がいき\",\n         \"がいけん\",\n         \"がいこう\",\n         \"かいさつ\",\n         \"かいしゃ\",\n         \"かいすいよく\",\n         \"かいぜん\",\n         \"かいぞうど\",\n         \"かいつう\",\n         \"かいてん\",\n         \"かいとう\",\n         \"かいふく\",\n         \"がいへき\",\n         \"かいほう\",\n         \"かいよう\",\n         \"がいらい\",\n         \"かいわ\",\n         \"かえる\",\n         \"かおり\",\n         \"かかえる\",\n         \"かがく\",\n         \"かがし\",\n         \"かがみ\",\n         \"かくご\",\n         \"かくとく\",\n         \"かざる\",\n         \"がぞう\",\n         \"かたい\",\n         \"かたち\",\n         \"がちょう\",\n         \"がっきゅう\",\n         \"がっこう\",\n         \"がっさん\",\n         \"がっしょう\",\n         \"かなざわし\",\n         \"かのう\",\n         \"がはく\",\n         \"かぶか\",\n         \"かほう\",\n         \"かほご\",\n         \"かまう\",\n         \"かまぼこ\",\n         \"かめれおん\",\n         \"かゆい\",\n         \"かようび\",\n         \"からい\",\n         \"かるい\",\n         \"かろう\",\n         \"かわく\",\n         \"かわら\",\n         \"がんか\",\n         \"かんけい\",\n         \"かんこう\",\n         \"かんしゃ\",\n         \"かんそう\",\n         \"かんたん\",\n         \"かんち\",\n         \"がんばる\",\n         \"きあい\",\n         \"きあつ\",\n         \"きいろ\",\n         \"ぎいん\",\n         \"きうい\",\n         \"きうん\",\n         \"きえる\",\n         \"きおう\",\n         \"きおく\",\n         \"きおち\",\n         \"きおん\",\n         \"きかい\",\n         \"きかく\",\n         \"きかんしゃ\",\n         \"ききて\",\n         \"きくばり\",\n         \"きくらげ\",\n         \"きけんせい\",\n         \"きこう\",\n         \"きこえる\",\n         \"きこく\",\n         \"きさい\",\n         \"きさく\",\n         \"きさま\",\n         \"きさらぎ\",\n         \"ぎじかがく\",\n         \"ぎしき\",\n         \"ぎじたいけん\",\n         \"ぎじにってい\",\n         \"ぎじゅつしゃ\",\n         \"きすう\",\n         \"きせい\",\n         \"きせき\",\n         \"きせつ\",\n         \"きそう\",\n         \"きぞく\",\n         \"きぞん\",\n         \"きたえる\",\n         \"きちょう\",\n         \"きつえん\",\n         \"ぎっちり\",\n         \"きつつき\",\n         \"きつね\",\n         \"きてい\",\n         \"きどう\",\n         \"きどく\",\n         \"きない\",\n         \"きなが\",\n         \"きなこ\",\n         \"きぬごし\",\n         \"きねん\",\n         \"きのう\",\n         \"きのした\",\n         \"きはく\",\n         \"きびしい\",\n         \"きひん\",\n         \"きふく\",\n         \"きぶん\",\n         \"きぼう\",\n         \"きほん\",\n         \"きまる\",\n         \"きみつ\",\n         \"きむずかしい\",\n         \"きめる\",\n         \"きもだめし\",\n         \"きもち\",\n         \"きもの\",\n         \"きゃく\",\n         \"きやく\",\n         \"ぎゅうにく\",\n         \"きよう\",\n         \"きょうりゅう\",\n         \"きらい\",\n         \"きらく\",\n         \"きりん\",\n         \"きれい\",\n         \"きれつ\",\n         \"きろく\",\n         \"ぎろん\",\n         \"きわめる\",\n         \"ぎんいろ\",\n         \"きんかくじ\",\n         \"きんじょ\",\n         \"きんようび\",\n         \"ぐあい\",\n         \"くいず\",\n         \"くうかん\",\n         \"くうき\",\n         \"くうぐん\",\n         \"くうこう\",\n         \"ぐうせい\",\n         \"くうそう\",\n         \"ぐうたら\",\n         \"くうふく\",\n         \"くうぼ\",\n         \"くかん\",\n         \"くきょう\",\n         \"くげん\",\n         \"ぐこう\",\n         \"くさい\",\n         \"くさき\",\n         \"くさばな\",\n         \"くさる\",\n         \"くしゃみ\",\n         \"くしょう\",\n         \"くすのき\",\n         \"くすりゆび\",\n         \"くせげ\",\n         \"くせん\",\n         \"ぐたいてき\",\n         \"くださる\",\n         \"くたびれる\",\n         \"くちこみ\",\n         \"くちさき\",\n         \"くつした\",\n         \"ぐっすり\",\n         \"くつろぐ\",\n         \"くとうてん\",\n         \"くどく\",\n         \"くなん\",\n         \"くねくね\",\n         \"くのう\",\n         \"くふう\",\n         \"くみあわせ\",\n         \"くみたてる\",\n         \"くめる\",\n         \"くやくしょ\",\n         \"くらす\",\n         \"くらべる\",\n         \"くるま\",\n         \"くれる\",\n         \"くろう\",\n         \"くわしい\",\n         \"ぐんかん\",\n         \"ぐんしょく\",\n         \"ぐんたい\",\n         \"ぐんて\",\n         \"けあな\",\n         \"けいかく\",\n         \"けいけん\",\n         \"けいこ\",\n         \"けいさつ\",\n         \"げいじゅつ\",\n         \"けいたい\",\n         \"げいのうじん\",\n         \"けいれき\",\n         \"けいろ\",\n         \"けおとす\",\n         \"けおりもの\",\n         \"げきか\",\n         \"げきげん\",\n         \"げきだん\",\n         \"げきちん\",\n         \"げきとつ\",\n         \"げきは\",\n         \"げきやく\",\n         \"げこう\",\n         \"げこくじょう\",\n         \"げざい\",\n         \"けさき\",\n         \"げざん\",\n         \"けしき\",\n         \"けしごむ\",\n         \"けしょう\",\n         \"げすと\",\n         \"けたば\",\n         \"けちゃっぷ\",\n         \"けちらす\",\n         \"けつあつ\",\n         \"けつい\",\n         \"けつえき\",\n         \"けっこん\",\n         \"けつじょ\",\n         \"けっせき\",\n         \"けってい\",\n         \"けつまつ\",\n         \"げつようび\",\n         \"げつれい\",\n         \"けつろん\",\n         \"げどく\",\n         \"けとばす\",\n         \"けとる\",\n         \"けなげ\",\n         \"けなす\",\n         \"けなみ\",\n         \"けぬき\",\n         \"げねつ\",\n         \"けねん\",\n         \"けはい\",\n         \"げひん\",\n         \"けぶかい\",\n         \"げぼく\",\n         \"けまり\",\n         \"けみかる\",\n         \"けむし\",\n         \"けむり\",\n         \"けもの\",\n         \"けらい\",\n         \"けろけろ\",\n         \"けわしい\",\n         \"けんい\",\n         \"けんえつ\",\n         \"けんお\",\n         \"けんか\",\n         \"げんき\",\n         \"けんげん\",\n         \"けんこう\",\n         \"けんさく\",\n         \"けんしゅう\",\n         \"けんすう\",\n         \"げんそう\",\n         \"けんちく\",\n         \"けんてい\",\n         \"けんとう\",\n         \"けんない\",\n         \"けんにん\",\n         \"げんぶつ\",\n         \"けんま\",\n         \"けんみん\",\n         \"けんめい\",\n         \"けんらん\",\n         \"けんり\",\n         \"こあくま\",\n         \"こいぬ\",\n         \"こいびと\",\n         \"ごうい\",\n         \"こうえん\",\n         \"こうおん\",\n         \"こうかん\",\n         \"ごうきゅう\",\n         \"ごうけい\",\n         \"こうこう\",\n         \"こうさい\",\n         \"こうじ\",\n         \"こうすい\",\n         \"ごうせい\",\n         \"こうそく\",\n         \"こうたい\",\n         \"こうちゃ\",\n         \"こうつう\",\n         \"こうてい\",\n         \"こうどう\",\n         \"こうない\",\n         \"こうはい\",\n         \"ごうほう\",\n         \"ごうまん\",\n         \"こうもく\",\n         \"こうりつ\",\n         \"こえる\",\n         \"こおり\",\n         \"ごかい\",\n         \"ごがつ\",\n         \"ごかん\",\n         \"こくご\",\n         \"こくさい\",\n         \"こくとう\",\n         \"こくない\",\n         \"こくはく\",\n         \"こぐま\",\n         \"こけい\",\n         \"こける\",\n         \"ここのか\",\n         \"こころ\",\n         \"こさめ\",\n         \"こしつ\",\n         \"こすう\",\n         \"こせい\",\n         \"こせき\",\n         \"こぜん\",\n         \"こそだて\",\n         \"こたい\",\n         \"こたえる\",\n         \"こたつ\",\n         \"こちょう\",\n         \"こっか\",\n         \"こつこつ\",\n         \"こつばん\",\n         \"こつぶ\",\n         \"こてい\",\n         \"こてん\",\n         \"ことがら\",\n         \"ことし\",\n         \"ことば\",\n         \"ことり\",\n         \"こなごな\",\n         \"こねこね\",\n         \"このまま\",\n         \"このみ\",\n         \"このよ\",\n         \"ごはん\",\n         \"こひつじ\",\n         \"こふう\",\n         \"こふん\",\n         \"こぼれる\",\n         \"ごまあぶら\",\n         \"こまかい\",\n         \"ごますり\",\n         \"こまつな\",\n         \"こまる\",\n         \"こむぎこ\",\n         \"こもじ\",\n         \"こもち\",\n         \"こもの\",\n         \"こもん\",\n         \"こやく\",\n         \"こやま\",\n         \"こゆう\",\n         \"こゆび\",\n         \"こよい\",\n         \"こよう\",\n         \"こりる\",\n         \"これくしょん\",\n         \"ころっけ\",\n         \"こわもて\",\n         \"こわれる\",\n         \"こんいん\",\n         \"こんかい\",\n         \"こんき\",\n         \"こんしゅう\",\n         \"こんすい\",\n         \"こんだて\",\n         \"こんとん\",\n         \"こんなん\",\n         \"こんびに\",\n         \"こんぽん\",\n         \"こんまけ\",\n         \"こんや\",\n         \"こんれい\",\n         \"こんわく\",\n         \"ざいえき\",\n         \"さいかい\",\n         \"さいきん\",\n         \"ざいげん\",\n         \"ざいこ\",\n         \"さいしょ\",\n         \"さいせい\",\n         \"ざいたく\",\n         \"ざいちゅう\",\n         \"さいてき\",\n         \"ざいりょう\",\n         \"さうな\",\n         \"さかいし\",\n         \"さがす\",\n         \"さかな\",\n         \"さかみち\",\n         \"さがる\",\n         \"さぎょう\",\n         \"さくし\",\n         \"さくひん\",\n         \"さくら\",\n         \"さこく\",\n         \"さこつ\",\n         \"さずかる\",\n         \"ざせき\",\n         \"さたん\",\n         \"さつえい\",\n         \"ざつおん\",\n         \"ざっか\",\n         \"ざつがく\",\n         \"さっきょく\",\n         \"ざっし\",\n         \"さつじん\",\n         \"ざっそう\",\n         \"さつたば\",\n         \"さつまいも\",\n         \"さてい\",\n         \"さといも\",\n         \"さとう\",\n         \"さとおや\",\n         \"さとし\",\n         \"さとる\",\n         \"さのう\",\n         \"さばく\",\n         \"さびしい\",\n         \"さべつ\",\n         \"さほう\",\n         \"さほど\",\n         \"さます\",\n         \"さみしい\",\n         \"さみだれ\",\n         \"さむけ\",\n         \"さめる\",\n         \"さやえんどう\",\n         \"さゆう\",\n         \"さよう\",\n         \"さよく\",\n         \"さらだ\",\n         \"ざるそば\",\n         \"さわやか\",\n         \"さわる\",\n         \"さんいん\",\n         \"さんか\",\n         \"さんきゃく\",\n         \"さんこう\",\n         \"さんさい\",\n         \"ざんしょ\",\n         \"さんすう\",\n         \"さんせい\",\n         \"さんそ\",\n         \"さんち\",\n         \"さんま\",\n         \"さんみ\",\n         \"さんらん\",\n         \"しあい\",\n         \"しあげ\",\n         \"しあさって\",\n         \"しあわせ\",\n         \"しいく\",\n         \"しいん\",\n         \"しうち\",\n         \"しえい\",\n         \"しおけ\",\n         \"しかい\",\n         \"しかく\",\n         \"じかん\",\n         \"しごと\",\n         \"しすう\",\n         \"じだい\",\n         \"したうけ\",\n         \"したぎ\",\n         \"したて\",\n         \"したみ\",\n         \"しちょう\",\n         \"しちりん\",\n         \"しっかり\",\n         \"しつじ\",\n         \"しつもん\",\n         \"してい\",\n         \"してき\",\n         \"してつ\",\n         \"じてん\",\n         \"じどう\",\n         \"しなぎれ\",\n         \"しなもの\",\n         \"しなん\",\n         \"しねま\",\n         \"しねん\",\n         \"しのぐ\",\n         \"しのぶ\",\n         \"しはい\",\n         \"しばかり\",\n         \"しはつ\",\n         \"しはらい\",\n         \"しはん\",\n         \"しひょう\",\n         \"しふく\",\n         \"じぶん\",\n         \"しへい\",\n         \"しほう\",\n         \"しほん\",\n         \"しまう\",\n         \"しまる\",\n         \"しみん\",\n         \"しむける\",\n         \"じむしょ\",\n         \"しめい\",\n         \"しめる\",\n         \"しもん\",\n         \"しゃいん\",\n         \"しゃうん\",\n         \"しゃおん\",\n         \"じゃがいも\",\n         \"しやくしょ\",\n         \"しゃくほう\",\n         \"しゃけん\",\n         \"しゃこ\",\n         \"しゃざい\",\n         \"しゃしん\",\n         \"しゃせん\",\n         \"しゃそう\",\n         \"しゃたい\",\n         \"しゃちょう\",\n         \"しゃっきん\",\n         \"じゃま\",\n         \"しゃりん\",\n         \"しゃれい\",\n         \"じゆう\",\n         \"じゅうしょ\",\n         \"しゅくはく\",\n         \"じゅしん\",\n         \"しゅっせき\",\n         \"しゅみ\",\n         \"しゅらば\",\n         \"じゅんばん\",\n         \"しょうかい\",\n         \"しょくたく\",\n         \"しょっけん\",\n         \"しょどう\",\n         \"しょもつ\",\n         \"しらせる\",\n         \"しらべる\",\n         \"しんか\",\n         \"しんこう\",\n         \"じんじゃ\",\n         \"しんせいじ\",\n         \"しんちく\",\n         \"しんりん\",\n         \"すあげ\",\n         \"すあし\",\n         \"すあな\",\n         \"ずあん\",\n         \"すいえい\",\n         \"すいか\",\n         \"すいとう\",\n         \"ずいぶん\",\n         \"すいようび\",\n         \"すうがく\",\n         \"すうじつ\",\n         \"すうせん\",\n         \"すおどり\",\n         \"すきま\",\n         \"すくう\",\n         \"すくない\",\n         \"すける\",\n         \"すごい\",\n         \"すこし\",\n         \"ずさん\",\n         \"すずしい\",\n         \"すすむ\",\n         \"すすめる\",\n         \"すっかり\",\n         \"ずっしり\",\n         \"ずっと\",\n         \"すてき\",\n         \"すてる\",\n         \"すねる\",\n         \"すのこ\",\n         \"すはだ\",\n         \"すばらしい\",\n         \"ずひょう\",\n         \"ずぶぬれ\",\n         \"すぶり\",\n         \"すふれ\",\n         \"すべて\",\n         \"すべる\",\n         \"ずほう\",\n         \"すぼん\",\n         \"すまい\",\n         \"すめし\",\n         \"すもう\",\n         \"すやき\",\n         \"すらすら\",\n         \"するめ\",\n         \"すれちがう\",\n         \"すろっと\",\n         \"すわる\",\n         \"すんぜん\",\n         \"すんぽう\",\n         \"せあぶら\",\n         \"せいかつ\",\n         \"せいげん\",\n         \"せいじ\",\n         \"せいよう\",\n         \"せおう\",\n         \"せかいかん\",\n         \"せきにん\",\n         \"せきむ\",\n         \"せきゆ\",\n         \"せきらんうん\",\n         \"せけん\",\n         \"せこう\",\n         \"せすじ\",\n         \"せたい\",\n         \"せたけ\",\n         \"せっかく\",\n         \"せっきゃく\",\n         \"ぜっく\",\n         \"せっけん\",\n         \"せっこつ\",\n         \"せっさたくま\",\n         \"せつぞく\",\n         \"せつだん\",\n         \"せつでん\",\n         \"せっぱん\",\n         \"せつび\",\n         \"せつぶん\",\n         \"せつめい\",\n         \"せつりつ\",\n         \"せなか\",\n         \"せのび\",\n         \"せはば\",\n         \"せびろ\",\n         \"せぼね\",\n         \"せまい\",\n         \"せまる\",\n         \"せめる\",\n         \"せもたれ\",\n         \"せりふ\",\n         \"ぜんあく\",\n         \"せんい\",\n         \"せんえい\",\n         \"せんか\",\n         \"せんきょ\",\n         \"せんく\",\n         \"せんげん\",\n         \"ぜんご\",\n         \"せんさい\",\n         \"せんしゅ\",\n         \"せんすい\",\n         \"せんせい\",\n         \"せんぞ\",\n         \"せんたく\",\n         \"せんちょう\",\n         \"せんてい\",\n         \"せんとう\",\n         \"せんぬき\",\n         \"せんねん\",\n         \"せんぱい\",\n         \"ぜんぶ\",\n         \"ぜんぽう\",\n         \"せんむ\",\n         \"せんめんじょ\",\n         \"せんもん\",\n         \"せんやく\",\n         \"せんゆう\",\n         \"せんよう\",\n         \"ぜんら\",\n         \"ぜんりゃく\",\n         \"せんれい\",\n         \"せんろ\",\n         \"そあく\",\n         \"そいとげる\",\n         \"そいね\",\n         \"そうがんきょう\",\n         \"そうき\",\n         \"そうご\",\n         \"そうしん\",\n         \"そうだん\",\n         \"そうなん\",\n         \"そうび\",\n         \"そうめん\",\n         \"そうり\",\n         \"そえもの\",\n         \"そえん\",\n         \"そがい\",\n         \"そげき\",\n         \"そこう\",\n         \"そこそこ\",\n         \"そざい\",\n         \"そしな\",\n         \"そせい\",\n         \"そせん\",\n         \"そそぐ\",\n         \"そだてる\",\n         \"そつう\",\n         \"そつえん\",\n         \"そっかん\",\n         \"そつぎょう\",\n         \"そっけつ\",\n         \"そっこう\",\n         \"そっせん\",\n         \"そっと\",\n         \"そとがわ\",\n         \"そとづら\",\n         \"そなえる\",\n         \"そなた\",\n         \"そふぼ\",\n         \"そぼく\",\n         \"そぼろ\",\n         \"そまつ\",\n         \"そまる\",\n         \"そむく\",\n         \"そむりえ\",\n         \"そめる\",\n         \"そもそも\",\n         \"そよかぜ\",\n         \"そらまめ\",\n         \"そろう\",\n         \"そんかい\",\n         \"そんけい\",\n         \"そんざい\",\n         \"そんしつ\",\n         \"そんぞく\",\n         \"そんちょう\",\n         \"ぞんび\",\n         \"ぞんぶん\",\n         \"そんみん\",\n         \"たあい\",\n         \"たいいん\",\n         \"たいうん\",\n         \"たいえき\",\n         \"たいおう\",\n         \"だいがく\",\n         \"たいき\",\n         \"たいぐう\",\n         \"たいけん\",\n         \"たいこ\",\n         \"たいざい\",\n         \"だいじょうぶ\",\n         \"だいすき\",\n         \"たいせつ\",\n         \"たいそう\",\n         \"だいたい\",\n         \"たいちょう\",\n         \"たいてい\",\n         \"だいどころ\",\n         \"たいない\",\n         \"たいねつ\",\n         \"たいのう\",\n         \"たいはん\",\n         \"だいひょう\",\n         \"たいふう\",\n         \"たいへん\",\n         \"たいほ\",\n         \"たいまつばな\",\n         \"たいみんぐ\",\n         \"たいむ\",\n         \"たいめん\",\n         \"たいやき\",\n         \"たいよう\",\n         \"たいら\",\n         \"たいりょく\",\n         \"たいる\",\n         \"たいわん\",\n         \"たうえ\",\n         \"たえる\",\n         \"たおす\",\n         \"たおる\",\n         \"たおれる\",\n         \"たかい\",\n         \"たかね\",\n         \"たきび\",\n         \"たくさん\",\n         \"たこく\",\n         \"たこやき\",\n         \"たさい\",\n         \"たしざん\",\n         \"だじゃれ\",\n         \"たすける\",\n         \"たずさわる\",\n         \"たそがれ\",\n         \"たたかう\",\n         \"たたく\",\n         \"ただしい\",\n         \"たたみ\",\n         \"たちばな\",\n         \"だっかい\",\n         \"だっきゃく\",\n         \"だっこ\",\n         \"だっしゅつ\",\n         \"だったい\",\n         \"たてる\",\n         \"たとえる\",\n         \"たなばた\",\n         \"たにん\",\n         \"たぬき\",\n         \"たのしみ\",\n         \"たはつ\",\n         \"たぶん\",\n         \"たべる\",\n         \"たぼう\",\n         \"たまご\",\n         \"たまる\",\n         \"だむる\",\n         \"ためいき\",\n         \"ためす\",\n         \"ためる\",\n         \"たもつ\",\n         \"たやすい\",\n         \"たよる\",\n         \"たらす\",\n         \"たりきほんがん\",\n         \"たりょう\",\n         \"たりる\",\n         \"たると\",\n         \"たれる\",\n         \"たれんと\",\n         \"たろっと\",\n         \"たわむれる\",\n         \"だんあつ\",\n         \"たんい\",\n         \"たんおん\",\n         \"たんか\",\n         \"たんき\",\n         \"たんけん\",\n         \"たんご\",\n         \"たんさん\",\n         \"たんじょうび\",\n         \"だんせい\",\n         \"たんそく\",\n         \"たんたい\",\n         \"だんち\",\n         \"たんてい\",\n         \"たんとう\",\n         \"だんな\",\n         \"たんにん\",\n         \"だんねつ\",\n         \"たんのう\",\n         \"たんぴん\",\n         \"だんぼう\",\n         \"たんまつ\",\n         \"たんめい\",\n         \"だんれつ\",\n         \"だんろ\",\n         \"だんわ\",\n         \"ちあい\",\n         \"ちあん\",\n         \"ちいき\",\n         \"ちいさい\",\n         \"ちえん\",\n         \"ちかい\",\n         \"ちから\",\n         \"ちきゅう\",\n         \"ちきん\",\n         \"ちけいず\",\n         \"ちけん\",\n         \"ちこく\",\n         \"ちさい\",\n         \"ちしき\",\n         \"ちしりょう\",\n         \"ちせい\",\n         \"ちそう\",\n         \"ちたい\",\n         \"ちたん\",\n         \"ちちおや\",\n         \"ちつじょ\",\n         \"ちてき\",\n         \"ちてん\",\n         \"ちぬき\",\n         \"ちぬり\",\n         \"ちのう\",\n         \"ちひょう\",\n         \"ちへいせん\",\n         \"ちほう\",\n         \"ちまた\",\n         \"ちみつ\",\n         \"ちみどろ\",\n         \"ちめいど\",\n         \"ちゃんこなべ\",\n         \"ちゅうい\",\n         \"ちゆりょく\",\n         \"ちょうし\",\n         \"ちょさくけん\",\n         \"ちらし\",\n         \"ちらみ\",\n         \"ちりがみ\",\n         \"ちりょう\",\n         \"ちるど\",\n         \"ちわわ\",\n         \"ちんたい\",\n         \"ちんもく\",\n         \"ついか\",\n         \"ついたち\",\n         \"つうか\",\n         \"つうじょう\",\n         \"つうはん\",\n         \"つうわ\",\n         \"つかう\",\n         \"つかれる\",\n         \"つくね\",\n         \"つくる\",\n         \"つけね\",\n         \"つける\",\n         \"つごう\",\n         \"つたえる\",\n         \"つづく\",\n         \"つつじ\",\n         \"つつむ\",\n         \"つとめる\",\n         \"つながる\",\n         \"つなみ\",\n         \"つねづね\",\n         \"つのる\",\n         \"つぶす\",\n         \"つまらない\",\n         \"つまる\",\n         \"つみき\",\n         \"つめたい\",\n         \"つもり\",\n         \"つもる\",\n         \"つよい\",\n         \"つるぼ\",\n         \"つるみく\",\n         \"つわもの\",\n         \"つわり\",\n         \"てあし\",\n         \"てあて\",\n         \"てあみ\",\n         \"ていおん\",\n         \"ていか\",\n         \"ていき\",\n         \"ていけい\",\n         \"ていこく\",\n         \"ていさつ\",\n         \"ていし\",\n         \"ていせい\",\n         \"ていたい\",\n         \"ていど\",\n         \"ていねい\",\n         \"ていひょう\",\n         \"ていへん\",\n         \"ていぼう\",\n         \"てうち\",\n         \"ておくれ\",\n         \"てきとう\",\n         \"てくび\",\n         \"でこぼこ\",\n         \"てさぎょう\",\n         \"てさげ\",\n         \"てすり\",\n         \"てそう\",\n         \"てちがい\",\n         \"てちょう\",\n         \"てつがく\",\n         \"てつづき\",\n         \"でっぱ\",\n         \"てつぼう\",\n         \"てつや\",\n         \"でぬかえ\",\n         \"てぬき\",\n         \"てぬぐい\",\n         \"てのひら\",\n         \"てはい\",\n         \"てぶくろ\",\n         \"てふだ\",\n         \"てほどき\",\n         \"てほん\",\n         \"てまえ\",\n         \"てまきずし\",\n         \"てみじか\",\n         \"てみやげ\",\n         \"てらす\",\n         \"てれび\",\n         \"てわけ\",\n         \"てわたし\",\n         \"でんあつ\",\n         \"てんいん\",\n         \"てんかい\",\n         \"てんき\",\n         \"てんぐ\",\n         \"てんけん\",\n         \"てんごく\",\n         \"てんさい\",\n         \"てんし\",\n         \"てんすう\",\n         \"でんち\",\n         \"てんてき\",\n         \"てんとう\",\n         \"てんない\",\n         \"てんぷら\",\n         \"てんぼうだい\",\n         \"てんめつ\",\n         \"てんらんかい\",\n         \"でんりょく\",\n         \"でんわ\",\n         \"どあい\",\n         \"といれ\",\n         \"どうかん\",\n         \"とうきゅう\",\n         \"どうぐ\",\n         \"とうし\",\n         \"とうむぎ\",\n         \"とおい\",\n         \"とおか\",\n         \"とおく\",\n         \"とおす\",\n         \"とおる\",\n         \"とかい\",\n         \"とかす\",\n         \"ときおり\",\n         \"ときどき\",\n         \"とくい\",\n         \"とくしゅう\",\n         \"とくてん\",\n         \"とくに\",\n         \"とくべつ\",\n         \"とけい\",\n         \"とける\",\n         \"とこや\",\n         \"とさか\",\n         \"としょかん\",\n         \"とそう\",\n         \"とたん\",\n         \"とちゅう\",\n         \"とっきゅう\",\n         \"とっくん\",\n         \"とつぜん\",\n         \"とつにゅう\",\n         \"とどける\",\n         \"ととのえる\",\n         \"とない\",\n         \"となえる\",\n         \"となり\",\n         \"とのさま\",\n         \"とばす\",\n         \"どぶがわ\",\n         \"とほう\",\n         \"とまる\",\n         \"とめる\",\n         \"ともだち\",\n         \"ともる\",\n         \"どようび\",\n         \"とらえる\",\n         \"とんかつ\",\n         \"どんぶり\",\n         \"ないかく\",\n         \"ないこう\",\n         \"ないしょ\",\n         \"ないす\",\n         \"ないせん\",\n         \"ないそう\",\n         \"なおす\",\n         \"ながい\",\n         \"なくす\",\n         \"なげる\",\n         \"なこうど\",\n         \"なさけ\",\n         \"なたでここ\",\n         \"なっとう\",\n         \"なつやすみ\",\n         \"ななおし\",\n         \"なにごと\",\n         \"なにもの\",\n         \"なにわ\",\n         \"なのか\",\n         \"なふだ\",\n         \"なまいき\",\n         \"なまえ\",\n         \"なまみ\",\n         \"なみだ\",\n         \"なめらか\",\n         \"なめる\",\n         \"なやむ\",\n         \"ならう\",\n         \"ならび\",\n         \"ならぶ\",\n         \"なれる\",\n         \"なわとび\",\n         \"なわばり\",\n         \"にあう\",\n         \"にいがた\",\n         \"にうけ\",\n         \"におい\",\n         \"にかい\",\n         \"にがて\",\n         \"にきび\",\n         \"にくしみ\",\n         \"にくまん\",\n         \"にげる\",\n         \"にさんかたんそ\",\n         \"にしき\",\n         \"にせもの\",\n         \"にちじょう\",\n         \"にちようび\",\n         \"にっか\",\n         \"にっき\",\n         \"にっけい\",\n         \"にっこう\",\n         \"にっさん\",\n         \"にっしょく\",\n         \"にっすう\",\n         \"にっせき\",\n         \"にってい\",\n         \"になう\",\n         \"にほん\",\n         \"にまめ\",\n         \"にもつ\",\n         \"にやり\",\n         \"にゅういん\",\n         \"にりんしゃ\",\n         \"にわとり\",\n         \"にんい\",\n         \"にんか\",\n         \"にんき\",\n         \"にんげん\",\n         \"にんしき\",\n         \"にんずう\",\n         \"にんそう\",\n         \"にんたい\",\n         \"にんち\",\n         \"にんてい\",\n         \"にんにく\",\n         \"にんぷ\",\n         \"にんまり\",\n         \"にんむ\",\n         \"にんめい\",\n         \"にんよう\",\n         \"ぬいくぎ\",\n         \"ぬかす\",\n         \"ぬぐいとる\",\n         \"ぬぐう\",\n         \"ぬくもり\",\n         \"ぬすむ\",\n         \"ぬまえび\",\n         \"ぬめり\",\n         \"ぬらす\",\n         \"ぬんちゃく\",\n         \"ねあげ\",\n         \"ねいき\",\n         \"ねいる\",\n         \"ねいろ\",\n         \"ねぐせ\",\n         \"ねくたい\",\n         \"ねくら\",\n         \"ねこぜ\",\n         \"ねこむ\",\n         \"ねさげ\",\n         \"ねすごす\",\n         \"ねそべる\",\n         \"ねだん\",\n         \"ねつい\",\n         \"ねっしん\",\n         \"ねつぞう\",\n         \"ねったいぎょ\",\n         \"ねぶそく\",\n         \"ねふだ\",\n         \"ねぼう\",\n         \"ねほりはほり\",\n         \"ねまき\",\n         \"ねまわし\",\n         \"ねみみ\",\n         \"ねむい\",\n         \"ねむたい\",\n         \"ねもと\",\n         \"ねらう\",\n         \"ねわざ\",\n         \"ねんいり\",\n         \"ねんおし\",\n         \"ねんかん\",\n         \"ねんきん\",\n         \"ねんぐ\",\n         \"ねんざ\",\n         \"ねんし\",\n         \"ねんちゃく\",\n         \"ねんど\",\n         \"ねんぴ\",\n         \"ねんぶつ\",\n         \"ねんまつ\",\n         \"ねんりょう\",\n         \"ねんれい\",\n         \"のいず\",\n         \"のおづま\",\n         \"のがす\",\n         \"のきなみ\",\n         \"のこぎり\",\n         \"のこす\",\n         \"のこる\",\n         \"のせる\",\n         \"のぞく\",\n         \"のぞむ\",\n         \"のたまう\",\n         \"のちほど\",\n         \"のっく\",\n         \"のばす\",\n         \"のはら\",\n         \"のべる\",\n         \"のぼる\",\n         \"のみもの\",\n         \"のやま\",\n         \"のらいぬ\",\n         \"のらねこ\",\n         \"のりもの\",\n         \"のりゆき\",\n         \"のれん\",\n         \"のんき\",\n         \"ばあい\",\n         \"はあく\",\n         \"ばあさん\",\n         \"ばいか\",\n         \"ばいく\",\n         \"はいけん\",\n         \"はいご\",\n         \"はいしん\",\n         \"はいすい\",\n         \"はいせん\",\n         \"はいそう\",\n         \"はいち\",\n         \"ばいばい\",\n         \"はいれつ\",\n         \"はえる\",\n         \"はおる\",\n         \"はかい\",\n         \"ばかり\",\n         \"はかる\",\n         \"はくしゅ\",\n         \"はけん\",\n         \"はこぶ\",\n         \"はさみ\",\n         \"はさん\",\n         \"はしご\",\n         \"ばしょ\",\n         \"はしる\",\n         \"はせる\",\n         \"ぱそこん\",\n         \"はそん\",\n         \"はたん\",\n         \"はちみつ\",\n         \"はつおん\",\n         \"はっかく\",\n         \"はづき\",\n         \"はっきり\",\n         \"はっくつ\",\n         \"はっけん\",\n         \"はっこう\",\n         \"はっさん\",\n         \"はっしん\",\n         \"はったつ\",\n         \"はっちゅう\",\n         \"はってん\",\n         \"はっぴょう\",\n         \"はっぽう\",\n         \"はなす\",\n         \"はなび\",\n         \"はにかむ\",\n         \"はぶらし\",\n         \"はみがき\",\n         \"はむかう\",\n         \"はめつ\",\n         \"はやい\",\n         \"はやし\",\n         \"はらう\",\n         \"はろうぃん\",\n         \"はわい\",\n         \"はんい\",\n         \"はんえい\",\n         \"はんおん\",\n         \"はんかく\",\n         \"はんきょう\",\n         \"ばんぐみ\",\n         \"はんこ\",\n         \"はんしゃ\",\n         \"はんすう\",\n         \"はんだん\",\n         \"ぱんち\",\n         \"ぱんつ\",\n         \"はんてい\",\n         \"はんとし\",\n         \"はんのう\",\n         \"はんぱ\",\n         \"はんぶん\",\n         \"はんぺん\",\n         \"はんぼうき\",\n         \"はんめい\",\n         \"はんらん\",\n         \"はんろん\",\n         \"ひいき\",\n         \"ひうん\",\n         \"ひえる\",\n         \"ひかく\",\n         \"ひかり\",\n         \"ひかる\",\n         \"ひかん\",\n         \"ひくい\",\n         \"ひけつ\",\n         \"ひこうき\",\n         \"ひこく\",\n         \"ひさい\",\n         \"ひさしぶり\",\n         \"ひさん\",\n         \"びじゅつかん\",\n         \"ひしょ\",\n         \"ひそか\",\n         \"ひそむ\",\n         \"ひたむき\",\n         \"ひだり\",\n         \"ひたる\",\n         \"ひつぎ\",\n         \"ひっこし\",\n         \"ひっし\",\n         \"ひつじゅひん\",\n         \"ひっす\",\n         \"ひつぜん\",\n         \"ぴったり\",\n         \"ぴっちり\",\n         \"ひつよう\",\n         \"ひてい\",\n         \"ひとごみ\",\n         \"ひなまつり\",\n         \"ひなん\",\n         \"ひねる\",\n         \"ひはん\",\n         \"ひびく\",\n         \"ひひょう\",\n         \"ひほう\",\n         \"ひまわり\",\n         \"ひまん\",\n         \"ひみつ\",\n         \"ひめい\",\n         \"ひめじし\",\n         \"ひやけ\",\n         \"ひやす\",\n         \"ひよう\",\n         \"びょうき\",\n         \"ひらがな\",\n         \"ひらく\",\n         \"ひりつ\",\n         \"ひりょう\",\n         \"ひるま\",\n         \"ひるやすみ\",\n         \"ひれい\",\n         \"ひろい\",\n         \"ひろう\",\n         \"ひろき\",\n         \"ひろゆき\",\n         \"ひんかく\",\n         \"ひんけつ\",\n         \"ひんこん\",\n         \"ひんしゅ\",\n         \"ひんそう\",\n         \"ぴんち\",\n         \"ひんぱん\",\n         \"びんぼう\",\n         \"ふあん\",\n         \"ふいうち\",\n         \"ふうけい\",\n         \"ふうせん\",\n         \"ぷうたろう\",\n         \"ふうとう\",\n         \"ふうふ\",\n         \"ふえる\",\n         \"ふおん\",\n         \"ふかい\",\n         \"ふきん\",\n         \"ふくざつ\",\n         \"ふくぶくろ\",\n         \"ふこう\",\n         \"ふさい\",\n         \"ふしぎ\",\n         \"ふじみ\",\n         \"ふすま\",\n         \"ふせい\",\n         \"ふせぐ\",\n         \"ふそく\",\n         \"ぶたにく\",\n         \"ふたん\",\n         \"ふちょう\",\n         \"ふつう\",\n         \"ふつか\",\n         \"ふっかつ\",\n         \"ふっき\",\n         \"ふっこく\",\n         \"ぶどう\",\n         \"ふとる\",\n         \"ふとん\",\n         \"ふのう\",\n         \"ふはい\",\n         \"ふひょう\",\n         \"ふへん\",\n         \"ふまん\",\n         \"ふみん\",\n         \"ふめつ\",\n         \"ふめん\",\n         \"ふよう\",\n         \"ふりこ\",\n         \"ふりる\",\n         \"ふるい\",\n         \"ふんいき\",\n         \"ぶんがく\",\n         \"ぶんぐ\",\n         \"ふんしつ\",\n         \"ぶんせき\",\n         \"ふんそう\",\n         \"ぶんぽう\",\n         \"へいあん\",\n         \"へいおん\",\n         \"へいがい\",\n         \"へいき\",\n         \"へいげん\",\n         \"へいこう\",\n         \"へいさ\",\n         \"へいしゃ\",\n         \"へいせつ\",\n         \"へいそ\",\n         \"へいたく\",\n         \"へいてん\",\n         \"へいねつ\",\n         \"へいわ\",\n         \"へきが\",\n         \"へこむ\",\n         \"べにいろ\",\n         \"べにしょうが\",\n         \"へらす\",\n         \"へんかん\",\n         \"べんきょう\",\n         \"べんごし\",\n         \"へんさい\",\n         \"へんたい\",\n         \"べんり\",\n         \"ほあん\",\n         \"ほいく\",\n         \"ぼうぎょ\",\n         \"ほうこく\",\n         \"ほうそう\",\n         \"ほうほう\",\n         \"ほうもん\",\n         \"ほうりつ\",\n         \"ほえる\",\n         \"ほおん\",\n         \"ほかん\",\n         \"ほきょう\",\n         \"ぼきん\",\n         \"ほくろ\",\n         \"ほけつ\",\n         \"ほけん\",\n         \"ほこう\",\n         \"ほこる\",\n         \"ほしい\",\n         \"ほしつ\",\n         \"ほしゅ\",\n         \"ほしょう\",\n         \"ほせい\",\n         \"ほそい\",\n         \"ほそく\",\n         \"ほたて\",\n         \"ほたる\",\n         \"ぽちぶくろ\",\n         \"ほっきょく\",\n         \"ほっさ\",\n         \"ほったん\",\n         \"ほとんど\",\n         \"ほめる\",\n         \"ほんい\",\n         \"ほんき\",\n         \"ほんけ\",\n         \"ほんしつ\",\n         \"ほんやく\",\n         \"まいにち\",\n         \"まかい\",\n         \"まかせる\",\n         \"まがる\",\n         \"まける\",\n         \"まこと\",\n         \"まさつ\",\n         \"まじめ\",\n         \"ますく\",\n         \"まぜる\",\n         \"まつり\",\n         \"まとめ\",\n         \"まなぶ\",\n         \"まぬけ\",\n         \"まねく\",\n         \"まほう\",\n         \"まもる\",\n         \"まゆげ\",\n         \"まよう\",\n         \"まろやか\",\n         \"まわす\",\n         \"まわり\",\n         \"まわる\",\n         \"まんが\",\n         \"まんきつ\",\n         \"まんぞく\",\n         \"まんなか\",\n         \"みいら\",\n         \"みうち\",\n         \"みえる\",\n         \"みがく\",\n         \"みかた\",\n         \"みかん\",\n         \"みけん\",\n         \"みこん\",\n         \"みじかい\",\n         \"みすい\",\n         \"みすえる\",\n         \"みせる\",\n         \"みっか\",\n         \"みつかる\",\n         \"みつける\",\n         \"みてい\",\n         \"みとめる\",\n         \"みなと\",\n         \"みなみかさい\",\n         \"みねらる\",\n         \"みのう\",\n         \"みのがす\",\n         \"みほん\",\n         \"みもと\",\n         \"みやげ\",\n         \"みらい\",\n         \"みりょく\",\n         \"みわく\",\n         \"みんか\",\n         \"みんぞく\",\n         \"むいか\",\n         \"むえき\",\n         \"むえん\",\n         \"むかい\",\n         \"むかう\",\n         \"むかえ\",\n         \"むかし\",\n         \"むぎちゃ\",\n         \"むける\",\n         \"むげん\",\n         \"むさぼる\",\n         \"むしあつい\",\n         \"むしば\",\n         \"むじゅん\",\n         \"むしろ\",\n         \"むすう\",\n         \"むすこ\",\n         \"むすぶ\",\n         \"むすめ\",\n         \"むせる\",\n         \"むせん\",\n         \"むちゅう\",\n         \"むなしい\",\n         \"むのう\",\n         \"むやみ\",\n         \"むよう\",\n         \"むらさき\",\n         \"むりょう\",\n         \"むろん\",\n         \"めいあん\",\n         \"めいうん\",\n         \"めいえん\",\n         \"めいかく\",\n         \"めいきょく\",\n         \"めいさい\",\n         \"めいし\",\n         \"めいそう\",\n         \"めいぶつ\",\n         \"めいれい\",\n         \"めいわく\",\n         \"めぐまれる\",\n         \"めざす\",\n         \"めした\",\n         \"めずらしい\",\n         \"めだつ\",\n         \"めまい\",\n         \"めやす\",\n         \"めんきょ\",\n         \"めんせき\",\n         \"めんどう\",\n         \"もうしあげる\",\n         \"もうどうけん\",\n         \"もえる\",\n         \"もくし\",\n         \"もくてき\",\n         \"もくようび\",\n         \"もちろん\",\n         \"もどる\",\n         \"もらう\",\n         \"もんく\",\n         \"もんだい\",\n         \"やおや\",\n         \"やける\",\n         \"やさい\",\n         \"やさしい\",\n         \"やすい\",\n         \"やすたろう\",\n         \"やすみ\",\n         \"やせる\",\n         \"やそう\",\n         \"やたい\",\n         \"やちん\",\n         \"やっと\",\n         \"やっぱり\",\n         \"やぶる\",\n         \"やめる\",\n         \"ややこしい\",\n         \"やよい\",\n         \"やわらかい\",\n         \"ゆうき\",\n         \"ゆうびんきょく\",\n         \"ゆうべ\",\n         \"ゆうめい\",\n         \"ゆけつ\",\n         \"ゆしゅつ\",\n         \"ゆせん\",\n         \"ゆそう\",\n         \"ゆたか\",\n         \"ゆちゃく\",\n         \"ゆでる\",\n         \"ゆにゅう\",\n         \"ゆびわ\",\n         \"ゆらい\",\n         \"ゆれる\",\n         \"ようい\",\n         \"ようか\",\n         \"ようきゅう\",\n         \"ようじ\",\n         \"ようす\",\n         \"ようちえん\",\n         \"よかぜ\",\n         \"よかん\",\n         \"よきん\",\n         \"よくせい\",\n         \"よくぼう\",\n         \"よけい\",\n         \"よごれる\",\n         \"よさん\",\n         \"よしゅう\",\n         \"よそう\",\n         \"よそく\",\n         \"よっか\",\n         \"よてい\",\n         \"よどがわく\",\n         \"よねつ\",\n         \"よやく\",\n         \"よゆう\",\n         \"よろこぶ\",\n         \"よろしい\",\n         \"らいう\",\n         \"らくがき\",\n         \"らくご\",\n         \"らくさつ\",\n         \"らくだ\",\n         \"らしんばん\",\n         \"らせん\",\n         \"らぞく\",\n         \"らたい\",\n         \"らっか\",\n         \"られつ\",\n         \"りえき\",\n         \"りかい\",\n         \"りきさく\",\n         \"りきせつ\",\n         \"りくぐん\",\n         \"りくつ\",\n         \"りけん\",\n         \"りこう\",\n         \"りせい\",\n         \"りそう\",\n         \"りそく\",\n         \"りてん\",\n         \"りねん\",\n         \"りゆう\",\n         \"りゅうがく\",\n         \"りよう\",\n         \"りょうり\",\n         \"りょかん\",\n         \"りょくちゃ\",\n         \"りょこう\",\n         \"りりく\",\n         \"りれき\",\n         \"りろん\",\n         \"りんご\",\n         \"るいけい\",\n         \"るいさい\",\n         \"るいじ\",\n         \"るいせき\",\n         \"るすばん\",\n         \"るりがわら\",\n         \"れいかん\",\n         \"れいぎ\",\n         \"れいせい\",\n         \"れいぞうこ\",\n         \"れいとう\",\n         \"れいぼう\",\n         \"れきし\",\n         \"れきだい\",\n         \"れんあい\",\n         \"れんけい\",\n         \"れんこん\",\n         \"れんさい\",\n         \"れんしゅう\",\n         \"れんぞく\",\n         \"れんらく\",\n         \"ろうか\",\n         \"ろうご\",\n         \"ろうじん\",\n         \"ろうそく\",\n         \"ろくが\",\n         \"ろこつ\",\n         \"ろじうら\",\n         \"ろしゅつ\",\n         \"ろせん\",\n         \"ろてん\",\n         \"ろめん\",\n         \"ろれつ\",\n         \"ろんぎ\",\n         \"ろんぱ\",\n         \"ろんぶん\",\n         \"ろんり\",\n         \"わかす\",\n         \"わかめ\",\n         \"わかやま\",\n         \"わかれる\",\n         \"わしつ\",\n         \"わじまし\",\n         \"わすれもの\",\n         \"わらう\",\n         \"われる\"}};\n\nconst dictionary zh_Hans =\n    {\n        {\"的\",\n         \"一\",\n         \"是\",\n         \"在\",\n         \"不\",\n         \"了\",\n         \"有\",\n         \"和\",\n         \"人\",\n         \"这\",\n         \"中\",\n         \"大\",\n         \"为\",\n         \"上\",\n         \"个\",\n         \"国\",\n         \"我\",\n         \"以\",\n         \"要\",\n         \"他\",\n         \"时\",\n         \"来\",\n         \"用\",\n         \"们\",\n         \"生\",\n         \"到\",\n         \"作\",\n         \"地\",\n         \"于\",\n         \"出\",\n         \"就\",\n         \"分\",\n         \"对\",\n         \"成\",\n         \"会\",\n         \"可\",\n         \"主\",\n         \"发\",\n         \"年\",\n         \"动\",\n         \"同\",\n         \"工\",\n         \"也\",\n         \"能\",\n         \"下\",\n         \"过\",\n         \"子\",\n         \"说\",\n         \"产\",\n         \"种\",\n         \"面\",\n         \"而\",\n         \"方\",\n         \"后\",\n         \"多\",\n         \"定\",\n         \"行\",\n         \"学\",\n         \"法\",\n         \"所\",\n         \"民\",\n         \"得\",\n         \"经\",\n         \"十\",\n         \"三\",\n         \"之\",\n         \"进\",\n         \"着\",\n         \"等\",\n         \"部\",\n         \"度\",\n         \"家\",\n         \"电\",\n         \"力\",\n         \"里\",\n         \"如\",\n         \"水\",\n         \"化\",\n         \"高\",\n         \"自\",\n         \"二\",\n         \"理\",\n         \"起\",\n         \"小\",\n         \"物\",\n         \"现\",\n         \"实\",\n         \"加\",\n         \"量\",\n         \"都\",\n         \"两\",\n         \"体\",\n         \"制\",\n         \"机\",\n         \"当\",\n         \"使\",\n         \"点\",\n         \"从\",\n         \"业\",\n         \"本\",\n         \"去\",\n         \"把\",\n         \"性\",\n         \"好\",\n         \"应\",\n         \"开\",\n         \"它\",\n         \"合\",\n         \"还\",\n         \"因\",\n         \"由\",\n         \"其\",\n         \"些\",\n         \"然\",\n         \"前\",\n         \"外\",\n         \"天\",\n         \"政\",\n         \"四\",\n         \"日\",\n         \"那\",\n         \"社\",\n         \"义\",\n         \"事\",\n         \"平\",\n         \"形\",\n         \"相\",\n         \"全\",\n         \"表\",\n         \"间\",\n         \"样\",\n         \"与\",\n         \"关\",\n         \"各\",\n         \"重\",\n         \"新\",\n         \"线\",\n         \"内\",\n         \"数\",\n         \"正\",\n         \"心\",\n         \"反\",\n         \"你\",\n         \"明\",\n         \"看\",\n         \"原\",\n         \"又\",\n         \"么\",\n         \"利\",\n         \"比\",\n         \"或\",\n         \"但\",\n         \"质\",\n         \"气\",\n         \"第\",\n         \"向\",\n         \"道\",\n         \"命\",\n         \"此\",\n         \"变\",\n         \"条\",\n         \"只\",\n         \"没\",\n         \"结\",\n         \"解\",\n         \"问\",\n         \"意\",\n         \"建\",\n         \"月\",\n         \"公\",\n         \"无\",\n         \"系\",\n         \"军\",\n         \"很\",\n         \"情\",\n         \"者\",\n         \"最\",\n         \"立\",\n         \"代\",\n         \"想\",\n         \"已\",\n         \"通\",\n         \"并\",\n         \"提\",\n         \"直\",\n         \"题\",\n         \"党\",\n         \"程\",\n         \"展\",\n         \"五\",\n         \"果\",\n         \"料\",\n         \"象\",\n         \"员\",\n         \"革\",\n         \"位\",\n         \"入\",\n         \"常\",\n         \"文\",\n         \"总\",\n         \"次\",\n         \"品\",\n         \"式\",\n         \"活\",\n         \"设\",\n         \"及\",\n         \"管\",\n         \"特\",\n         \"件\",\n         \"长\",\n         \"求\",\n         \"老\",\n         \"头\",\n         \"基\",\n         \"资\",\n         \"边\",\n         \"流\",\n         \"路\",\n         \"级\",\n         \"少\",\n         \"图\",\n         \"山\",\n         \"统\",\n         \"接\",\n         \"知\",\n         \"较\",\n         \"将\",\n         \"组\",\n         \"见\",\n         \"计\",\n         \"别\",\n         \"她\",\n         \"手\",\n         \"角\",\n         \"期\",\n         \"根\",\n         \"论\",\n         \"运\",\n         \"农\",\n         \"指\",\n         \"几\",\n         \"九\",\n         \"区\",\n         \"强\",\n         \"放\",\n         \"决\",\n         \"西\",\n         \"被\",\n         \"干\",\n         \"做\",\n         \"必\",\n         \"战\",\n         \"先\",\n         \"回\",\n         \"则\",\n         \"任\",\n         \"取\",\n         \"据\",\n         \"处\",\n         \"队\",\n         \"南\",\n         \"给\",\n         \"色\",\n         \"光\",\n         \"门\",\n         \"即\",\n         \"保\",\n         \"治\",\n         \"北\",\n         \"造\",\n         \"百\",\n         \"规\",\n         \"热\",\n         \"领\",\n         \"七\",\n         \"海\",\n         \"口\",\n         \"东\",\n         \"导\",\n         \"器\",\n         \"压\",\n         \"志\",\n         \"世\",\n         \"金\",\n         \"增\",\n         \"争\",\n         \"济\",\n         \"阶\",\n         \"油\",\n         \"思\",\n         \"术\",\n         \"极\",\n         \"交\",\n         \"受\",\n         \"联\",\n         \"什\",\n         \"认\",\n         \"六\",\n         \"共\",\n         \"权\",\n         \"收\",\n         \"证\",\n         \"改\",\n         \"清\",\n         \"美\",\n         \"再\",\n         \"采\",\n         \"转\",\n         \"更\",\n         \"单\",\n         \"风\",\n         \"切\",\n         \"打\",\n         \"白\",\n         \"教\",\n         \"速\",\n         \"花\",\n         \"带\",\n         \"安\",\n         \"场\",\n         \"身\",\n         \"车\",\n         \"例\",\n         \"真\",\n         \"务\",\n         \"具\",\n         \"万\",\n         \"每\",\n         \"目\",\n         \"至\",\n         \"达\",\n         \"走\",\n         \"积\",\n         \"示\",\n         \"议\",\n         \"声\",\n         \"报\",\n         \"斗\",\n         \"完\",\n         \"类\",\n         \"八\",\n         \"离\",\n         \"华\",\n         \"名\",\n         \"确\",\n         \"才\",\n         \"科\",\n         \"张\",\n         \"信\",\n         \"马\",\n         \"节\",\n         \"话\",\n         \"米\",\n         \"整\",\n         \"空\",\n         \"元\",\n         \"况\",\n         \"今\",\n         \"集\",\n         \"温\",\n         \"传\",\n         \"土\",\n         \"许\",\n         \"步\",\n         \"群\",\n         \"广\",\n         \"石\",\n         \"记\",\n         \"需\",\n         \"段\",\n         \"研\",\n         \"界\",\n         \"拉\",\n         \"林\",\n         \"律\",\n         \"叫\",\n         \"且\",\n         \"究\",\n         \"观\",\n         \"越\",\n         \"织\",\n         \"装\",\n         \"影\",\n         \"算\",\n         \"低\",\n         \"持\",\n         \"音\",\n         \"众\",\n         \"书\",\n         \"布\",\n         \"复\",\n         \"容\",\n         \"儿\",\n         \"须\",\n         \"际\",\n         \"商\",\n         \"非\",\n         \"验\",\n         \"连\",\n         \"断\",\n         \"深\",\n         \"难\",\n         \"近\",\n         \"矿\",\n         \"千\",\n         \"周\",\n         \"委\",\n         \"素\",\n         \"技\",\n         \"备\",\n         \"半\",\n         \"办\",\n         \"青\",\n         \"省\",\n         \"列\",\n         \"习\",\n         \"响\",\n         \"约\",\n         \"支\",\n         \"般\",\n         \"史\",\n         \"感\",\n         \"劳\",\n         \"便\",\n         \"团\",\n         \"往\",\n         \"酸\",\n         \"历\",\n         \"市\",\n         \"克\",\n         \"何\",\n         \"除\",\n         \"消\",\n         \"构\",\n         \"府\",\n         \"称\",\n         \"太\",\n         \"准\",\n         \"精\",\n         \"值\",\n         \"号\",\n         \"率\",\n         \"族\",\n         \"维\",\n         \"划\",\n         \"选\",\n         \"标\",\n         \"写\",\n         \"存\",\n         \"候\",\n         \"毛\",\n         \"亲\",\n         \"快\",\n         \"效\",\n         \"斯\",\n         \"院\",\n         \"查\",\n         \"江\",\n         \"型\",\n         \"眼\",\n         \"王\",\n         \"按\",\n         \"格\",\n         \"养\",\n         \"易\",\n         \"置\",\n         \"派\",\n         \"层\",\n         \"片\",\n         \"始\",\n         \"却\",\n         \"专\",\n         \"状\",\n         \"育\",\n         \"厂\",\n         \"京\",\n         \"识\",\n         \"适\",\n         \"属\",\n         \"圆\",\n         \"包\",\n         \"火\",\n         \"住\",\n         \"调\",\n         \"满\",\n         \"县\",\n         \"局\",\n         \"照\",\n         \"参\",\n         \"红\",\n         \"细\",\n         \"引\",\n         \"听\",\n         \"该\",\n         \"铁\",\n         \"价\",\n         \"严\",\n         \"首\",\n         \"底\",\n         \"液\",\n         \"官\",\n         \"德\",\n         \"随\",\n         \"病\",\n         \"苏\",\n         \"失\",\n         \"尔\",\n         \"死\",\n         \"讲\",\n         \"配\",\n         \"女\",\n         \"黄\",\n         \"推\",\n         \"显\",\n         \"谈\",\n         \"罪\",\n         \"神\",\n         \"艺\",\n         \"呢\",\n         \"席\",\n         \"含\",\n         \"企\",\n         \"望\",\n         \"密\",\n         \"批\",\n         \"营\",\n         \"项\",\n         \"防\",\n         \"举\",\n         \"球\",\n         \"英\",\n         \"氧\",\n         \"势\",\n         \"告\",\n         \"李\",\n         \"台\",\n         \"落\",\n         \"木\",\n         \"帮\",\n         \"轮\",\n         \"破\",\n         \"亚\",\n         \"师\",\n         \"围\",\n         \"注\",\n         \"远\",\n         \"字\",\n         \"材\",\n         \"排\",\n         \"供\",\n         \"河\",\n         \"态\",\n         \"封\",\n         \"另\",\n         \"施\",\n         \"减\",\n         \"树\",\n         \"溶\",\n         \"怎\",\n         \"止\",\n         \"案\",\n         \"言\",\n         \"士\",\n         \"均\",\n         \"武\",\n         \"固\",\n         \"叶\",\n         \"鱼\",\n         \"波\",\n         \"视\",\n         \"仅\",\n         \"费\",\n         \"紧\",\n         \"爱\",\n         \"左\",\n         \"章\",\n         \"早\",\n         \"朝\",\n         \"害\",\n         \"续\",\n         \"轻\",\n         \"服\",\n         \"试\",\n         \"食\",\n         \"充\",\n         \"兵\",\n         \"源\",\n         \"判\",\n         \"护\",\n         \"司\",\n         \"足\",\n         \"某\",\n         \"练\",\n         \"差\",\n         \"致\",\n         \"板\",\n         \"田\",\n         \"降\",\n         \"黑\",\n         \"犯\",\n         \"负\",\n         \"击\",\n         \"范\",\n         \"继\",\n         \"兴\",\n         \"似\",\n         \"余\",\n         \"坚\",\n         \"曲\",\n         \"输\",\n         \"修\",\n         \"故\",\n         \"城\",\n         \"夫\",\n         \"够\",\n         \"送\",\n         \"笔\",\n         \"船\",\n         \"占\",\n         \"右\",\n         \"财\",\n         \"吃\",\n         \"富\",\n         \"春\",\n         \"职\",\n         \"觉\",\n         \"汉\",\n         \"画\",\n         \"功\",\n         \"巴\",\n         \"跟\",\n         \"虽\",\n         \"杂\",\n         \"飞\",\n         \"检\",\n         \"吸\",\n         \"助\",\n         \"升\",\n         \"阳\",\n         \"互\",\n         \"初\",\n         \"创\",\n         \"抗\",\n         \"考\",\n         \"投\",\n         \"坏\",\n         \"策\",\n         \"古\",\n         \"径\",\n         \"换\",\n         \"未\",\n         \"跑\",\n         \"留\",\n         \"钢\",\n         \"曾\",\n         \"端\",\n         \"责\",\n         \"站\",\n         \"简\",\n         \"述\",\n         \"钱\",\n         \"副\",\n         \"尽\",\n         \"帝\",\n         \"射\",\n         \"草\",\n         \"冲\",\n         \"承\",\n         \"独\",\n         \"令\",\n         \"限\",\n         \"阿\",\n         \"宣\",\n         \"环\",\n         \"双\",\n         \"请\",\n         \"超\",\n         \"微\",\n         \"让\",\n         \"控\",\n         \"州\",\n         \"良\",\n         \"轴\",\n         \"找\",\n         \"否\",\n         \"纪\",\n         \"益\",\n         \"依\",\n         \"优\",\n         \"顶\",\n         \"础\",\n         \"载\",\n         \"倒\",\n         \"房\",\n         \"突\",\n         \"坐\",\n         \"粉\",\n         \"敌\",\n         \"略\",\n         \"客\",\n         \"袁\",\n         \"冷\",\n         \"胜\",\n         \"绝\",\n         \"析\",\n         \"块\",\n         \"剂\",\n         \"测\",\n         \"丝\",\n         \"协\",\n         \"诉\",\n         \"念\",\n         \"陈\",\n         \"仍\",\n         \"罗\",\n         \"盐\",\n         \"友\",\n         \"洋\",\n         \"错\",\n         \"苦\",\n         \"夜\",\n         \"刑\",\n         \"移\",\n         \"频\",\n         \"逐\",\n         \"靠\",\n         \"混\",\n         \"母\",\n         \"短\",\n         \"皮\",\n         \"终\",\n         \"聚\",\n         \"汽\",\n         \"村\",\n         \"云\",\n         \"哪\",\n         \"既\",\n         \"距\",\n         \"卫\",\n         \"停\",\n         \"烈\",\n         \"央\",\n         \"察\",\n         \"烧\",\n         \"迅\",\n         \"境\",\n         \"若\",\n         \"印\",\n         \"洲\",\n         \"刻\",\n         \"括\",\n         \"激\",\n         \"孔\",\n         \"搞\",\n         \"甚\",\n         \"室\",\n         \"待\",\n         \"核\",\n         \"校\",\n         \"散\",\n         \"侵\",\n         \"吧\",\n         \"甲\",\n         \"游\",\n         \"久\",\n         \"菜\",\n         \"味\",\n         \"旧\",\n         \"模\",\n         \"湖\",\n         \"货\",\n         \"损\",\n         \"预\",\n         \"阻\",\n         \"毫\",\n         \"普\",\n         \"稳\",\n         \"乙\",\n         \"妈\",\n         \"植\",\n         \"息\",\n         \"扩\",\n         \"银\",\n         \"语\",\n         \"挥\",\n         \"酒\",\n         \"守\",\n         \"拿\",\n         \"序\",\n         \"纸\",\n         \"医\",\n         \"缺\",\n         \"雨\",\n         \"吗\",\n         \"针\",\n         \"刘\",\n         \"啊\",\n         \"急\",\n         \"唱\",\n         \"误\",\n         \"训\",\n         \"愿\",\n         \"审\",\n         \"附\",\n         \"获\",\n         \"茶\",\n         \"鲜\",\n         \"粮\",\n         \"斤\",\n         \"孩\",\n         \"脱\",\n         \"硫\",\n         \"肥\",\n         \"善\",\n         \"龙\",\n         \"演\",\n         \"父\",\n         \"渐\",\n         \"血\",\n         \"欢\",\n         \"械\",\n         \"掌\",\n         \"歌\",\n         \"沙\",\n         \"刚\",\n         \"攻\",\n         \"谓\",\n         \"盾\",\n         \"讨\",\n         \"晚\",\n         \"粒\",\n         \"乱\",\n         \"燃\",\n         \"矛\",\n         \"乎\",\n         \"杀\",\n         \"药\",\n         \"宁\",\n         \"鲁\",\n         \"贵\",\n         \"钟\",\n         \"煤\",\n         \"读\",\n         \"班\",\n         \"伯\",\n         \"香\",\n         \"介\",\n         \"迫\",\n         \"句\",\n         \"丰\",\n         \"培\",\n         \"握\",\n         \"兰\",\n         \"担\",\n         \"弦\",\n         \"蛋\",\n         \"沉\",\n         \"假\",\n         \"穿\",\n         \"执\",\n         \"答\",\n         \"乐\",\n         \"谁\",\n         \"顺\",\n         \"烟\",\n         \"缩\",\n         \"征\",\n         \"脸\",\n         \"喜\",\n         \"松\",\n         \"脚\",\n         \"困\",\n         \"异\",\n         \"免\",\n         \"背\",\n         \"星\",\n         \"福\",\n         \"买\",\n         \"染\",\n         \"井\",\n         \"概\",\n         \"慢\",\n         \"怕\",\n         \"磁\",\n         \"倍\",\n         \"祖\",\n         \"皇\",\n         \"促\",\n         \"静\",\n         \"补\",\n         \"评\",\n         \"翻\",\n         \"肉\",\n         \"践\",\n         \"尼\",\n         \"衣\",\n         \"宽\",\n         \"扬\",\n         \"棉\",\n         \"希\",\n         \"伤\",\n         \"操\",\n         \"垂\",\n         \"秋\",\n         \"宜\",\n         \"氢\",\n         \"套\",\n         \"督\",\n         \"振\",\n         \"架\",\n         \"亮\",\n         \"末\",\n         \"宪\",\n         \"庆\",\n         \"编\",\n         \"牛\",\n         \"触\",\n         \"映\",\n         \"雷\",\n         \"销\",\n         \"诗\",\n         \"座\",\n         \"居\",\n         \"抓\",\n         \"裂\",\n         \"胞\",\n         \"呼\",\n         \"娘\",\n         \"景\",\n         \"威\",\n         \"绿\",\n         \"晶\",\n         \"厚\",\n         \"盟\",\n         \"衡\",\n         \"鸡\",\n         \"孙\",\n         \"延\",\n         \"危\",\n         \"胶\",\n         \"屋\",\n         \"乡\",\n         \"临\",\n         \"陆\",\n         \"顾\",\n         \"掉\",\n         \"呀\",\n         \"灯\",\n         \"岁\",\n         \"措\",\n         \"束\",\n         \"耐\",\n         \"剧\",\n         \"玉\",\n         \"赵\",\n         \"跳\",\n         \"哥\",\n         \"季\",\n         \"课\",\n         \"凯\",\n         \"胡\",\n         \"额\",\n         \"款\",\n         \"绍\",\n         \"卷\",\n         \"齐\",\n         \"伟\",\n         \"蒸\",\n         \"殖\",\n         \"永\",\n         \"宗\",\n         \"苗\",\n         \"川\",\n         \"炉\",\n         \"岩\",\n         \"弱\",\n         \"零\",\n         \"杨\",\n         \"奏\",\n         \"沿\",\n         \"露\",\n         \"杆\",\n         \"探\",\n         \"滑\",\n         \"镇\",\n         \"饭\",\n         \"浓\",\n         \"航\",\n         \"怀\",\n         \"赶\",\n         \"库\",\n         \"夺\",\n         \"伊\",\n         \"灵\",\n         \"税\",\n         \"途\",\n         \"灭\",\n         \"赛\",\n         \"归\",\n         \"召\",\n         \"鼓\",\n         \"播\",\n         \"盘\",\n         \"裁\",\n         \"险\",\n         \"康\",\n         \"唯\",\n         \"录\",\n         \"菌\",\n         \"纯\",\n         \"借\",\n         \"糖\",\n         \"盖\",\n         \"横\",\n         \"符\",\n         \"私\",\n         \"努\",\n         \"堂\",\n         \"域\",\n         \"枪\",\n         \"润\",\n         \"幅\",\n         \"哈\",\n         \"竟\",\n         \"熟\",\n         \"虫\",\n         \"泽\",\n         \"脑\",\n         \"壤\",\n         \"碳\",\n         \"欧\",\n         \"遍\",\n         \"侧\",\n         \"寨\",\n         \"敢\",\n         \"彻\",\n         \"虑\",\n         \"斜\",\n         \"薄\",\n         \"庭\",\n         \"纳\",\n         \"弹\",\n         \"饲\",\n         \"伸\",\n         \"折\",\n         \"麦\",\n         \"湿\",\n         \"暗\",\n         \"荷\",\n         \"瓦\",\n         \"塞\",\n         \"床\",\n         \"筑\",\n         \"恶\",\n         \"户\",\n         \"访\",\n         \"塔\",\n         \"奇\",\n         \"透\",\n         \"梁\",\n         \"刀\",\n         \"旋\",\n         \"迹\",\n         \"卡\",\n         \"氯\",\n         \"遇\",\n         \"份\",\n         \"毒\",\n         \"泥\",\n         \"退\",\n         \"洗\",\n         \"摆\",\n         \"灰\",\n         \"彩\",\n         \"卖\",\n         \"耗\",\n         \"夏\",\n         \"择\",\n         \"忙\",\n         \"铜\",\n         \"献\",\n         \"硬\",\n         \"予\",\n         \"繁\",\n         \"圈\",\n         \"雪\",\n         \"函\",\n         \"亦\",\n         \"抽\",\n         \"篇\",\n         \"阵\",\n         \"阴\",\n         \"丁\",\n         \"尺\",\n         \"追\",\n         \"堆\",\n         \"雄\",\n         \"迎\",\n         \"泛\",\n         \"爸\",\n         \"楼\",\n         \"避\",\n         \"谋\",\n         \"吨\",\n         \"野\",\n         \"猪\",\n         \"旗\",\n         \"累\",\n         \"偏\",\n         \"典\",\n         \"馆\",\n         \"索\",\n         \"秦\",\n         \"脂\",\n         \"潮\",\n         \"爷\",\n         \"豆\",\n         \"忽\",\n         \"托\",\n         \"惊\",\n         \"塑\",\n         \"遗\",\n         \"愈\",\n         \"朱\",\n         \"替\",\n         \"纤\",\n         \"粗\",\n         \"倾\",\n         \"尚\",\n         \"痛\",\n         \"楚\",\n         \"谢\",\n         \"奋\",\n         \"购\",\n         \"磨\",\n         \"君\",\n         \"池\",\n         \"旁\",\n         \"碎\",\n         \"骨\",\n         \"监\",\n         \"捕\",\n         \"弟\",\n         \"暴\",\n         \"割\",\n         \"贯\",\n         \"殊\",\n         \"释\",\n         \"词\",\n         \"亡\",\n         \"壁\",\n         \"顿\",\n         \"宝\",\n         \"午\",\n         \"尘\",\n         \"闻\",\n         \"揭\",\n         \"炮\",\n         \"残\",\n         \"冬\",\n         \"桥\",\n         \"妇\",\n         \"警\",\n         \"综\",\n         \"招\",\n         \"吴\",\n         \"付\",\n         \"浮\",\n         \"遭\",\n         \"徐\",\n         \"您\",\n         \"摇\",\n         \"谷\",\n         \"赞\",\n         \"箱\",\n         \"隔\",\n         \"订\",\n         \"男\",\n         \"吹\",\n         \"园\",\n         \"纷\",\n         \"唐\",\n         \"败\",\n         \"宋\",\n         \"玻\",\n         \"巨\",\n         \"耕\",\n         \"坦\",\n         \"荣\",\n         \"闭\",\n         \"湾\",\n         \"键\",\n         \"凡\",\n         \"驻\",\n         \"锅\",\n         \"救\",\n         \"恩\",\n         \"剥\",\n         \"凝\",\n         \"碱\",\n         \"齿\",\n         \"截\",\n         \"炼\",\n         \"麻\",\n         \"纺\",\n         \"禁\",\n         \"废\",\n         \"盛\",\n         \"版\",\n         \"缓\",\n         \"净\",\n         \"睛\",\n         \"昌\",\n         \"婚\",\n         \"涉\",\n         \"筒\",\n         \"嘴\",\n         \"插\",\n         \"岸\",\n         \"朗\",\n         \"庄\",\n         \"街\",\n         \"藏\",\n         \"姑\",\n         \"贸\",\n         \"腐\",\n         \"奴\",\n         \"啦\",\n         \"惯\",\n         \"乘\",\n         \"伙\",\n         \"恢\",\n         \"匀\",\n         \"纱\",\n         \"扎\",\n         \"辩\",\n         \"耳\",\n         \"彪\",\n         \"臣\",\n         \"亿\",\n         \"璃\",\n         \"抵\",\n         \"脉\",\n         \"秀\",\n         \"萨\",\n         \"俄\",\n         \"网\",\n         \"舞\",\n         \"店\",\n         \"喷\",\n         \"纵\",\n         \"寸\",\n         \"汗\",\n         \"挂\",\n         \"洪\",\n         \"贺\",\n         \"闪\",\n         \"柬\",\n         \"爆\",\n         \"烯\",\n         \"津\",\n         \"稻\",\n         \"墙\",\n         \"软\",\n         \"勇\",\n         \"像\",\n         \"滚\",\n         \"厘\",\n         \"蒙\",\n         \"芳\",\n         \"肯\",\n         \"坡\",\n         \"柱\",\n         \"荡\",\n         \"腿\",\n         \"仪\",\n         \"旅\",\n         \"尾\",\n         \"轧\",\n         \"冰\",\n         \"贡\",\n         \"登\",\n         \"黎\",\n         \"削\",\n         \"钻\",\n         \"勒\",\n         \"逃\",\n         \"障\",\n         \"氨\",\n         \"郭\",\n         \"峰\",\n         \"币\",\n         \"港\",\n         \"伏\",\n         \"轨\",\n         \"亩\",\n         \"毕\",\n         \"擦\",\n         \"莫\",\n         \"刺\",\n         \"浪\",\n         \"秘\",\n         \"援\",\n         \"株\",\n         \"健\",\n         \"售\",\n         \"股\",\n         \"岛\",\n         \"甘\",\n         \"泡\",\n         \"睡\",\n         \"童\",\n         \"铸\",\n         \"汤\",\n         \"阀\",\n         \"休\",\n         \"汇\",\n         \"舍\",\n         \"牧\",\n         \"绕\",\n         \"炸\",\n         \"哲\",\n         \"磷\",\n         \"绩\",\n         \"朋\",\n         \"淡\",\n         \"尖\",\n         \"启\",\n         \"陷\",\n         \"柴\",\n         \"呈\",\n         \"徒\",\n         \"颜\",\n         \"泪\",\n         \"稍\",\n         \"忘\",\n         \"泵\",\n         \"蓝\",\n         \"拖\",\n         \"洞\",\n         \"授\",\n         \"镜\",\n         \"辛\",\n         \"壮\",\n         \"锋\",\n         \"贫\",\n         \"虚\",\n         \"弯\",\n         \"摩\",\n         \"泰\",\n         \"幼\",\n         \"廷\",\n         \"尊\",\n         \"窗\",\n         \"纲\",\n         \"弄\",\n         \"隶\",\n         \"疑\",\n         \"氏\",\n         \"宫\",\n         \"姐\",\n         \"震\",\n         \"瑞\",\n         \"怪\",\n         \"尤\",\n         \"琴\",\n         \"循\",\n         \"描\",\n         \"膜\",\n         \"违\",\n         \"夹\",\n         \"腰\",\n         \"缘\",\n         \"珠\",\n         \"穷\",\n         \"森\",\n         \"枝\",\n         \"竹\",\n         \"沟\",\n         \"催\",\n         \"绳\",\n         \"忆\",\n         \"邦\",\n         \"剩\",\n         \"幸\",\n         \"浆\",\n         \"栏\",\n         \"拥\",\n         \"牙\",\n         \"贮\",\n         \"礼\",\n         \"滤\",\n         \"钠\",\n         \"纹\",\n         \"罢\",\n         \"拍\",\n         \"咱\",\n         \"喊\",\n         \"袖\",\n         \"埃\",\n         \"勤\",\n         \"罚\",\n         \"焦\",\n         \"潜\",\n         \"伍\",\n         \"墨\",\n         \"欲\",\n         \"缝\",\n         \"姓\",\n         \"刊\",\n         \"饱\",\n         \"仿\",\n         \"奖\",\n         \"铝\",\n         \"鬼\",\n         \"丽\",\n         \"跨\",\n         \"默\",\n         \"挖\",\n         \"链\",\n         \"扫\",\n         \"喝\",\n         \"袋\",\n         \"炭\",\n         \"污\",\n         \"幕\",\n         \"诸\",\n         \"弧\",\n         \"励\",\n         \"梅\",\n         \"奶\",\n         \"洁\",\n         \"灾\",\n         \"舟\",\n         \"鉴\",\n         \"苯\",\n         \"讼\",\n         \"抱\",\n         \"毁\",\n         \"懂\",\n         \"寒\",\n         \"智\",\n         \"埔\",\n         \"寄\",\n         \"届\",\n         \"跃\",\n         \"渡\",\n         \"挑\",\n         \"丹\",\n         \"艰\",\n         \"贝\",\n         \"碰\",\n         \"拔\",\n         \"爹\",\n         \"戴\",\n         \"码\",\n         \"梦\",\n         \"芽\",\n         \"熔\",\n         \"赤\",\n         \"渔\",\n         \"哭\",\n         \"敬\",\n         \"颗\",\n         \"奔\",\n         \"铅\",\n         \"仲\",\n         \"虎\",\n         \"稀\",\n         \"妹\",\n         \"乏\",\n         \"珍\",\n         \"申\",\n         \"桌\",\n         \"遵\",\n         \"允\",\n         \"隆\",\n         \"螺\",\n         \"仓\",\n         \"魏\",\n         \"锐\",\n         \"晓\",\n         \"氮\",\n         \"兼\",\n         \"隐\",\n         \"碍\",\n         \"赫\",\n         \"拨\",\n         \"忠\",\n         \"肃\",\n         \"缸\",\n         \"牵\",\n         \"抢\",\n         \"博\",\n         \"巧\",\n         \"壳\",\n         \"兄\",\n         \"杜\",\n         \"讯\",\n         \"诚\",\n         \"碧\",\n         \"祥\",\n         \"柯\",\n         \"页\",\n         \"巡\",\n         \"矩\",\n         \"悲\",\n         \"灌\",\n         \"龄\",\n         \"伦\",\n         \"票\",\n         \"寻\",\n         \"桂\",\n         \"铺\",\n         \"圣\",\n         \"恐\",\n         \"恰\",\n         \"郑\",\n         \"趣\",\n         \"抬\",\n         \"荒\",\n         \"腾\",\n         \"贴\",\n         \"柔\",\n         \"滴\",\n         \"猛\",\n         \"阔\",\n         \"辆\",\n         \"妻\",\n         \"填\",\n         \"撤\",\n         \"储\",\n         \"签\",\n         \"闹\",\n         \"扰\",\n         \"紫\",\n         \"砂\",\n         \"递\",\n         \"戏\",\n         \"吊\",\n         \"陶\",\n         \"伐\",\n         \"喂\",\n         \"疗\",\n         \"瓶\",\n         \"婆\",\n         \"抚\",\n         \"臂\",\n         \"摸\",\n         \"忍\",\n         \"虾\",\n         \"蜡\",\n         \"邻\",\n         \"胸\",\n         \"巩\",\n         \"挤\",\n         \"偶\",\n         \"弃\",\n         \"槽\",\n         \"劲\",\n         \"乳\",\n         \"邓\",\n         \"吉\",\n         \"仁\",\n         \"烂\",\n         \"砖\",\n         \"租\",\n         \"乌\",\n         \"舰\",\n         \"伴\",\n         \"瓜\",\n         \"浅\",\n         \"丙\",\n         \"暂\",\n         \"燥\",\n         \"橡\",\n         \"柳\",\n         \"迷\",\n         \"暖\",\n         \"牌\",\n         \"秧\",\n         \"胆\",\n         \"详\",\n         \"簧\",\n         \"踏\",\n         \"瓷\",\n         \"谱\",\n         \"呆\",\n         \"宾\",\n         \"糊\",\n         \"洛\",\n         \"辉\",\n         \"愤\",\n         \"竞\",\n         \"隙\",\n         \"怒\",\n         \"粘\",\n         \"乃\",\n         \"绪\",\n         \"肩\",\n         \"籍\",\n         \"敏\",\n         \"涂\",\n         \"熙\",\n         \"皆\",\n         \"侦\",\n         \"悬\",\n         \"掘\",\n         \"享\",\n         \"纠\",\n         \"醒\",\n         \"狂\",\n         \"锁\",\n         \"淀\",\n         \"恨\",\n         \"牲\",\n         \"霸\",\n         \"爬\",\n         \"赏\",\n         \"逆\",\n         \"玩\",\n         \"陵\",\n         \"祝\",\n         \"秒\",\n         \"浙\",\n         \"貌\",\n         \"役\",\n         \"彼\",\n         \"悉\",\n         \"鸭\",\n         \"趋\",\n         \"凤\",\n         \"晨\",\n         \"畜\",\n         \"辈\",\n         \"秩\",\n         \"卵\",\n         \"署\",\n         \"梯\",\n         \"炎\",\n         \"滩\",\n         \"棋\",\n         \"驱\",\n         \"筛\",\n         \"峡\",\n         \"冒\",\n         \"啥\",\n         \"寿\",\n         \"译\",\n         \"浸\",\n         \"泉\",\n         \"帽\",\n         \"迟\",\n         \"硅\",\n         \"疆\",\n         \"贷\",\n         \"漏\",\n         \"稿\",\n         \"冠\",\n         \"嫩\",\n         \"胁\",\n         \"芯\",\n         \"牢\",\n         \"叛\",\n         \"蚀\",\n         \"奥\",\n         \"鸣\",\n         \"岭\",\n         \"羊\",\n         \"凭\",\n         \"串\",\n         \"塘\",\n         \"绘\",\n         \"酵\",\n         \"融\",\n         \"盆\",\n         \"锡\",\n         \"庙\",\n         \"筹\",\n         \"冻\",\n         \"辅\",\n         \"摄\",\n         \"袭\",\n         \"筋\",\n         \"拒\",\n         \"僚\",\n         \"旱\",\n         \"钾\",\n         \"鸟\",\n         \"漆\",\n         \"沈\",\n         \"眉\",\n         \"疏\",\n         \"添\",\n         \"棒\",\n         \"穗\",\n         \"硝\",\n         \"韩\",\n         \"逼\",\n         \"扭\",\n         \"侨\",\n         \"凉\",\n         \"挺\",\n         \"碗\",\n         \"栽\",\n         \"炒\",\n         \"杯\",\n         \"患\",\n         \"馏\",\n         \"劝\",\n         \"豪\",\n         \"辽\",\n         \"勃\",\n         \"鸿\",\n         \"旦\",\n         \"吏\",\n         \"拜\",\n         \"狗\",\n         \"埋\",\n         \"辊\",\n         \"掩\",\n         \"饮\",\n         \"搬\",\n         \"骂\",\n         \"辞\",\n         \"勾\",\n         \"扣\",\n         \"估\",\n         \"蒋\",\n         \"绒\",\n         \"雾\",\n         \"丈\",\n         \"朵\",\n         \"姆\",\n         \"拟\",\n         \"宇\",\n         \"辑\",\n         \"陕\",\n         \"雕\",\n         \"偿\",\n         \"蓄\",\n         \"崇\",\n         \"剪\",\n         \"倡\",\n         \"厅\",\n         \"咬\",\n         \"驶\",\n         \"薯\",\n         \"刷\",\n         \"斥\",\n         \"番\",\n         \"赋\",\n         \"奉\",\n         \"佛\",\n         \"浇\",\n         \"漫\",\n         \"曼\",\n         \"扇\",\n         \"钙\",\n         \"桃\",\n         \"扶\",\n         \"仔\",\n         \"返\",\n         \"俗\",\n         \"亏\",\n         \"腔\",\n         \"鞋\",\n         \"棱\",\n         \"覆\",\n         \"框\",\n         \"悄\",\n         \"叔\",\n         \"撞\",\n         \"骗\",\n         \"勘\",\n         \"旺\",\n         \"沸\",\n         \"孤\",\n         \"吐\",\n         \"孟\",\n         \"渠\",\n         \"屈\",\n         \"疾\",\n         \"妙\",\n         \"惜\",\n         \"仰\",\n         \"狠\",\n         \"胀\",\n         \"谐\",\n         \"抛\",\n         \"霉\",\n         \"桑\",\n         \"岗\",\n         \"嘛\",\n         \"衰\",\n         \"盗\",\n         \"渗\",\n         \"脏\",\n         \"赖\",\n         \"涌\",\n         \"甜\",\n         \"曹\",\n         \"阅\",\n         \"肌\",\n         \"哩\",\n         \"厉\",\n         \"烃\",\n         \"纬\",\n         \"毅\",\n         \"昨\",\n         \"伪\",\n         \"症\",\n         \"煮\",\n         \"叹\",\n         \"钉\",\n         \"搭\",\n         \"茎\",\n         \"笼\",\n         \"酷\",\n         \"偷\",\n         \"弓\",\n         \"锥\",\n         \"恒\",\n         \"杰\",\n         \"坑\",\n         \"鼻\",\n         \"翼\",\n         \"纶\",\n         \"叙\",\n         \"狱\",\n         \"逮\",\n         \"罐\",\n         \"络\",\n         \"棚\",\n         \"抑\",\n         \"膨\",\n         \"蔬\",\n         \"寺\",\n         \"骤\",\n         \"穆\",\n         \"冶\",\n         \"枯\",\n         \"册\",\n         \"尸\",\n         \"凸\",\n         \"绅\",\n         \"坯\",\n         \"牺\",\n         \"焰\",\n         \"轰\",\n         \"欣\",\n         \"晋\",\n         \"瘦\",\n         \"御\",\n         \"锭\",\n         \"锦\",\n         \"丧\",\n         \"旬\",\n         \"锻\",\n         \"垄\",\n         \"搜\",\n         \"扑\",\n         \"邀\",\n         \"亭\",\n         \"酯\",\n         \"迈\",\n         \"舒\",\n         \"脆\",\n         \"酶\",\n         \"闲\",\n         \"忧\",\n         \"酚\",\n         \"顽\",\n         \"羽\",\n         \"涨\",\n         \"卸\",\n         \"仗\",\n         \"陪\",\n         \"辟\",\n         \"惩\",\n         \"杭\",\n         \"姚\",\n         \"肚\",\n         \"捉\",\n         \"飘\",\n         \"漂\",\n         \"昆\",\n         \"欺\",\n         \"吾\",\n         \"郎\",\n         \"烷\",\n         \"汁\",\n         \"呵\",\n         \"饰\",\n         \"萧\",\n         \"雅\",\n         \"邮\",\n         \"迁\",\n         \"燕\",\n         \"撒\",\n         \"姻\",\n         \"赴\",\n         \"宴\",\n         \"烦\",\n         \"债\",\n         \"帐\",\n         \"斑\",\n         \"铃\",\n         \"旨\",\n         \"醇\",\n         \"董\",\n         \"饼\",\n         \"雏\",\n         \"姿\",\n         \"拌\",\n         \"傅\",\n         \"腹\",\n         \"妥\",\n         \"揉\",\n         \"贤\",\n         \"拆\",\n         \"歪\",\n         \"葡\",\n         \"胺\",\n         \"丢\",\n         \"浩\",\n         \"徽\",\n         \"昂\",\n         \"垫\",\n         \"挡\",\n         \"览\",\n         \"贪\",\n         \"慰\",\n         \"缴\",\n         \"汪\",\n         \"慌\",\n         \"冯\",\n         \"诺\",\n         \"姜\",\n         \"谊\",\n         \"凶\",\n         \"劣\",\n         \"诬\",\n         \"耀\",\n         \"昏\",\n         \"躺\",\n         \"盈\",\n         \"骑\",\n         \"乔\",\n         \"溪\",\n         \"丛\",\n         \"卢\",\n         \"抹\",\n         \"闷\",\n         \"咨\",\n         \"刮\",\n         \"驾\",\n         \"缆\",\n         \"悟\",\n         \"摘\",\n         \"铒\",\n         \"掷\",\n         \"颇\",\n         \"幻\",\n         \"柄\",\n         \"惠\",\n         \"惨\",\n         \"佳\",\n         \"仇\",\n         \"腊\",\n         \"窝\",\n         \"涤\",\n         \"剑\",\n         \"瞧\",\n         \"堡\",\n         \"泼\",\n         \"葱\",\n         \"罩\",\n         \"霍\",\n         \"捞\",\n         \"胎\",\n         \"苍\",\n         \"滨\",\n         \"俩\",\n         \"捅\",\n         \"湘\",\n         \"砍\",\n         \"霞\",\n         \"邵\",\n         \"萄\",\n         \"疯\",\n         \"淮\",\n         \"遂\",\n         \"熊\",\n         \"粪\",\n         \"烘\",\n         \"宿\",\n         \"档\",\n         \"戈\",\n         \"驳\",\n         \"嫂\",\n         \"裕\",\n         \"徙\",\n         \"箭\",\n         \"捐\",\n         \"肠\",\n         \"撑\",\n         \"晒\",\n         \"辨\",\n         \"殿\",\n         \"莲\",\n         \"摊\",\n         \"搅\",\n         \"酱\",\n         \"屏\",\n         \"疫\",\n         \"哀\",\n         \"蔡\",\n         \"堵\",\n         \"沫\",\n         \"皱\",\n         \"畅\",\n         \"叠\",\n         \"阁\",\n         \"莱\",\n         \"敲\",\n         \"辖\",\n         \"钩\",\n         \"痕\",\n         \"坝\",\n         \"巷\",\n         \"饿\",\n         \"祸\",\n         \"丘\",\n         \"玄\",\n         \"溜\",\n         \"曰\",\n         \"逻\",\n         \"彭\",\n         \"尝\",\n         \"卿\",\n         \"妨\",\n         \"艇\",\n         \"吞\",\n         \"韦\",\n         \"怨\",\n         \"矮\",\n         \"歇\"}};\n\nconst dictionary zh_Hant =\n    {\n        {\"的\",\n         \"一\",\n         \"是\",\n         \"在\",\n         \"不\",\n         \"了\",\n         \"有\",\n         \"和\",\n         \"人\",\n         \"這\",\n         \"中\",\n         \"大\",\n         \"為\",\n         \"上\",\n         \"個\",\n         \"國\",\n         \"我\",\n         \"以\",\n         \"要\",\n         \"他\",\n         \"時\",\n         \"來\",\n         \"用\",\n         \"們\",\n         \"生\",\n         \"到\",\n         \"作\",\n         \"地\",\n         \"於\",\n         \"出\",\n         \"就\",\n         \"分\",\n         \"對\",\n         \"成\",\n         \"會\",\n         \"可\",\n         \"主\",\n         \"發\",\n         \"年\",\n         \"動\",\n         \"同\",\n         \"工\",\n         \"也\",\n         \"能\",\n         \"下\",\n         \"過\",\n         \"子\",\n         \"說\",\n         \"產\",\n         \"種\",\n         \"面\",\n         \"而\",\n         \"方\",\n         \"後\",\n         \"多\",\n         \"定\",\n         \"行\",\n         \"學\",\n         \"法\",\n         \"所\",\n         \"民\",\n         \"得\",\n         \"經\",\n         \"十\",\n         \"三\",\n         \"之\",\n         \"進\",\n         \"著\",\n         \"等\",\n         \"部\",\n         \"度\",\n         \"家\",\n         \"電\",\n         \"力\",\n         \"裡\",\n         \"如\",\n         \"水\",\n         \"化\",\n         \"高\",\n         \"自\",\n         \"二\",\n         \"理\",\n         \"起\",\n         \"小\",\n         \"物\",\n         \"現\",\n         \"實\",\n         \"加\",\n         \"量\",\n         \"都\",\n         \"兩\",\n         \"體\",\n         \"制\",\n         \"機\",\n         \"當\",\n         \"使\",\n         \"點\",\n         \"從\",\n         \"業\",\n         \"本\",\n         \"去\",\n         \"把\",\n         \"性\",\n         \"好\",\n         \"應\",\n         \"開\",\n         \"它\",\n         \"合\",\n         \"還\",\n         \"因\",\n         \"由\",\n         \"其\",\n         \"些\",\n         \"然\",\n         \"前\",\n         \"外\",\n         \"天\",\n         \"政\",\n         \"四\",\n         \"日\",\n         \"那\",\n         \"社\",\n         \"義\",\n         \"事\",\n         \"平\",\n         \"形\",\n         \"相\",\n         \"全\",\n         \"表\",\n         \"間\",\n         \"樣\",\n         \"與\",\n         \"關\",\n         \"各\",\n         \"重\",\n         \"新\",\n         \"線\",\n         \"內\",\n         \"數\",\n         \"正\",\n         \"心\",\n         \"反\",\n         \"你\",\n         \"明\",\n         \"看\",\n         \"原\",\n         \"又\",\n         \"麼\",\n         \"利\",\n         \"比\",\n         \"或\",\n         \"但\",\n         \"質\",\n         \"氣\",\n         \"第\",\n         \"向\",\n         \"道\",\n         \"命\",\n         \"此\",\n         \"變\",\n         \"條\",\n         \"只\",\n         \"沒\",\n         \"結\",\n         \"解\",\n         \"問\",\n         \"意\",\n         \"建\",\n         \"月\",\n         \"公\",\n         \"無\",\n         \"系\",\n         \"軍\",\n         \"很\",\n         \"情\",\n         \"者\",\n         \"最\",\n         \"立\",\n         \"代\",\n         \"想\",\n         \"已\",\n         \"通\",\n         \"並\",\n         \"提\",\n         \"直\",\n         \"題\",\n         \"黨\",\n         \"程\",\n         \"展\",\n         \"五\",\n         \"果\",\n         \"料\",\n         \"象\",\n         \"員\",\n         \"革\",\n         \"位\",\n         \"入\",\n         \"常\",\n         \"文\",\n         \"總\",\n         \"次\",\n         \"品\",\n         \"式\",\n         \"活\",\n         \"設\",\n         \"及\",\n         \"管\",\n         \"特\",\n         \"件\",\n         \"長\",\n         \"求\",\n         \"老\",\n         \"頭\",\n         \"基\",\n         \"資\",\n         \"邊\",\n         \"流\",\n         \"路\",\n         \"級\",\n         \"少\",\n         \"圖\",\n         \"山\",\n         \"統\",\n         \"接\",\n         \"知\",\n         \"較\",\n         \"將\",\n         \"組\",\n         \"見\",\n         \"計\",\n         \"別\",\n         \"她\",\n         \"手\",\n         \"角\",\n         \"期\",\n         \"根\",\n         \"論\",\n         \"運\",\n         \"農\",\n         \"指\",\n         \"幾\",\n         \"九\",\n         \"區\",\n         \"強\",\n         \"放\",\n         \"決\",\n         \"西\",\n         \"被\",\n         \"幹\",\n         \"做\",\n         \"必\",\n         \"戰\",\n         \"先\",\n         \"回\",\n         \"則\",\n         \"任\",\n         \"取\",\n         \"據\",\n         \"處\",\n         \"隊\",\n         \"南\",\n         \"給\",\n         \"色\",\n         \"光\",\n         \"門\",\n         \"即\",\n         \"保\",\n         \"治\",\n         \"北\",\n         \"造\",\n         \"百\",\n         \"規\",\n         \"熱\",\n         \"領\",\n         \"七\",\n         \"海\",\n         \"口\",\n         \"東\",\n         \"導\",\n         \"器\",\n         \"壓\",\n         \"志\",\n         \"世\",\n         \"金\",\n         \"增\",\n         \"爭\",\n         \"濟\",\n         \"階\",\n         \"油\",\n         \"思\",\n         \"術\",\n         \"極\",\n         \"交\",\n         \"受\",\n         \"聯\",\n         \"什\",\n         \"認\",\n         \"六\",\n         \"共\",\n         \"權\",\n         \"收\",\n         \"證\",\n         \"改\",\n         \"清\",\n         \"美\",\n         \"再\",\n         \"採\",\n         \"轉\",\n         \"更\",\n         \"單\",\n         \"風\",\n         \"切\",\n         \"打\",\n         \"白\",\n         \"教\",\n         \"速\",\n         \"花\",\n         \"帶\",\n         \"安\",\n         \"場\",\n         \"身\",\n         \"車\",\n         \"例\",\n         \"真\",\n         \"務\",\n         \"具\",\n         \"萬\",\n         \"每\",\n         \"目\",\n         \"至\",\n         \"達\",\n         \"走\",\n         \"積\",\n         \"示\",\n         \"議\",\n         \"聲\",\n         \"報\",\n         \"鬥\",\n         \"完\",\n         \"類\",\n         \"八\",\n         \"離\",\n         \"華\",\n         \"名\",\n         \"確\",\n         \"才\",\n         \"科\",\n         \"張\",\n         \"信\",\n         \"馬\",\n         \"節\",\n         \"話\",\n         \"米\",\n         \"整\",\n         \"空\",\n         \"元\",\n         \"況\",\n         \"今\",\n         \"集\",\n         \"溫\",\n         \"傳\",\n         \"土\",\n         \"許\",\n         \"步\",\n         \"群\",\n         \"廣\",\n         \"石\",\n         \"記\",\n         \"需\",\n         \"段\",\n         \"研\",\n         \"界\",\n         \"拉\",\n         \"林\",\n         \"律\",\n         \"叫\",\n         \"且\",\n         \"究\",\n         \"觀\",\n         \"越\",\n         \"織\",\n         \"裝\",\n         \"影\",\n         \"算\",\n         \"低\",\n         \"持\",\n         \"音\",\n         \"眾\",\n         \"書\",\n         \"布\",\n         \"复\",\n         \"容\",\n         \"兒\",\n         \"須\",\n         \"際\",\n         \"商\",\n         \"非\",\n         \"驗\",\n         \"連\",\n         \"斷\",\n         \"深\",\n         \"難\",\n         \"近\",\n         \"礦\",\n         \"千\",\n         \"週\",\n         \"委\",\n         \"素\",\n         \"技\",\n         \"備\",\n         \"半\",\n         \"辦\",\n         \"青\",\n         \"省\",\n         \"列\",\n         \"習\",\n         \"響\",\n         \"約\",\n         \"支\",\n         \"般\",\n         \"史\",\n         \"感\",\n         \"勞\",\n         \"便\",\n         \"團\",\n         \"往\",\n         \"酸\",\n         \"歷\",\n         \"市\",\n         \"克\",\n         \"何\",\n         \"除\",\n         \"消\",\n         \"構\",\n         \"府\",\n         \"稱\",\n         \"太\",\n         \"準\",\n         \"精\",\n         \"值\",\n         \"號\",\n         \"率\",\n         \"族\",\n         \"維\",\n         \"劃\",\n         \"選\",\n         \"標\",\n         \"寫\",\n         \"存\",\n         \"候\",\n         \"毛\",\n         \"親\",\n         \"快\",\n         \"效\",\n         \"斯\",\n         \"院\",\n         \"查\",\n         \"江\",\n         \"型\",\n         \"眼\",\n         \"王\",\n         \"按\",\n         \"格\",\n         \"養\",\n         \"易\",\n         \"置\",\n         \"派\",\n         \"層\",\n         \"片\",\n         \"始\",\n         \"卻\",\n         \"專\",\n         \"狀\",\n         \"育\",\n         \"廠\",\n         \"京\",\n         \"識\",\n         \"適\",\n         \"屬\",\n         \"圓\",\n         \"包\",\n         \"火\",\n         \"住\",\n         \"調\",\n         \"滿\",\n         \"縣\",\n         \"局\",\n         \"照\",\n         \"參\",\n         \"紅\",\n         \"細\",\n         \"引\",\n         \"聽\",\n         \"該\",\n         \"鐵\",\n         \"價\",\n         \"嚴\",\n         \"首\",\n         \"底\",\n         \"液\",\n         \"官\",\n         \"德\",\n         \"隨\",\n         \"病\",\n         \"蘇\",\n         \"失\",\n         \"爾\",\n         \"死\",\n         \"講\",\n         \"配\",\n         \"女\",\n         \"黃\",\n         \"推\",\n         \"顯\",\n         \"談\",\n         \"罪\",\n         \"神\",\n         \"藝\",\n         \"呢\",\n         \"席\",\n         \"含\",\n         \"企\",\n         \"望\",\n         \"密\",\n         \"批\",\n         \"營\",\n         \"項\",\n         \"防\",\n         \"舉\",\n         \"球\",\n         \"英\",\n         \"氧\",\n         \"勢\",\n         \"告\",\n         \"李\",\n         \"台\",\n         \"落\",\n         \"木\",\n         \"幫\",\n         \"輪\",\n         \"破\",\n         \"亞\",\n         \"師\",\n         \"圍\",\n         \"注\",\n         \"遠\",\n         \"字\",\n         \"材\",\n         \"排\",\n         \"供\",\n         \"河\",\n         \"態\",\n         \"封\",\n         \"另\",\n         \"施\",\n         \"減\",\n         \"樹\",\n         \"溶\",\n         \"怎\",\n         \"止\",\n         \"案\",\n         \"言\",\n         \"士\",\n         \"均\",\n         \"武\",\n         \"固\",\n         \"葉\",\n         \"魚\",\n         \"波\",\n         \"視\",\n         \"僅\",\n         \"費\",\n         \"緊\",\n         \"愛\",\n         \"左\",\n         \"章\",\n         \"早\",\n         \"朝\",\n         \"害\",\n         \"續\",\n         \"輕\",\n         \"服\",\n         \"試\",\n         \"食\",\n         \"充\",\n         \"兵\",\n         \"源\",\n         \"判\",\n         \"護\",\n         \"司\",\n         \"足\",\n         \"某\",\n         \"練\",\n         \"差\",\n         \"致\",\n         \"板\",\n         \"田\",\n         \"降\",\n         \"黑\",\n         \"犯\",\n         \"負\",\n         \"擊\",\n         \"范\",\n         \"繼\",\n         \"興\",\n         \"似\",\n         \"餘\",\n         \"堅\",\n         \"曲\",\n         \"輸\",\n         \"修\",\n         \"故\",\n         \"城\",\n         \"夫\",\n         \"夠\",\n         \"送\",\n         \"筆\",\n         \"船\",\n         \"佔\",\n         \"右\",\n         \"財\",\n         \"吃\",\n         \"富\",\n         \"春\",\n         \"職\",\n         \"覺\",\n         \"漢\",\n         \"畫\",\n         \"功\",\n         \"巴\",\n         \"跟\",\n         \"雖\",\n         \"雜\",\n         \"飛\",\n         \"檢\",\n         \"吸\",\n         \"助\",\n         \"昇\",\n         \"陽\",\n         \"互\",\n         \"初\",\n         \"創\",\n         \"抗\",\n         \"考\",\n         \"投\",\n         \"壞\",\n         \"策\",\n         \"古\",\n         \"徑\",\n         \"換\",\n         \"未\",\n         \"跑\",\n         \"留\",\n         \"鋼\",\n         \"曾\",\n         \"端\",\n         \"責\",\n         \"站\",\n         \"簡\",\n         \"述\",\n         \"錢\",\n         \"副\",\n         \"盡\",\n         \"帝\",\n         \"射\",\n         \"草\",\n         \"衝\",\n         \"承\",\n         \"獨\",\n         \"令\",\n         \"限\",\n         \"阿\",\n         \"宣\",\n         \"環\",\n         \"雙\",\n         \"請\",\n         \"超\",\n         \"微\",\n         \"讓\",\n         \"控\",\n         \"州\",\n         \"良\",\n         \"軸\",\n         \"找\",\n         \"否\",\n         \"紀\",\n         \"益\",\n         \"依\",\n         \"優\",\n         \"頂\",\n         \"礎\",\n         \"載\",\n         \"倒\",\n         \"房\",\n         \"突\",\n         \"坐\",\n         \"粉\",\n         \"敵\",\n         \"略\",\n         \"客\",\n         \"袁\",\n         \"冷\",\n         \"勝\",\n         \"絕\",\n         \"析\",\n         \"塊\",\n         \"劑\",\n         \"測\",\n         \"絲\",\n         \"協\",\n         \"訴\",\n         \"念\",\n         \"陳\",\n         \"仍\",\n         \"羅\",\n         \"鹽\",\n         \"友\",\n         \"洋\",\n         \"錯\",\n         \"苦\",\n         \"夜\",\n         \"刑\",\n         \"移\",\n         \"頻\",\n         \"逐\",\n         \"靠\",\n         \"混\",\n         \"母\",\n         \"短\",\n         \"皮\",\n         \"終\",\n         \"聚\",\n         \"汽\",\n         \"村\",\n         \"雲\",\n         \"哪\",\n         \"既\",\n         \"距\",\n         \"衛\",\n         \"停\",\n         \"烈\",\n         \"央\",\n         \"察\",\n         \"燒\",\n         \"迅\",\n         \"境\",\n         \"若\",\n         \"印\",\n         \"洲\",\n         \"刻\",\n         \"括\",\n         \"激\",\n         \"孔\",\n         \"搞\",\n         \"甚\",\n         \"室\",\n         \"待\",\n         \"核\",\n         \"校\",\n         \"散\",\n         \"侵\",\n         \"吧\",\n         \"甲\",\n         \"遊\",\n         \"久\",\n         \"菜\",\n         \"味\",\n         \"舊\",\n         \"模\",\n         \"湖\",\n         \"貨\",\n         \"損\",\n         \"預\",\n         \"阻\",\n         \"毫\",\n         \"普\",\n         \"穩\",\n         \"乙\",\n         \"媽\",\n         \"植\",\n         \"息\",\n         \"擴\",\n         \"銀\",\n         \"語\",\n         \"揮\",\n         \"酒\",\n         \"守\",\n         \"拿\",\n         \"序\",\n         \"紙\",\n         \"醫\",\n         \"缺\",\n         \"雨\",\n         \"嗎\",\n         \"針\",\n         \"劉\",\n         \"啊\",\n         \"急\",\n         \"唱\",\n         \"誤\",\n         \"訓\",\n         \"願\",\n         \"審\",\n         \"附\",\n         \"獲\",\n         \"茶\",\n         \"鮮\",\n         \"糧\",\n         \"斤\",\n         \"孩\",\n         \"脫\",\n         \"硫\",\n         \"肥\",\n         \"善\",\n         \"龍\",\n         \"演\",\n         \"父\",\n         \"漸\",\n         \"血\",\n         \"歡\",\n         \"械\",\n         \"掌\",\n         \"歌\",\n         \"沙\",\n         \"剛\",\n         \"攻\",\n         \"謂\",\n         \"盾\",\n         \"討\",\n         \"晚\",\n         \"粒\",\n         \"亂\",\n         \"燃\",\n         \"矛\",\n         \"乎\",\n         \"殺\",\n         \"藥\",\n         \"寧\",\n         \"魯\",\n         \"貴\",\n         \"鐘\",\n         \"煤\",\n         \"讀\",\n         \"班\",\n         \"伯\",\n         \"香\",\n         \"介\",\n         \"迫\",\n         \"句\",\n         \"豐\",\n         \"培\",\n         \"握\",\n         \"蘭\",\n         \"擔\",\n         \"弦\",\n         \"蛋\",\n         \"沉\",\n         \"假\",\n         \"穿\",\n         \"執\",\n         \"答\",\n         \"樂\",\n         \"誰\",\n         \"順\",\n         \"煙\",\n         \"縮\",\n         \"徵\",\n         \"臉\",\n         \"喜\",\n         \"松\",\n         \"腳\",\n         \"困\",\n         \"異\",\n         \"免\",\n         \"背\",\n         \"星\",\n         \"福\",\n         \"買\",\n         \"染\",\n         \"井\",\n         \"概\",\n         \"慢\",\n         \"怕\",\n         \"磁\",\n         \"倍\",\n         \"祖\",\n         \"皇\",\n         \"促\",\n         \"靜\",\n         \"補\",\n         \"評\",\n         \"翻\",\n         \"肉\",\n         \"踐\",\n         \"尼\",\n         \"衣\",\n         \"寬\",\n         \"揚\",\n         \"棉\",\n         \"希\",\n         \"傷\",\n         \"操\",\n         \"垂\",\n         \"秋\",\n         \"宜\",\n         \"氫\",\n         \"套\",\n         \"督\",\n         \"振\",\n         \"架\",\n         \"亮\",\n         \"末\",\n         \"憲\",\n         \"慶\",\n         \"編\",\n         \"牛\",\n         \"觸\",\n         \"映\",\n         \"雷\",\n         \"銷\",\n         \"詩\",\n         \"座\",\n         \"居\",\n         \"抓\",\n         \"裂\",\n         \"胞\",\n         \"呼\",\n         \"娘\",\n         \"景\",\n         \"威\",\n         \"綠\",\n         \"晶\",\n         \"厚\",\n         \"盟\",\n         \"衡\",\n         \"雞\",\n         \"孫\",\n         \"延\",\n         \"危\",\n         \"膠\",\n         \"屋\",\n         \"鄉\",\n         \"臨\",\n         \"陸\",\n         \"顧\",\n         \"掉\",\n         \"呀\",\n         \"燈\",\n         \"歲\",\n         \"措\",\n         \"束\",\n         \"耐\",\n         \"劇\",\n         \"玉\",\n         \"趙\",\n         \"跳\",\n         \"哥\",\n         \"季\",\n         \"課\",\n         \"凱\",\n         \"胡\",\n         \"額\",\n         \"款\",\n         \"紹\",\n         \"卷\",\n         \"齊\",\n         \"偉\",\n         \"蒸\",\n         \"殖\",\n         \"永\",\n         \"宗\",\n         \"苗\",\n         \"川\",\n         \"爐\",\n         \"岩\",\n         \"弱\",\n         \"零\",\n         \"楊\",\n         \"奏\",\n         \"沿\",\n         \"露\",\n         \"桿\",\n         \"探\",\n         \"滑\",\n         \"鎮\",\n         \"飯\",\n         \"濃\",\n         \"航\",\n         \"懷\",\n         \"趕\",\n         \"庫\",\n         \"奪\",\n         \"伊\",\n         \"靈\",\n         \"稅\",\n         \"途\",\n         \"滅\",\n         \"賽\",\n         \"歸\",\n         \"召\",\n         \"鼓\",\n         \"播\",\n         \"盤\",\n         \"裁\",\n         \"險\",\n         \"康\",\n         \"唯\",\n         \"錄\",\n         \"菌\",\n         \"純\",\n         \"借\",\n         \"糖\",\n         \"蓋\",\n         \"橫\",\n         \"符\",\n         \"私\",\n         \"努\",\n         \"堂\",\n         \"域\",\n         \"槍\",\n         \"潤\",\n         \"幅\",\n         \"哈\",\n         \"竟\",\n         \"熟\",\n         \"蟲\",\n         \"澤\",\n         \"腦\",\n         \"壤\",\n         \"碳\",\n         \"歐\",\n         \"遍\",\n         \"側\",\n         \"寨\",\n         \"敢\",\n         \"徹\",\n         \"慮\",\n         \"斜\",\n         \"薄\",\n         \"庭\",\n         \"納\",\n         \"彈\",\n         \"飼\",\n         \"伸\",\n         \"折\",\n         \"麥\",\n         \"濕\",\n         \"暗\",\n         \"荷\",\n         \"瓦\",\n         \"塞\",\n         \"床\",\n         \"築\",\n         \"惡\",\n         \"戶\",\n         \"訪\",\n         \"塔\",\n         \"奇\",\n         \"透\",\n         \"梁\",\n         \"刀\",\n         \"旋\",\n         \"跡\",\n         \"卡\",\n         \"氯\",\n         \"遇\",\n         \"份\",\n         \"毒\",\n         \"泥\",\n         \"退\",\n         \"洗\",\n         \"擺\",\n         \"灰\",\n         \"彩\",\n         \"賣\",\n         \"耗\",\n         \"夏\",\n         \"擇\",\n         \"忙\",\n         \"銅\",\n         \"獻\",\n         \"硬\",\n         \"予\",\n         \"繁\",\n         \"圈\",\n         \"雪\",\n         \"函\",\n         \"亦\",\n         \"抽\",\n         \"篇\",\n         \"陣\",\n         \"陰\",\n         \"丁\",\n         \"尺\",\n         \"追\",\n         \"堆\",\n         \"雄\",\n         \"迎\",\n         \"泛\",\n         \"爸\",\n         \"樓\",\n         \"避\",\n         \"謀\",\n         \"噸\",\n         \"野\",\n         \"豬\",\n         \"旗\",\n         \"累\",\n         \"偏\",\n         \"典\",\n         \"館\",\n         \"索\",\n         \"秦\",\n         \"脂\",\n         \"潮\",\n         \"爺\",\n         \"豆\",\n         \"忽\",\n         \"托\",\n         \"驚\",\n         \"塑\",\n         \"遺\",\n         \"愈\",\n         \"朱\",\n         \"替\",\n         \"纖\",\n         \"粗\",\n         \"傾\",\n         \"尚\",\n         \"痛\",\n         \"楚\",\n         \"謝\",\n         \"奮\",\n         \"購\",\n         \"磨\",\n         \"君\",\n         \"池\",\n         \"旁\",\n         \"碎\",\n         \"骨\",\n         \"監\",\n         \"捕\",\n         \"弟\",\n         \"暴\",\n         \"割\",\n         \"貫\",\n         \"殊\",\n         \"釋\",\n         \"詞\",\n         \"亡\",\n         \"壁\",\n         \"頓\",\n         \"寶\",\n         \"午\",\n         \"塵\",\n         \"聞\",\n         \"揭\",\n         \"炮\",\n         \"殘\",\n         \"冬\",\n         \"橋\",\n         \"婦\",\n         \"警\",\n         \"綜\",\n         \"招\",\n         \"吳\",\n         \"付\",\n         \"浮\",\n         \"遭\",\n         \"徐\",\n         \"您\",\n         \"搖\",\n         \"谷\",\n         \"贊\",\n         \"箱\",\n         \"隔\",\n         \"訂\",\n         \"男\",\n         \"吹\",\n         \"園\",\n         \"紛\",\n         \"唐\",\n         \"敗\",\n         \"宋\",\n         \"玻\",\n         \"巨\",\n         \"耕\",\n         \"坦\",\n         \"榮\",\n         \"閉\",\n         \"灣\",\n         \"鍵\",\n         \"凡\",\n         \"駐\",\n         \"鍋\",\n         \"救\",\n         \"恩\",\n         \"剝\",\n         \"凝\",\n         \"鹼\",\n         \"齒\",\n         \"截\",\n         \"煉\",\n         \"麻\",\n         \"紡\",\n         \"禁\",\n         \"廢\",\n         \"盛\",\n         \"版\",\n         \"緩\",\n         \"淨\",\n         \"睛\",\n         \"昌\",\n         \"婚\",\n         \"涉\",\n         \"筒\",\n         \"嘴\",\n         \"插\",\n         \"岸\",\n         \"朗\",\n         \"莊\",\n         \"街\",\n         \"藏\",\n         \"姑\",\n         \"貿\",\n         \"腐\",\n         \"奴\",\n         \"啦\",\n         \"慣\",\n         \"乘\",\n         \"夥\",\n         \"恢\",\n         \"勻\",\n         \"紗\",\n         \"扎\",\n         \"辯\",\n         \"耳\",\n         \"彪\",\n         \"臣\",\n         \"億\",\n         \"璃\",\n         \"抵\",\n         \"脈\",\n         \"秀\",\n         \"薩\",\n         \"俄\",\n         \"網\",\n         \"舞\",\n         \"店\",\n         \"噴\",\n         \"縱\",\n         \"寸\",\n         \"汗\",\n         \"掛\",\n         \"洪\",\n         \"賀\",\n         \"閃\",\n         \"柬\",\n         \"爆\",\n         \"烯\",\n         \"津\",\n         \"稻\",\n         \"牆\",\n         \"軟\",\n         \"勇\",\n         \"像\",\n         \"滾\",\n         \"厘\",\n         \"蒙\",\n         \"芳\",\n         \"肯\",\n         \"坡\",\n         \"柱\",\n         \"盪\",\n         \"腿\",\n         \"儀\",\n         \"旅\",\n         \"尾\",\n         \"軋\",\n         \"冰\",\n         \"貢\",\n         \"登\",\n         \"黎\",\n         \"削\",\n         \"鑽\",\n         \"勒\",\n         \"逃\",\n         \"障\",\n         \"氨\",\n         \"郭\",\n         \"峰\",\n         \"幣\",\n         \"港\",\n         \"伏\",\n         \"軌\",\n         \"畝\",\n         \"畢\",\n         \"擦\",\n         \"莫\",\n         \"刺\",\n         \"浪\",\n         \"秘\",\n         \"援\",\n         \"株\",\n         \"健\",\n         \"售\",\n         \"股\",\n         \"島\",\n         \"甘\",\n         \"泡\",\n         \"睡\",\n         \"童\",\n         \"鑄\",\n         \"湯\",\n         \"閥\",\n         \"休\",\n         \"匯\",\n         \"舍\",\n         \"牧\",\n         \"繞\",\n         \"炸\",\n         \"哲\",\n         \"磷\",\n         \"績\",\n         \"朋\",\n         \"淡\",\n         \"尖\",\n         \"啟\",\n         \"陷\",\n         \"柴\",\n         \"呈\",\n         \"徒\",\n         \"顏\",\n         \"淚\",\n         \"稍\",\n         \"忘\",\n         \"泵\",\n         \"藍\",\n         \"拖\",\n         \"洞\",\n         \"授\",\n         \"鏡\",\n         \"辛\",\n         \"壯\",\n         \"鋒\",\n         \"貧\",\n         \"虛\",\n         \"彎\",\n         \"摩\",\n         \"泰\",\n         \"幼\",\n         \"廷\",\n         \"尊\",\n         \"窗\",\n         \"綱\",\n         \"弄\",\n         \"隸\",\n         \"疑\",\n         \"氏\",\n         \"宮\",\n         \"姐\",\n         \"震\",\n         \"瑞\",\n         \"怪\",\n         \"尤\",\n         \"琴\",\n         \"循\",\n         \"描\",\n         \"膜\",\n         \"違\",\n         \"夾\",\n         \"腰\",\n         \"緣\",\n         \"珠\",\n         \"窮\",\n         \"森\",\n         \"枝\",\n         \"竹\",\n         \"溝\",\n         \"催\",\n         \"繩\",\n         \"憶\",\n         \"邦\",\n         \"剩\",\n         \"幸\",\n         \"漿\",\n         \"欄\",\n         \"擁\",\n         \"牙\",\n         \"貯\",\n         \"禮\",\n         \"濾\",\n         \"鈉\",\n         \"紋\",\n         \"罷\",\n         \"拍\",\n         \"咱\",\n         \"喊\",\n         \"袖\",\n         \"埃\",\n         \"勤\",\n         \"罰\",\n         \"焦\",\n         \"潛\",\n         \"伍\",\n         \"墨\",\n         \"欲\",\n         \"縫\",\n         \"姓\",\n         \"刊\",\n         \"飽\",\n         \"仿\",\n         \"獎\",\n         \"鋁\",\n         \"鬼\",\n         \"麗\",\n         \"跨\",\n         \"默\",\n         \"挖\",\n         \"鏈\",\n         \"掃\",\n         \"喝\",\n         \"袋\",\n         \"炭\",\n         \"污\",\n         \"幕\",\n         \"諸\",\n         \"弧\",\n         \"勵\",\n         \"梅\",\n         \"奶\",\n         \"潔\",\n         \"災\",\n         \"舟\",\n         \"鑑\",\n         \"苯\",\n         \"訟\",\n         \"抱\",\n         \"毀\",\n         \"懂\",\n         \"寒\",\n         \"智\",\n         \"埔\",\n         \"寄\",\n         \"屆\",\n         \"躍\",\n         \"渡\",\n         \"挑\",\n         \"丹\",\n         \"艱\",\n         \"貝\",\n         \"碰\",\n         \"拔\",\n         \"爹\",\n         \"戴\",\n         \"碼\",\n         \"夢\",\n         \"芽\",\n         \"熔\",\n         \"赤\",\n         \"漁\",\n         \"哭\",\n         \"敬\",\n         \"顆\",\n         \"奔\",\n         \"鉛\",\n         \"仲\",\n         \"虎\",\n         \"稀\",\n         \"妹\",\n         \"乏\",\n         \"珍\",\n         \"申\",\n         \"桌\",\n         \"遵\",\n         \"允\",\n         \"隆\",\n         \"螺\",\n         \"倉\",\n         \"魏\",\n         \"銳\",\n         \"曉\",\n         \"氮\",\n         \"兼\",\n         \"隱\",\n         \"礙\",\n         \"赫\",\n         \"撥\",\n         \"忠\",\n         \"肅\",\n         \"缸\",\n         \"牽\",\n         \"搶\",\n         \"博\",\n         \"巧\",\n         \"殼\",\n         \"兄\",\n         \"杜\",\n         \"訊\",\n         \"誠\",\n         \"碧\",\n         \"祥\",\n         \"柯\",\n         \"頁\",\n         \"巡\",\n         \"矩\",\n         \"悲\",\n         \"灌\",\n         \"齡\",\n         \"倫\",\n         \"票\",\n         \"尋\",\n         \"桂\",\n         \"鋪\",\n         \"聖\",\n         \"恐\",\n         \"恰\",\n         \"鄭\",\n         \"趣\",\n         \"抬\",\n         \"荒\",\n         \"騰\",\n         \"貼\",\n         \"柔\",\n         \"滴\",\n         \"猛\",\n         \"闊\",\n         \"輛\",\n         \"妻\",\n         \"填\",\n         \"撤\",\n         \"儲\",\n         \"簽\",\n         \"鬧\",\n         \"擾\",\n         \"紫\",\n         \"砂\",\n         \"遞\",\n         \"戲\",\n         \"吊\",\n         \"陶\",\n         \"伐\",\n         \"餵\",\n         \"療\",\n         \"瓶\",\n         \"婆\",\n         \"撫\",\n         \"臂\",\n         \"摸\",\n         \"忍\",\n         \"蝦\",\n         \"蠟\",\n         \"鄰\",\n         \"胸\",\n         \"鞏\",\n         \"擠\",\n         \"偶\",\n         \"棄\",\n         \"槽\",\n         \"勁\",\n         \"乳\",\n         \"鄧\",\n         \"吉\",\n         \"仁\",\n         \"爛\",\n         \"磚\",\n         \"租\",\n         \"烏\",\n         \"艦\",\n         \"伴\",\n         \"瓜\",\n         \"淺\",\n         \"丙\",\n         \"暫\",\n         \"燥\",\n         \"橡\",\n         \"柳\",\n         \"迷\",\n         \"暖\",\n         \"牌\",\n         \"秧\",\n         \"膽\",\n         \"詳\",\n         \"簧\",\n         \"踏\",\n         \"瓷\",\n         \"譜\",\n         \"呆\",\n         \"賓\",\n         \"糊\",\n         \"洛\",\n         \"輝\",\n         \"憤\",\n         \"競\",\n         \"隙\",\n         \"怒\",\n         \"粘\",\n         \"乃\",\n         \"緒\",\n         \"肩\",\n         \"籍\",\n         \"敏\",\n         \"塗\",\n         \"熙\",\n         \"皆\",\n         \"偵\",\n         \"懸\",\n         \"掘\",\n         \"享\",\n         \"糾\",\n         \"醒\",\n         \"狂\",\n         \"鎖\",\n         \"淀\",\n         \"恨\",\n         \"牲\",\n         \"霸\",\n         \"爬\",\n         \"賞\",\n         \"逆\",\n         \"玩\",\n         \"陵\",\n         \"祝\",\n         \"秒\",\n         \"浙\",\n         \"貌\",\n         \"役\",\n         \"彼\",\n         \"悉\",\n         \"鴨\",\n         \"趨\",\n         \"鳳\",\n         \"晨\",\n         \"畜\",\n         \"輩\",\n         \"秩\",\n         \"卵\",\n         \"署\",\n         \"梯\",\n         \"炎\",\n         \"灘\",\n         \"棋\",\n         \"驅\",\n         \"篩\",\n         \"峽\",\n         \"冒\",\n         \"啥\",\n         \"壽\",\n         \"譯\",\n         \"浸\",\n         \"泉\",\n         \"帽\",\n         \"遲\",\n         \"矽\",\n         \"疆\",\n         \"貸\",\n         \"漏\",\n         \"稿\",\n         \"冠\",\n         \"嫩\",\n         \"脅\",\n         \"芯\",\n         \"牢\",\n         \"叛\",\n         \"蝕\",\n         \"奧\",\n         \"鳴\",\n         \"嶺\",\n         \"羊\",\n         \"憑\",\n         \"串\",\n         \"塘\",\n         \"繪\",\n         \"酵\",\n         \"融\",\n         \"盆\",\n         \"錫\",\n         \"廟\",\n         \"籌\",\n         \"凍\",\n         \"輔\",\n         \"攝\",\n         \"襲\",\n         \"筋\",\n         \"拒\",\n         \"僚\",\n         \"旱\",\n         \"鉀\",\n         \"鳥\",\n         \"漆\",\n         \"沈\",\n         \"眉\",\n         \"疏\",\n         \"添\",\n         \"棒\",\n         \"穗\",\n         \"硝\",\n         \"韓\",\n         \"逼\",\n         \"扭\",\n         \"僑\",\n         \"涼\",\n         \"挺\",\n         \"碗\",\n         \"栽\",\n         \"炒\",\n         \"杯\",\n         \"患\",\n         \"餾\",\n         \"勸\",\n         \"豪\",\n         \"遼\",\n         \"勃\",\n         \"鴻\",\n         \"旦\",\n         \"吏\",\n         \"拜\",\n         \"狗\",\n         \"埋\",\n         \"輥\",\n         \"掩\",\n         \"飲\",\n         \"搬\",\n         \"罵\",\n         \"辭\",\n         \"勾\",\n         \"扣\",\n         \"估\",\n         \"蔣\",\n         \"絨\",\n         \"霧\",\n         \"丈\",\n         \"朵\",\n         \"姆\",\n         \"擬\",\n         \"宇\",\n         \"輯\",\n         \"陝\",\n         \"雕\",\n         \"償\",\n         \"蓄\",\n         \"崇\",\n         \"剪\",\n         \"倡\",\n         \"廳\",\n         \"咬\",\n         \"駛\",\n         \"薯\",\n         \"刷\",\n         \"斥\",\n         \"番\",\n         \"賦\",\n         \"奉\",\n         \"佛\",\n         \"澆\",\n         \"漫\",\n         \"曼\",\n         \"扇\",\n         \"鈣\",\n         \"桃\",\n         \"扶\",\n         \"仔\",\n         \"返\",\n         \"俗\",\n         \"虧\",\n         \"腔\",\n         \"鞋\",\n         \"棱\",\n         \"覆\",\n         \"框\",\n         \"悄\",\n         \"叔\",\n         \"撞\",\n         \"騙\",\n         \"勘\",\n         \"旺\",\n         \"沸\",\n         \"孤\",\n         \"吐\",\n         \"孟\",\n         \"渠\",\n         \"屈\",\n         \"疾\",\n         \"妙\",\n         \"惜\",\n         \"仰\",\n         \"狠\",\n         \"脹\",\n         \"諧\",\n         \"拋\",\n         \"黴\",\n         \"桑\",\n         \"崗\",\n         \"嘛\",\n         \"衰\",\n         \"盜\",\n         \"滲\",\n         \"臟\",\n         \"賴\",\n         \"湧\",\n         \"甜\",\n         \"曹\",\n         \"閱\",\n         \"肌\",\n         \"哩\",\n         \"厲\",\n         \"烴\",\n         \"緯\",\n         \"毅\",\n         \"昨\",\n         \"偽\",\n         \"症\",\n         \"煮\",\n         \"嘆\",\n         \"釘\",\n         \"搭\",\n         \"莖\",\n         \"籠\",\n         \"酷\",\n         \"偷\",\n         \"弓\",\n         \"錐\",\n         \"恆\",\n         \"傑\",\n         \"坑\",\n         \"鼻\",\n         \"翼\",\n         \"綸\",\n         \"敘\",\n         \"獄\",\n         \"逮\",\n         \"罐\",\n         \"絡\",\n         \"棚\",\n         \"抑\",\n         \"膨\",\n         \"蔬\",\n         \"寺\",\n         \"驟\",\n         \"穆\",\n         \"冶\",\n         \"枯\",\n         \"冊\",\n         \"屍\",\n         \"凸\",\n         \"紳\",\n         \"坯\",\n         \"犧\",\n         \"焰\",\n         \"轟\",\n         \"欣\",\n         \"晉\",\n         \"瘦\",\n         \"禦\",\n         \"錠\",\n         \"錦\",\n         \"喪\",\n         \"旬\",\n         \"鍛\",\n         \"壟\",\n         \"搜\",\n         \"撲\",\n         \"邀\",\n         \"亭\",\n         \"酯\",\n         \"邁\",\n         \"舒\",\n         \"脆\",\n         \"酶\",\n         \"閒\",\n         \"憂\",\n         \"酚\",\n         \"頑\",\n         \"羽\",\n         \"漲\",\n         \"卸\",\n         \"仗\",\n         \"陪\",\n         \"闢\",\n         \"懲\",\n         \"杭\",\n         \"姚\",\n         \"肚\",\n         \"捉\",\n         \"飄\",\n         \"漂\",\n         \"昆\",\n         \"欺\",\n         \"吾\",\n         \"郎\",\n         \"烷\",\n         \"汁\",\n         \"呵\",\n         \"飾\",\n         \"蕭\",\n         \"雅\",\n         \"郵\",\n         \"遷\",\n         \"燕\",\n         \"撒\",\n         \"姻\",\n         \"赴\",\n         \"宴\",\n         \"煩\",\n         \"債\",\n         \"帳\",\n         \"斑\",\n         \"鈴\",\n         \"旨\",\n         \"醇\",\n         \"董\",\n         \"餅\",\n         \"雛\",\n         \"姿\",\n         \"拌\",\n         \"傅\",\n         \"腹\",\n         \"妥\",\n         \"揉\",\n         \"賢\",\n         \"拆\",\n         \"歪\",\n         \"葡\",\n         \"胺\",\n         \"丟\",\n         \"浩\",\n         \"徽\",\n         \"昂\",\n         \"墊\",\n         \"擋\",\n         \"覽\",\n         \"貪\",\n         \"慰\",\n         \"繳\",\n         \"汪\",\n         \"慌\",\n         \"馮\",\n         \"諾\",\n         \"姜\",\n         \"誼\",\n         \"兇\",\n         \"劣\",\n         \"誣\",\n         \"耀\",\n         \"昏\",\n         \"躺\",\n         \"盈\",\n         \"騎\",\n         \"喬\",\n         \"溪\",\n         \"叢\",\n         \"盧\",\n         \"抹\",\n         \"悶\",\n         \"諮\",\n         \"刮\",\n         \"駕\",\n         \"纜\",\n         \"悟\",\n         \"摘\",\n         \"鉺\",\n         \"擲\",\n         \"頗\",\n         \"幻\",\n         \"柄\",\n         \"惠\",\n         \"慘\",\n         \"佳\",\n         \"仇\",\n         \"臘\",\n         \"窩\",\n         \"滌\",\n         \"劍\",\n         \"瞧\",\n         \"堡\",\n         \"潑\",\n         \"蔥\",\n         \"罩\",\n         \"霍\",\n         \"撈\",\n         \"胎\",\n         \"蒼\",\n         \"濱\",\n         \"倆\",\n         \"捅\",\n         \"湘\",\n         \"砍\",\n         \"霞\",\n         \"邵\",\n         \"萄\",\n         \"瘋\",\n         \"淮\",\n         \"遂\",\n         \"熊\",\n         \"糞\",\n         \"烘\",\n         \"宿\",\n         \"檔\",\n         \"戈\",\n         \"駁\",\n         \"嫂\",\n         \"裕\",\n         \"徙\",\n         \"箭\",\n         \"捐\",\n         \"腸\",\n         \"撐\",\n         \"曬\",\n         \"辨\",\n         \"殿\",\n         \"蓮\",\n         \"攤\",\n         \"攪\",\n         \"醬\",\n         \"屏\",\n         \"疫\",\n         \"哀\",\n         \"蔡\",\n         \"堵\",\n         \"沫\",\n         \"皺\",\n         \"暢\",\n         \"疊\",\n         \"閣\",\n         \"萊\",\n         \"敲\",\n         \"轄\",\n         \"鉤\",\n         \"痕\",\n         \"壩\",\n         \"巷\",\n         \"餓\",\n         \"禍\",\n         \"丘\",\n         \"玄\",\n         \"溜\",\n         \"曰\",\n         \"邏\",\n         \"彭\",\n         \"嘗\",\n         \"卿\",\n         \"妨\",\n         \"艇\",\n         \"吞\",\n         \"韋\",\n         \"怨\",\n         \"矮\",\n         \"歇\"}};\n\n// Word lists from:\n// github.com/bitcoin/bips/blob/master/bip-0039/bip-0039-wordlists.md\nconst dictionary_list all{\n    &en,\n    &es,\n    &ja,\n    &zh_Hans,\n    &zh_Hant,\n};\n\n} // namespace language\n} // namespace wallet\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/wallet/dictionary_symbol.cpp",
    "content": "﻿/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/wallet/dictionary.hpp>\n#include <boost/algorithm/string.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\nnamespace symbol\n{\n\nconst std::array<const char *, 64> ban_list = {\n    \"HUJINTAO\",\n    \"WENJIABAO\",\n    \"WJB\",\n    \"XIJINPING\",\n    \"XJP\",\n    \"TANKMAN\",\n    \"LIUSI\",\n    \"VPN\",\n    \"64MEMO\",\n    \"GFW\",\n    \"FREEDOM\",\n    \"FREECHINA\",\n    \"LIKEQIANG\",\n    \"ZHOUYONGKANG\",\n    \"LICHANGCHUN\",\n    \"WUBANGGUO\",\n    \"HEGUOQIANG\",\n    \"JIANGZEMIN\",\n    \"JZM\",\n    \"FUCK\",\n    \"SHIT\",\n    \"198964\",\n    \"GONGCHANDANG\",\n    \"GCD\",\n    \"TUGONG\",\n    \"COMMUNISM\",\n    \"FALUNGONG\",\n    \"COMMUNIST\",\n    \"PARTY\",\n    \"CCP\",\n    \"CPC\",\n    \"HONGZHI\",\n    \"LIHONGZHI\",\n    \"LHZ\",\n    \"DAJIYUAN\",\n    \"ZANGDU\",\n    \"DALAI\",\n    \"MINZHU\",\n    \"CHINA\",\n    \"CHINESE\",\n    \"TAIWAN\",\n    \"SHABI\",\n    \"PENIS\",\n    \"J8\",\n    \"ISLAM\",\n    \"ALLHA\",\n    \"USD\",\n    \"CNY\",\n    \"EUR\",\n    \"AUD\",\n    \"GBP\",\n    \"CHF\",\n    \"UCN\",\n    \"CURRENCY\",\n    \"TOKEN\",\n    \"BALANCE\",\n    \"EXCHANGE\",\n    \"TOKEN\",\n    \"BUY\",\n    \"SELL\",\n    \"ASK\",\n    \"BID\",\n    \"UID\",\n    \"ZEN.\"};\n\nbool is_sensitive(const std::string &symbol)\n{\n    for (auto &each : ban_list)\n    {\n        if (symbol.find(each) != std::string::npos)\n        {\n            return true;\n        }\n    }\n    return false;\n}\n\nconst std::array<const char *, 1> forbidden_list = {\n    \"UCN\"};\n\nbool is_forbidden(const std::string &symbol)\n{\n    for (auto &each : forbidden_list)\n    {\n        if (symbol == each)\n        {\n            return true;\n        }\n    }\n    return false;\n}\n\n} // namespace symbol\n} // namespace wallet\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/wallet/ec_private.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/wallet/ec_private.hpp>\n\n#include <cstdint>\n#include <string>\n#include <boost/program_options.hpp>\n#include <UChain/coin/formats/base_58.hpp>\n#include <UChain/coin/math/checksum.hpp>\n#include <UChain/coin/math/elliptic_curve.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/wallet/ec_public.hpp>\n#include <UChain/coin/wallet/payment_address.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\nconst uint8_t ec_private::wif = 0x80;\n//- bad modify\nuint8_t ec_private::mainnet_p2kh = 0x44;\nconst uint16_t ec_private::mainnet = uint8_t(wif) << 8 | mainnet_p2kh;\nconst uint8_t ec_private::compressed_sentinel = 0x01;\n\nec_private::ec_private()\n    : valid_(false), compress_(true), version_(0), secret_(null_hash)\n{\n}\n\nec_private::ec_private(const ec_private &other)\n    : valid_(other.valid_), compress_(other.compress_), version_(other.version_),\n      secret_(other.secret_)\n{\n}\n\nec_private::ec_private(const std::string &wif, uint8_t address_version)\n    : ec_private(from_string(wif, address_version))\n{\n}\n\nec_private::ec_private(const wif_compressed &wif, uint8_t address_version)\n    : ec_private(from_compressed(wif, address_version))\n{\n}\n\nec_private::ec_private(const wif_uncompressed &wif, uint8_t address_version)\n    : ec_private(from_uncompressed(wif, address_version))\n{\n}\n\nec_private::ec_private(const ec_secret &secret, uint16_t version, bool compress)\n    : valid_(true), compress_(compress), version_(version), secret_(secret)\n{\n}\n\n// Validators.\n// ----------------------------------------------------------------------------\n\nbool ec_private::is_wif(data_slice decoded)\n{\n    const auto size = decoded.size();\n    if (size != wif_compressed_size && size != wif_uncompressed_size)\n        return false;\n\n    if (!verify_checksum(decoded))\n        return false;\n\n    return (size == wif_uncompressed_size) ||\n           decoded.data()[1 + ec_secret_size] == compressed_sentinel;\n}\n\n// Factories.\n// ----------------------------------------------------------------------------\n\nec_private ec_private::from_string(const std::string &wif,\n                                   uint8_t address_version)\n{\n    data_chunk decoded;\n    if (!decode_base58(decoded, wif) || !is_wif(decoded))\n        return ec_private();\n\n    const auto compressed = decoded.size() == wif_compressed_size;\n    return compressed ? ec_private(to_array<wif_compressed_size>(decoded), address_version) : ec_private(to_array<wif_uncompressed_size>(decoded), address_version);\n}\n\nec_private ec_private::from_compressed(const wif_compressed &wif,\n                                       uint8_t address_version)\n{\n    if (!is_wif(wif))\n        return ec_private();\n\n    const uint16_t version = to_version(address_version, wif.front());\n    const auto secret = slice<1, ec_secret_size + 1>(wif);\n    return ec_private(secret, version, true);\n}\n\nec_private ec_private::from_uncompressed(const wif_uncompressed &wif,\n                                         uint8_t address_version)\n{\n    if (!is_wif(wif))\n        return ec_private();\n\n    const uint16_t version = to_version(address_version, wif.front());\n    const auto secret = slice<1, ec_secret_size + 1>(wif);\n    return ec_private(secret, version, false);\n}\n\n// Cast operators.\n// ----------------------------------------------------------------------------\n\nec_private::operator const bool() const\n{\n    return valid_;\n}\n\nec_private::operator const ec_secret &() const\n{\n    return secret_;\n}\n\n// Serializer.\n// ----------------------------------------------------------------------------\n\n// Conversion to WIF loses payment address version info.\nstd::string ec_private::encoded() const\n{\n    if (compressed())\n    {\n        wif_compressed wif;\n        const auto prefix = to_array(wif_version());\n        const auto compressed = to_array(compressed_sentinel);\n        build_checked_array(wif, {prefix, secret_, compressed});\n        return encode_base58(wif);\n    }\n\n    wif_uncompressed wif;\n    const auto prefix = to_array(wif_version());\n    build_checked_array(wif, {prefix, secret_});\n    return encode_base58(wif);\n}\n\n// Accessors.\n// ----------------------------------------------------------------------------\n\nconst ec_secret &ec_private::secret() const\n{\n    return secret_;\n}\n\nconst uint16_t ec_private::version() const\n{\n    return version_;\n}\n\nconst uint8_t ec_private::payment_version() const\n{\n    return to_address_prefix(version_);\n}\n\nconst uint8_t ec_private::wif_version() const\n{\n    return to_wif_prefix(version_);\n}\n\nconst bool ec_private::compressed() const\n{\n    return compress_;\n}\n\n// Methods.\n// ----------------------------------------------------------------------------\n\n// Conversion to ec_public loses all version information.\n// In the case of failure the key is always compressed (ec_compressed_null).\nec_public ec_private::to_public() const\n{\n    ec_compressed point;\n    return valid_ && secret_to_public(point, secret_) ? ec_public(point, compressed()) : ec_public();\n}\n\npayment_address ec_private::to_payment_address() const\n{\n    return payment_address(*this);\n}\n\n// Operators.\n// ----------------------------------------------------------------------------\n\nec_private &ec_private::operator=(const ec_private &other)\n{\n    valid_ = other.valid_;\n    compress_ = other.compress_;\n    version_ = other.version_;\n    secret_ = other.secret_;\n    return *this;\n}\n\nbool ec_private::operator<(const ec_private &other) const\n{\n    return encoded() < other.encoded();\n}\n\nbool ec_private::operator==(const ec_private &other) const\n{\n    return valid_ == other.valid_ && compress_ == other.compress_ &&\n           version_ == other.version_ && secret_ == other.secret_;\n}\n\nbool ec_private::operator!=(const ec_private &other) const\n{\n    return !(*this == other);\n}\n\nstd::istream &operator>>(std::istream &in, ec_private &to)\n{\n    std::string value;\n    in >> value;\n    to = ec_private(value);\n\n    if (!to)\n    {\n        using namespace boost::program_options;\n        BOOST_THROW_EXCEPTION(invalid_option_value(value));\n    }\n\n    return in;\n}\n\nstd::ostream &operator<<(std::ostream &out, const ec_private &of)\n{\n    out << of.encoded();\n    return out;\n}\n\n} // namespace wallet\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/wallet/ec_public.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/wallet/ec_public.hpp>\n\n#include <boost/program_options.hpp>\n#include <UChain/coin/formats/base_16.hpp>\n#include <UChain/coin/math/elliptic_curve.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/wallet/ec_private.hpp>\n#include <UChain/coin/wallet/payment_address.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\nconst uint8_t ec_public::compressed_even = 0x02;\nconst uint8_t ec_public::compressed_odd = 0x03;\nconst uint8_t ec_public::uncompressed = 0x04;\n//- bad modify\nuint8_t ec_public::mainnet_p2kh = 0x44;\n\nec_public::ec_public()\n    : valid_(false), compress_(true), point_(null_compressed_point)\n{\n}\n\nec_public::ec_public(const ec_public &other)\n    : valid_(other.valid_), compress_(other.compress_), point_(other.point_)\n{\n}\n\nec_public::ec_public(const ec_private &secret)\n    : ec_public(from_private(secret))\n{\n}\n\nec_public::ec_public(const data_chunk &decoded)\n    : ec_public(from_data(decoded))\n{\n}\n\nec_public::ec_public(const std::string &base16)\n    : ec_public(from_string(base16))\n{\n}\n\nec_public::ec_public(const ec_uncompressed &point, bool compress)\n    : ec_public(from_point(point, compress))\n{\n}\n\nec_public::ec_public(const ec_compressed &point, bool compress)\n    : valid_(true), compress_(compress), point_(point)\n{\n}\n\n// Validators.\n// ----------------------------------------------------------------------------\n\nbool ec_public::is_point(data_slice decoded)\n{\n    return bc::is_public_key(decoded);\n}\n\n// Factories.\n// ----------------------------------------------------------------------------\n\nec_public ec_public::from_private(const ec_private &secret)\n{\n    if (!secret)\n        return ec_public();\n\n    return ec_public(secret.to_public());\n}\n\nec_public ec_public::from_string(const std::string &base16)\n{\n    data_chunk decoded;\n    if (!decode_base16(decoded, base16))\n        return ec_public();\n\n    return ec_public(decoded);\n}\n\nec_public ec_public::from_data(const data_chunk &decoded)\n{\n    if (!is_point(decoded))\n        return ec_public();\n\n    if (decoded.size() == ec_compressed_size)\n        return ec_public(to_array<ec_compressed_size>(decoded), true);\n\n    ec_compressed compressed;\n    return bc::compress(compressed, to_array<ec_uncompressed_size>(decoded)) ? ec_public(compressed, false) : ec_public();\n}\n\nec_public ec_public::from_point(const ec_uncompressed &point, bool compress)\n{\n    if (!is_point(point))\n        return ec_public();\n\n    ec_compressed compressed;\n    return bc::compress(compressed, point) ? ec_public(compressed, compress) : ec_public();\n}\n\n// Cast operators.\n// ----------------------------------------------------------------------------\n\nec_public::operator const bool() const\n{\n    return valid_;\n}\n\nec_public::operator const ec_compressed &() const\n{\n    return point_;\n}\n\n// Serializer.\n// ----------------------------------------------------------------------------\n\nstd::string ec_public::encoded() const\n{\n    if (compressed())\n        return encode_base16(point_);\n\n    // If the point is valid it should always decompress, but if not, is null.\n    ec_uncompressed uncompressed(null_uncompressed_point);\n    to_uncompressed(uncompressed);\n    return encode_base16(uncompressed);\n}\n\n// Accessors.\n// ----------------------------------------------------------------------------\n\nconst ec_compressed &ec_public::point() const\n{\n    return point_;\n}\n\nconst bool ec_public::compressed() const\n{\n    return compress_;\n}\n\n// Methods.\n// ----------------------------------------------------------------------------\n\nbool ec_public::to_data(data_chunk &out) const\n{\n    if (!valid_)\n        return false;\n\n    if (compressed())\n    {\n        out.resize(ec_compressed_size);\n        std::copy(point_.begin(), point_.end(), out.begin());\n        return true;\n    }\n\n    ec_uncompressed uncompressed;\n    if (to_uncompressed(uncompressed))\n    {\n        out.resize(ec_uncompressed_size);\n        std::copy(uncompressed.begin(), uncompressed.end(), out.begin());\n        return true;\n    }\n\n    return false;\n}\n\nbool ec_public::to_uncompressed(ec_uncompressed &out) const\n{\n    if (!valid_)\n        return false;\n\n    return bc::decompress(out, to_array<ec_compressed_size>(point_));\n}\n\npayment_address ec_public::to_payment_address(uint8_t version) const\n{\n    return payment_address(*this, version);\n}\n\n// Operators.\n// ----------------------------------------------------------------------------\n\nec_public &ec_public::operator=(const ec_public &other)\n{\n    valid_ = other.valid_;\n    compress_ = other.compress_;\n    version_ = other.version_;\n    point_ = other.point_;\n    return *this;\n}\n\nbool ec_public::operator<(const ec_public &other) const\n{\n    return encoded() < other.encoded();\n}\n\nbool ec_public::operator==(const ec_public &other) const\n{\n    return valid_ == other.valid_ && compress_ == other.compress_ &&\n           version_ == other.version_ && point_ == other.point_;\n}\n\nbool ec_public::operator!=(const ec_public &other) const\n{\n    return !(*this == other);\n}\n\nstd::istream &operator>>(std::istream &in, ec_public &to)\n{\n    std::string value;\n    in >> value;\n    to = ec_public(value);\n\n    if (!to)\n    {\n        using namespace boost::program_options;\n        BOOST_THROW_EXCEPTION(invalid_option_value(value));\n    }\n\n    return in;\n}\n\nstd::ostream &operator<<(std::ostream &out, const ec_public &of)\n{\n    out << of.encoded();\n    return out;\n}\n\n} // namespace wallet\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/wallet/ek_private.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/wallet/ek_private.hpp>\n\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <boost/program_options.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/formats/base_58.hpp>\n#include <UChain/coin/math/checksum.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\nek_private::ek_private()\n    : valid_(false), private_()\n{\n}\n\nek_private::ek_private(const std::string &encoded)\n    : ek_private(from_string(encoded))\n{\n}\n\nek_private::ek_private(const ek_private &other)\n    : valid_(other.valid_), private_(other.private_)\n{\n}\n\nek_private::ek_private(const encrypted_private &value)\n    : valid_(true), private_(value)\n{\n}\n\n// Factories.\n// ----------------------------------------------------------------------------\n\nek_private ek_private::from_string(const std::string &encoded)\n{\n    // TODO: incorporate existing parser here, setting new members.\n\n    encrypted_private key;\n    return decode_base58(key, encoded) && verify_checksum(key) ? ek_private(key) : ek_private();\n}\n\n// Cast operators.\n// ----------------------------------------------------------------------------\n\nek_private::operator const bool() const\n{\n    return valid_;\n}\n\nek_private::operator const encrypted_private &() const\n{\n    return private_;\n}\n\n// Serializer.\n// ----------------------------------------------------------------------------\n\nstd::string ek_private::encoded() const\n{\n    return encode_base58(private_);\n}\n\n// Accessors.\n// ----------------------------------------------------------------------------\n\nconst encrypted_private &ek_private::private_key() const\n{\n    return private_;\n}\n\n// Operators.\n// ----------------------------------------------------------------------------\n\nek_private &ek_private::operator=(const ek_private &other)\n{\n    valid_ = other.valid_;\n    private_ = other.private_;\n    return *this;\n}\n\nbool ek_private::operator<(const ek_private &other) const\n{\n    return encoded() < other.encoded();\n}\n\nbool ek_private::operator==(const ek_private &other) const\n{\n    return valid_ == other.valid_ && private_ == other.private_;\n}\n\nbool ek_private::operator!=(const ek_private &other) const\n{\n    return !(*this == other);\n}\n\nstd::istream &operator>>(std::istream &in, ek_private &to)\n{\n    std::string value;\n    in >> value;\n    to = ek_private(value);\n\n    if (!to)\n    {\n        using namespace boost::program_options;\n        BOOST_THROW_EXCEPTION(invalid_option_value(value));\n    }\n\n    return in;\n}\n\nstd::ostream &operator<<(std::ostream &out, const ek_private &of)\n{\n    out << of.encoded();\n    return out;\n}\n\n} // namespace wallet\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/wallet/ek_public.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/wallet/ek_public.hpp>\n\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <boost/program_options.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/formats/base_58.hpp>\n#include <UChain/coin/math/checksum.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\nek_public::ek_public()\n    : valid_(false), public_()\n{\n}\n\nek_public::ek_public(const std::string &encoded)\n    : ek_public(from_string(encoded))\n{\n}\n\nek_public::ek_public(const ek_public &other)\n    : valid_(other.valid_), public_(other.public_)\n{\n}\n\nek_public::ek_public(const encrypted_public &value)\n    : valid_(true), public_(value)\n{\n}\n\n// Factories.\n// ----------------------------------------------------------------------------\n\nek_public ek_public::from_string(const std::string &encoded)\n{\n    // TODO: incorporate existing parser here, setting new members.\n\n    encrypted_public key;\n    return decode_base58(key, encoded) && verify_checksum(key) ? ek_public(key) : ek_public();\n}\n\n// Cast operators.\n// ----------------------------------------------------------------------------\n\nek_public::operator const bool() const\n{\n    return valid_;\n}\n\nek_public::operator const encrypted_public &() const\n{\n    return public_;\n}\n\n// Serializer.\n// ----------------------------------------------------------------------------\n\nstd::string ek_public::encoded() const\n{\n    return encode_base58(public_);\n}\n\n// Accessors.\n// ----------------------------------------------------------------------------\n\nconst encrypted_public &ek_public::public_key() const\n{\n    return public_;\n}\n\n// Operators.\n// ----------------------------------------------------------------------------\n\nek_public &ek_public::operator=(const ek_public &other)\n{\n    valid_ = other.valid_;\n    public_ = other.public_;\n    return *this;\n}\n\nbool ek_public::operator<(const ek_public &other) const\n{\n    return encoded() < other.encoded();\n}\n\nbool ek_public::operator==(const ek_public &other) const\n{\n    return valid_ == other.valid_ && public_ == other.public_;\n}\n\nbool ek_public::operator!=(const ek_public &other) const\n{\n    return !(*this == other);\n}\n\nstd::istream &operator>>(std::istream &in, ek_public &to)\n{\n    std::string value;\n    in >> value;\n    to = ek_public(value);\n\n    if (!to)\n    {\n        using namespace boost::program_options;\n        BOOST_THROW_EXCEPTION(invalid_option_value(value));\n    }\n\n    return in;\n}\n\nstd::ostream &operator<<(std::ostream &out, const ek_public &of)\n{\n    out << of.encoded();\n    return out;\n}\n\n} // namespace wallet\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/wallet/ek_token.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/wallet/ek_token.hpp>\n\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <boost/program_options.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/formats/base_58.hpp>\n#include <UChain/coin/math/checksum.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\nek_token::ek_token()\n    : valid_(false), token_()\n{\n}\n\nek_token::ek_token(const std::string &encoded)\n    : ek_token(from_string(encoded))\n{\n}\n\nek_token::ek_token(const ek_token &other)\n    : valid_(other.valid_), token_(other.token_)\n{\n}\n\nek_token::ek_token(const encrypted_token &value)\n    : valid_(true), token_(value)\n{\n}\n\n// Factories.\n// ----------------------------------------------------------------------------\n\nek_token ek_token::from_string(const std::string &encoded)\n{\n    // TODO: incorporate existing parser here, setting new members.\n\n    encrypted_token key;\n    return decode_base58(key, encoded) && verify_checksum(key) ? ek_token(key) : ek_token();\n}\n\n// Cast operators.\n// ----------------------------------------------------------------------------\n\nek_token::operator const bool() const\n{\n    return valid_;\n}\n\nek_token::operator const encrypted_token &() const\n{\n    return token_;\n}\n\n// Serializer.\n// ----------------------------------------------------------------------------\n\nstd::string ek_token::encoded() const\n{\n    return encode_base58(token_);\n}\n\n// Accessors.\n// ----------------------------------------------------------------------------\n\nconst encrypted_token &ek_token::token() const\n{\n    return token_;\n}\n\n// Operators.\n// ----------------------------------------------------------------------------\n\nek_token &ek_token::operator=(const ek_token &other)\n{\n    valid_ = other.valid_;\n    token_ = other.token_;\n    return *this;\n}\n\nbool ek_token::operator<(const ek_token &other) const\n{\n    return encoded() < other.encoded();\n}\n\nbool ek_token::operator==(const ek_token &other) const\n{\n    return valid_ == other.valid_ && token_ == other.token_;\n}\n\nbool ek_token::operator!=(const ek_token &other) const\n{\n    return !(*this == other);\n}\n\nstd::istream &operator>>(std::istream &in, ek_token &to)\n{\n    std::string value;\n    in >> value;\n    to = ek_token(value);\n\n    if (!to)\n    {\n        using namespace boost::program_options;\n        BOOST_THROW_EXCEPTION(invalid_option_value(value));\n    }\n\n    return in;\n}\n\nstd::ostream &operator<<(std::ostream &out, const ek_token &of)\n{\n    out << of.encoded();\n    return out;\n}\n\n} // namespace wallet\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/wallet/encrypted_keys.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/wallet/encrypted_keys.hpp>\n\n#include <cstdint>\n#include <cstddef>\n#include <algorithm>\n#include <stdexcept>\n#include <boost/locale.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/math/checksum.hpp>\n#include <UChain/coin/math/crypto.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/math/elliptic_curve.hpp>\n#include <UChain/coin/unicode/unicode.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/endian.hpp>\n#include <UChain/coin/wallet/ec_private.hpp>\n#include <UChain/coin/wallet/ec_public.hpp>\n#include \"parse_encrypted_keys/parse_encrypted_key.hpp\"\n#include \"parse_encrypted_keys/parse_encrypted_prefix.hpp\"\n#include \"parse_encrypted_keys/parse_encrypted_private.hpp\"\n#include \"parse_encrypted_keys/parse_encrypted_public.hpp\"\n#include \"parse_encrypted_keys/parse_encrypted_token.hpp\"\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\n// Alias commonly-used constants for brevity.\nstatic constexpr auto half = half_hash_size;\nstatic constexpr auto quarter = quarter_hash_size;\n\n// Ensure that hash sizes are aligned with AES block size.\nstatic_assert(2 * quarter == bc::aes256_block_size, \"oops!\");\n\n// address_\n// ----------------------------------------------------------------------------\n\nstatic hash_digest address_hash(const payment_address &address)\n{\n    return bitcoin_hash(to_chunk(address.encoded()));\n}\n\nstatic bool address_salt(ek_salt &salt, const payment_address &address)\n{\n    salt = slice<0, ek_salt_size>(address_hash(address));\n    return true;\n}\n\nstatic bool address_salt(ek_salt &salt, const ec_compressed &point,\n                         uint8_t version, bool compressed)\n{\n    payment_address address({point, compressed}, version);\n    return address ? address_salt(salt, address) : false;\n}\n\nstatic bool address_salt(ek_salt &salt, const ec_secret &secret,\n                         uint8_t version, bool compressed)\n{\n    payment_address address({secret, version, compressed});\n    return address ? address_salt(salt, address) : false;\n}\n\nstatic bool address_validate(const ek_salt &salt,\n                             const payment_address &address)\n{\n    const auto hash = address_hash(address);\n    return std::equal(hash.begin(), hash.begin() + salt.size(), salt.begin());\n}\n\nstatic bool address_validate(const ek_salt &salt, const ec_compressed &point,\n                             uint8_t version, bool compressed)\n{\n    payment_address address({point, compressed}, version);\n    return address ? address_validate(salt, address) : false;\n}\n\nstatic bool address_validate(const ek_salt &salt, const ec_secret &secret,\n                             uint8_t version, bool compressed)\n{\n    payment_address address({secret, version, compressed});\n    return address ? address_validate(salt, address) : false;\n}\n\n// point_\n// ----------------------------------------------------------------------------\n\nstatic hash_digest point_hash(const ec_compressed &point)\n{\n    return slice<1, ec_compressed_size>(point);\n}\n\nstatic one_byte point_sign(uint8_t byte, const hash_digest &hash)\n{\n    static constexpr uint8_t low_bit_mask = 0x01;\n    const uint8_t last_byte = hash.back();\n    const uint8_t last_byte_odd_field = last_byte & low_bit_mask;\n    const uint8_t sign_byte = byte ^ last_byte_odd_field;\n    return to_array(sign_byte);\n}\n\nstatic one_byte point_sign(const one_byte &single, const hash_digest &hash)\n{\n    return point_sign(single.front(), hash);\n}\n\n// scrypt_\n// ----------------------------------------------------------------------------\n\nstatic hash_digest scrypt_token(data_slice data, data_slice salt)\n{\n    // Arbitrary scrypt parameters from BIP-38.\n    return scrypt<hash_size>(data, salt, 16384u, 8u, 8u);\n}\n\nstatic long_hash scrypt_pair(data_slice data, data_slice salt)\n{\n    // Arbitrary scrypt parameters from BIP-38.\n    return scrypt<long_hash_size>(data, salt, 1024u, 1u, 1u);\n}\n\nstatic long_hash scrypt_private(data_slice data, data_slice salt)\n{\n    // Arbitrary scrypt parameters from BIP-38.\n    return scrypt<long_hash_size>(data, salt, 16384u, 8u, 8u);\n}\n\n// set_flags\n// ----------------------------------------------------------------------------\n\nstatic one_byte set_flags(bool compressed, bool lot_sequence, bool multiplied)\n{\n    uint8_t byte = 0;\n\n    if (compressed)\n        byte |= ek_flag::ec_compressed_key;\n\n    if (lot_sequence)\n        byte |= ek_flag::lot_sequence_key;\n\n    if (!multiplied)\n        byte |= ek_flag::ec_non_multiplied;\n\n    return to_array(byte);\n}\n\nstatic one_byte set_flags(bool compressed, bool lot_sequence)\n{\n    return set_flags(compressed, lot_sequence, false);\n}\n\nstatic one_byte set_flags(bool compressed)\n{\n    return set_flags(compressed, false);\n}\n\n// create_key_pair\n// ----------------------------------------------------------------------------\n\nstatic void create_private_key(encrypted_private &out_private,\n                               const one_byte &flags, const ek_salt &salt, const ek_entropy &entropy,\n                               const hash_digest &derived1, const hash_digest &derived2,\n                               const ek_seed &seed, uint8_t version)\n{\n    const auto prefix = parse_encrypted_private::prefix_factory(version, true);\n\n    auto encrypt1 = xor_data<half>(seed, derived1);\n    aes256_encrypt(derived2, encrypt1);\n    const auto combined = splice(slice<quarter, half>(encrypt1),\n                                 slice<half, half + quarter>(seed));\n\n    auto encrypt2 = xor_data<half>(combined, derived1, 0, half);\n    aes256_encrypt(derived2, encrypt2);\n    const auto quarter1 = slice<0, quarter>(encrypt1);\n\n    build_checked_array(out_private,\n                        {prefix,\n                         flags,\n                         salt,\n                         entropy,\n                         quarter1,\n                         encrypt2});\n}\n\nstatic bool create_public_key(encrypted_public &out_public,\n                              const one_byte &flags, const ek_salt &salt, const ek_entropy &entropy,\n                              const hash_digest &derived1, const hash_digest &derived2,\n                              const ec_secret &secret, uint8_t version)\n{\n    ec_compressed point;\n    if (!secret_to_public(point, secret))\n        return false;\n\n    const auto prefix = parse_encrypted_public::prefix_factory(version);\n    const auto hash = point_hash(point);\n\n    auto encrypted1 = xor_data<half>(hash, derived1);\n    aes256_encrypt(derived2, encrypted1);\n\n    auto encrypted2 = xor_data<half>(hash, derived1, half);\n    aes256_encrypt(derived2, encrypted2);\n\n    const auto sign = point_sign(point.front(), derived2);\n    return build_checked_array(out_public,\n                               {prefix,\n                                flags,\n                                salt,\n                                entropy,\n                                sign,\n                                encrypted1,\n                                encrypted2});\n}\n\n// There is no scenario requiring a public key, we support it for completeness.\nbool create_key_pair(encrypted_private &out_private,\n                     encrypted_public &out_public, ec_compressed &out_point,\n                     const encrypted_token &token, const ek_seed &seed, uint8_t version,\n                     bool compressed)\n{\n    const parse_encrypted_token parse(token);\n    if (!parse.valid())\n        return false;\n\n    const auto point = splice(parse.sign(), parse.data());\n    auto point_copy = point;\n    const auto factor = bitcoin_hash(seed);\n    if (!ec_multiply(point_copy, factor))\n        return false;\n\n    ek_salt salt;\n    if (!address_salt(salt, point_copy, version, compressed))\n        return false;\n\n    const auto salt_entropy = splice(salt, parse.entropy());\n    const auto derived = split(scrypt_pair(point, salt_entropy));\n    const auto flags = set_flags(compressed, parse.lot_sequence(), true);\n\n    if (!create_public_key(out_public, flags, salt, parse.entropy(),\n                           derived.left, derived.right, factor, version))\n        return false;\n\n    create_private_key(out_private, flags, salt, parse.entropy(), derived.left,\n                       derived.right, seed, version);\n\n    out_point = point_copy;\n    return true;\n}\n\nbool create_key_pair(encrypted_private &out_private, ec_compressed &out_point,\n                     const encrypted_token &token, const ek_seed &seed, uint8_t version,\n                     bool compressed)\n{\n    encrypted_public out_public;\n    return create_key_pair(out_private, out_public, out_point, token, seed,\n                           version, compressed);\n}\n/* encrypt string with extra 0 value */\nvoid aes256_common_encrypt(data_chunk &mnemonic, data_chunk &passphrase, data_chunk &encry_output)\n{\n    aes_secret sec = sha256_hash(ripemd160_hash(passphrase));\n\n    encry_output.clear();\n\n    data_chunk &data = mnemonic;\n    uint32_t start = 0, left = aes256_block_size - (data.size() % aes256_block_size);\n\n    encry_output.push_back(static_cast<uint8_t>(left)); // bytes counts which not be encrypted\n\n    while (left--)\n        data.push_back(uint8_t(0)); // data must to be multiple blocksize\n\n    auto mnem_encrypt = [&encry_output](aes_secret &sec, data_chunk &data) {\n        uint64_t start = 0, i = 0;\n        aes_block block;\n        while (start < data.size())\n        {\n            for (i = 0; i < aes256_block_size; i++)\n                block[i] = static_cast<uint8_t>(*(data.begin() + start + i));\n\n            aes256_encrypt(sec, block);\n\n            for (auto x : block)\n                encry_output.push_back(static_cast<char>(x));\n\n            start += aes256_block_size;\n        }\n    };\n    mnem_encrypt(sec, data);\n}\n\n/* decrypt string */\nvoid aes256_common_decrypt(const data_chunk &mnemonic, data_chunk &passphrase, data_chunk &decry_output)\n{\n    aes_secret sec = sha256_hash(ripemd160_hash(passphrase));\n\n    decry_output.clear();\n\n    uint8_t left = static_cast<uint8_t>(*mnemonic.begin());\n\n    auto mnem_decrypt = [&decry_output](aes_secret &sec, const data_chunk &data) {\n        uint32_t start = 1, i = 0; // escape first byte\n        aes_block block;\n        while (start < data.size())\n        {\n            for (i = 0; i < aes256_block_size; i++)\n                block[i] = static_cast<uint8_t>(*(data.begin() + start + i));\n\n            aes256_decrypt(sec, block);\n\n            for (auto x : block)\n                decry_output.push_back(static_cast<char>(x));\n\n            start += aes256_block_size;\n        }\n    };\n    mnem_decrypt(sec, mnemonic);\n    while (left--)\n        decry_output.pop_back(); // remove left bytes\n}\n\n/* encrypt string with extra 0 value */\nvoid encrypt_string(const std::string &mnemonic, std::string &passphrase, std::string &encry_output)\n{\n    data_chunk pass_chunk(passphrase.begin(), passphrase.end());\n    aes_secret sec = sha256_hash(ripemd160_hash(pass_chunk));\n\n    encry_output.clear();\n\n    std::string data = mnemonic;\n    uint32_t start = 0, left = aes256_block_size - (data.size() % aes256_block_size);\n\n    encry_output.push_back(static_cast<char>(left)); // bytes counts which not be encrypted\n\n    while (left--)\n        data.push_back(uint8_t(0)); // data must to be multiple blocksize\n\n    auto mnem_encrypt = [&encry_output](aes_secret &sec, std::string &data) {\n        uint32_t start = 0, i = 0;\n        aes_block block;\n        while (start < data.size())\n        {\n            for (i = 0; i < aes256_block_size; i++)\n                block[i] = static_cast<uint8_t>(*(data.begin() + start + i));\n\n            aes256_encrypt(sec, block);\n\n            for (auto x : block)\n                encry_output.push_back(static_cast<char>(x));\n\n            start += aes256_block_size;\n        }\n    };\n    mnem_encrypt(sec, data);\n}\n\n/* decrypt string */\nvoid decrypt_string(const std::string &mnemonic, std::string &passphrase, std::string &decry_output)\n{\n    data_chunk pass_chunk(passphrase.begin(), passphrase.end());\n    aes_secret sec = sha256_hash(ripemd160_hash(pass_chunk));\n\n    decry_output.clear();\n\n    uint8_t left = static_cast<uint8_t>(*mnemonic.begin());\n\n    auto mnem_decrypt = [&decry_output](aes_secret &sec, const std::string &data) {\n        uint32_t start = 1, i = 0; // escape first byte\n        aes_block block;\n        while (start < data.size())\n        {\n            for (i = 0; i < aes256_block_size; i++)\n                block[i] = static_cast<uint8_t>(*(data.begin() + start + i));\n\n            aes256_decrypt(sec, block);\n\n            for (auto x : block)\n                decry_output.push_back(static_cast<char>(x));\n\n            start += aes256_block_size;\n        }\n    };\n    mnem_decrypt(sec, mnemonic);\n    decry_output = decry_output.substr(0, decry_output.size() - left); // remove left bytes\n}\n\n#ifdef WITH_ICU\n\n// create_token\n// ----------------------------------------------------------------------------\n\n// This call requires an ICU build, the other excluded calls are dependencies.\nstatic data_chunk normal(const std::string &passphrase)\n{\n    return to_chunk(to_normal_nfc_form(passphrase));\n}\n\nstatic bool create_token(encrypted_token &out_token,\n                         const std::string &passphrase, data_slice owner_salt,\n                         const ek_entropy &owner_entropy,\n                         const byte_array<parse_encrypted_token::prefix_size> &prefix)\n{\n    BITCOIN_ASSERT(owner_salt.size() == ek_salt_size ||\n                   owner_salt.size() == ek_entropy_size);\n\n    const auto lot_sequence = owner_salt.size() == ek_salt_size;\n    auto factor = scrypt_token(normal(passphrase), owner_salt);\n\n    if (lot_sequence)\n        factor = bitcoin_hash(splice(factor, owner_entropy));\n\n    ec_compressed point;\n    if (!secret_to_public(point, factor))\n        return false;\n\n    return build_checked_array(out_token,\n                               {prefix,\n                                owner_entropy,\n                                point});\n}\n\n// The salt here is owner-supplied random bits, not the address hash.\nbool create_token(encrypted_token &out_token, const std::string &passphrase,\n                  const ek_entropy &entropy)\n{\n    // BIP38: If lot and sequence numbers are not being included, then\n    // owner_salt is 8 random bytes instead of 4, lot_sequence is omitted and\n    // owner_entropy becomes an alias for owner_salt.\n    const auto prefix = parse_encrypted_token::prefix_factory(false);\n    return create_token(out_token, passphrase, entropy, entropy, prefix);\n}\n\n// The salt here is owner-supplied random bits, not the address hash.\nbool create_token(encrypted_token &out_token, const std::string &passphrase,\n                  const ek_salt &salt, uint32_t lot, uint32_t sequence)\n{\n    if (lot > ek_max_lot || sequence > ek_max_sequence)\n        return false;\n\n    static constexpr size_t max_sequence_bits = 12;\n    const uint32_t lot_sequence = (lot << max_sequence_bits) || sequence;\n    const auto entropy = splice(salt, to_big_endian(lot_sequence));\n    const auto prefix = parse_encrypted_token::prefix_factory(true);\n    create_token(out_token, passphrase, salt, entropy, prefix);\n    return true;\n}\n\n// encrypt\n// ----------------------------------------------------------------------------\n\nbool encrypt(encrypted_private &out_private, const ec_secret &secret,\n             const std::string &passphrase, uint8_t version, bool compressed)\n{\n    ek_salt salt;\n    if (!address_salt(salt, secret, version, compressed))\n        return false;\n\n    const auto derived = split(scrypt_private(normal(passphrase), salt));\n    const auto prefix = parse_encrypted_private::prefix_factory(version,\n                                                                false);\n\n    auto encrypted1 = xor_data<half>(secret, derived.left);\n    aes256_encrypt(derived.right, encrypted1);\n\n    auto encrypted2 = xor_data<half>(secret, derived.left, half);\n    aes256_encrypt(derived.right, encrypted2);\n\n    return build_checked_array(out_private,\n                               {prefix,\n                                set_flags(compressed),\n                                salt,\n                                encrypted1,\n                                encrypted2});\n}\n\n// decrypt private_key\n// ----------------------------------------------------------------------------\n\nstatic bool decrypt_multiplied(ec_secret &out_secret,\n                               const parse_encrypted_private &parse, const std::string &passphrase)\n{\n    auto secret = scrypt_token(normal(passphrase), parse.owner_salt());\n\n    if (parse.lot_sequence())\n        secret = bitcoin_hash(splice(secret, parse.entropy()));\n\n    ec_compressed point;\n    if (!secret_to_public(point, secret))\n        return false;\n\n    const auto salt_entropy = splice(parse.salt(), parse.entropy());\n    const auto derived = split(scrypt_pair(point, salt_entropy));\n\n    auto encrypt1 = parse.data1();\n    auto encrypt2 = parse.data2();\n\n    aes256_decrypt(derived.right, encrypt2);\n    const auto decrypt2 = xor_data<half>(encrypt2, derived.left, 0, half);\n    auto part = split(decrypt2);\n    auto extended = splice(encrypt1, part.left);\n\n    aes256_decrypt(derived.right, extended);\n    const auto decrypt1 = xor_data<half>(extended, derived.left);\n    const auto factor = bitcoin_hash(splice(decrypt1, part.right));\n    if (!ec_multiply(secret, factor))\n        return false;\n\n    const auto compressed = parse.compressed();\n    const auto address_version = parse.address_version();\n    if (!address_validate(parse.salt(), secret, address_version, compressed))\n        return false;\n\n    out_secret = secret;\n    return true;\n}\n\nstatic bool decrypt_secret(ec_secret &out_secret,\n                           const parse_encrypted_private &parse, const std::string &passphrase)\n{\n    auto encrypt1 = splice(parse.entropy(), parse.data1());\n    auto encrypt2 = parse.data2();\n    const auto derived = split(scrypt_private(normal(passphrase),\n                                              parse.salt()));\n\n    aes256_decrypt(derived.right, encrypt1);\n    aes256_decrypt(derived.right, encrypt2);\n\n    const auto encrypted = splice(encrypt1, encrypt2);\n    const auto secret = xor_data<hash_size>(encrypted, derived.left);\n\n    const auto compressed = parse.compressed();\n    const auto address_version = parse.address_version();\n    if (!address_validate(parse.salt(), secret, address_version, compressed))\n        return false;\n\n    out_secret = secret;\n    return true;\n}\n\nbool decrypt(ec_secret &out_secret, uint8_t &out_version, bool &out_compressed,\n             const encrypted_private &key, const std::string &passphrase)\n{\n    const parse_encrypted_private parse(key);\n    if (!parse.valid())\n        return false;\n\n    const auto success = parse.multiplied() ? decrypt_multiplied(out_secret, parse, passphrase) : decrypt_secret(out_secret, parse, passphrase);\n\n    if (success)\n    {\n        out_compressed = parse.compressed();\n        out_version = parse.address_version();\n    }\n\n    return success;\n}\n\n// decrypt public_key\n// ----------------------------------------------------------------------------\n\nbool decrypt(ec_compressed &out_point, uint8_t &out_version,\n             bool &out_compressed, const encrypted_public &key,\n             const std::string &passphrase)\n{\n    const parse_encrypted_public parse(key);\n    if (!parse.valid())\n        return false;\n\n    const auto version = parse.address_version();\n    const auto lot_sequence = parse.lot_sequence();\n    auto factor = scrypt_token(normal(passphrase), parse.owner_salt());\n\n    if (lot_sequence)\n        factor = bitcoin_hash(splice(factor, parse.entropy()));\n\n    ec_compressed point;\n    if (!secret_to_public(point, factor))\n        return false;\n\n    const auto salt_entropy = splice(parse.salt(), parse.entropy());\n    auto derived = split(scrypt_pair(point, salt_entropy));\n    auto encrypt = split(parse.data());\n\n    aes256_decrypt(derived.right, encrypt.left);\n    const auto decrypt1 = xor_data<half>(encrypt.left, derived.left);\n\n    aes256_decrypt(derived.right, encrypt.right);\n    const auto decrypt2 = xor_data<half>(encrypt.right, derived.left, 0, half);\n\n    const auto sign_byte = point_sign(parse.sign(), derived.right);\n    auto product = splice(sign_byte, decrypt1, decrypt2);\n    if (!ec_multiply(product, factor))\n        return false;\n\n    if (!address_validate(parse.salt(), product, version, parse.compressed()))\n        return false;\n\n    out_point = product;\n    out_version = version;\n    out_compressed = parse.compressed();\n    return true;\n}\n\n#endif // WITH_ICU\n\n} // namespace wallet\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/wallet/hd_private.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/wallet/hd_private.hpp>\n\n#include <cstdint>\n#include <string>\n#include <boost/program_options.hpp>\n#include <UChain/coin/constants.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/formats/base_58.hpp>\n#include <UChain/coin/math/checksum.hpp>\n#include <UChain/coin/math/elliptic_curve.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/deserializer.hpp>\n#include <UChain/coin/utility/endian.hpp>\n#include <UChain/coin/utility/serializer.hpp>\n#include <UChain/coin/wallet/ec_private.hpp>\n#include <UChain/coin/wallet/ec_public.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\nconst uint64_t hd_private::mainnet = to_prefixes(76066276,\n                                                 hd_public::mainnet);\n\nhd_private::hd_private()\n    : hd_public(), secret_(null_hash)\n{\n}\n\nhd_private::hd_private(const hd_private &other)\n    : hd_public(other), secret_(other.secret_)\n{\n}\n\nhd_private::hd_private(const data_chunk &seed, uint64_t prefixes)\n    : hd_private(from_seed(seed, prefixes))\n{\n}\n\n// This reads the private version and sets the public to mainnet.\nhd_private::hd_private(const hd_key &private_key)\n    : hd_private(from_key(private_key, hd_public::mainnet))\n{\n}\n\n// This reads the private version and sets the public to mainnet.\nhd_private::hd_private(const std::string &encoded)\n    : hd_private(from_string(encoded, hd_public::mainnet))\n{\n}\n\n// This reads the private version and sets the public.\nhd_private::hd_private(const hd_key &private_key, uint32_t prefix)\n    : hd_private(from_key(private_key, prefix))\n{\n}\n\n// This validates the private version and sets the public.\nhd_private::hd_private(const hd_key &private_key, uint64_t prefixes)\n    : hd_private(from_key(private_key, prefixes))\n{\n}\n\n// This reads the private version and sets the public.\nhd_private::hd_private(const std::string &encoded, uint32_t prefix)\n    : hd_private(from_string(encoded, prefix))\n{\n}\n\n// This validates the private version and sets the public.\nhd_private::hd_private(const std::string &encoded, uint64_t prefixes)\n    : hd_private(from_string(encoded, prefixes))\n{\n}\n\nhd_private::hd_private(const ec_secret &secret,\n                       const hd_chain_code &chain_code, const hd_lineage &lineage)\n    : hd_public(from_secret(secret, chain_code, lineage)),\n      secret_(secret)\n{\n}\n\n// Factories.\n// ----------------------------------------------------------------------------\n\nhd_private hd_private::from_seed(data_slice seed, uint64_t prefixes)\n{\n    // This is a magic constant from BIP32.\n    static const data_chunk magic(to_chunk(\"Bitcoin seed\"));\n\n    const auto intermediate = split(hmac_sha512_hash(seed, magic));\n\n    // The key is invalid if parse256(IL) >= n or 0:\n    if (!verify(intermediate.left))\n        return hd_private();\n\n    const auto master = hd_lineage{\n        prefixes,\n        0x00,\n        0x00000000,\n        0x00000000};\n\n    return hd_private(intermediate.left, intermediate.right, master);\n}\n\nhd_private hd_private::from_key(const hd_key &key, uint32_t public_prefix)\n{\n    const auto prefix = from_big_endian_unsafe<uint32_t>(key.begin());\n    return from_key(key, to_prefixes(prefix, public_prefix));\n}\n\nhd_private hd_private::from_key(const hd_key &key, uint64_t prefixes)\n{\n    // TODO: convert to istream_reader\n    auto stream = make_deserializer(key.begin(), key.end());\n    const auto prefix = stream.read_big_endian<uint32_t>();\n    const auto depth = stream.read_big_endian<uint8_t>();\n    const auto parent = stream.read_big_endian<uint32_t>();\n    const auto child = stream.read_big_endian<uint32_t>();\n    const auto chain = stream.read_bytes<hd_chain_code_size>();\n    /*const auto padding =*/stream.read_big_endian<uint8_t>();\n    const auto secret = stream.read_bytes<ec_secret_size>();\n\n    // Validate the prefix against the provided value.\n    if (prefix != to_prefix(prefixes))\n        return hd_private();\n\n    const hd_lineage lineage{\n        prefixes,\n        depth,\n        parent,\n        child};\n\n    return hd_private(secret, chain, lineage);\n}\n\nhd_private hd_private::from_string(const std::string &encoded,\n                                   uint32_t public_prefix)\n{\n    hd_key key;\n    if (!decode_base58(key, encoded))\n        return hd_private();\n\n    return hd_private(from_key(key, public_prefix));\n}\n\nhd_private hd_private::from_string(const std::string &encoded,\n                                   uint64_t prefixes)\n{\n    hd_key key;\n    return decode_base58(key, encoded) ? hd_private(key, prefixes) : hd_private();\n}\n\n// Cast operators.\n// ----------------------------------------------------------------------------\n\nhd_private::operator const ec_secret &() const\n{\n    return secret_;\n}\n\n// Serializer.\n// ----------------------------------------------------------------------------\n\nstd::string hd_private::encoded() const\n{\n    return encode_base58(to_hd_key());\n}\n\n/// Accessors.\n// ----------------------------------------------------------------------------\n\nconst ec_secret &hd_private::secret() const\n{\n    return secret_;\n}\n\n// Methods.\n// ----------------------------------------------------------------------------\n\n// HD keys do not carry a payment address prefix (just like WIF).\n// So we are currently not converting to ec_public or ec_private.\n\nhd_key hd_private::to_hd_key() const\n{\n    static constexpr uint8_t private_key_padding = 0x00;\n\n    hd_key out;\n    build_checked_array(out,\n                        {to_big_endian(to_prefix(lineage_.prefixes)),\n                         to_array(lineage_.depth),\n                         to_big_endian(lineage_.parent_fingerprint),\n                         to_big_endian(lineage_.child_number),\n                         chain_,\n                         to_array(private_key_padding),\n                         secret_});\n\n    return out;\n}\n\nhd_public hd_private::to_public() const\n{\n    return hd_public(((hd_public) * this).to_hd_key(),\n                     hd_public::to_prefix(lineage_.prefixes));\n}\n\nhd_private hd_private::derive_private(uint32_t index) const\n{\n    constexpr uint8_t depth = 0;\n\n    const auto data = (index >= hd_first_hardened_key) ? splice(to_array(depth), secret_, to_big_endian(index)) : splice(point_, to_big_endian(index));\n\n    const auto intermediate = split(hmac_sha512_hash(data, chain_));\n\n    // The child key ki is (parse256(IL) + kpar) mod n:\n    auto child = secret_;\n    if (!ec_add(child, intermediate.left))\n        return hd_private();\n\n    if (lineage_.depth == max_uint8)\n        return hd_private();\n\n    const hd_lineage lineage{\n        lineage_.prefixes,\n        static_cast<uint8_t>(lineage_.depth + 1),\n        fingerprint(),\n        index};\n\n    return hd_private(child, intermediate.right, lineage);\n}\n\nhd_public hd_private::derive_public(uint32_t index) const\n{\n    return derive_private(index).to_public();\n}\n\n// Operators.\n// ----------------------------------------------------------------------------\n\nhd_private &hd_private::operator=(const hd_private &other)\n{\n    secret_ = other.secret_;\n    valid_ = other.valid_;\n    chain_ = other.chain_;\n    lineage_ = other.lineage_;\n    point_ = other.point_;\n    return *this;\n}\n\nbool hd_private::operator<(const hd_private &other) const\n{\n    return encoded() < other.encoded();\n}\n\nbool hd_private::operator==(const hd_private &other) const\n{\n    return secret_ == other.secret_ && valid_ == other.valid_ &&\n           chain_ == other.chain_ && lineage_ == other.lineage_ &&\n           point_ == other.point_;\n}\n\nbool hd_private::operator!=(const hd_private &other) const\n{\n    return !(*this == other);\n}\n\n// We must assume mainnet for public version here.\n// When converting this to public a clone of this key should be used, with the\n// public version specified - after validating the private version.\nstd::istream &operator>>(std::istream &in, hd_private &to)\n{\n    std::string value;\n    in >> value;\n    to = hd_private(value, hd_public::mainnet);\n\n    if (!to)\n    {\n        using namespace boost::program_options;\n        BOOST_THROW_EXCEPTION(invalid_option_value(value));\n    }\n\n    return in;\n}\n\nstd::ostream &operator<<(std::ostream &out, const hd_private &of)\n{\n    out << of.encoded();\n    return out;\n}\n\n} // namespace wallet\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/wallet/hd_public.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/wallet/hd_public.hpp>\n\n#include <cstdint>\n#include <string>\n#include <boost/program_options.hpp>\n#include <UChain/coin/constants.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/formats/base_58.hpp>\n#include <UChain/coin/math/checksum.hpp>\n#include <UChain/coin/math/elliptic_curve.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/deserializer.hpp>\n#include <UChain/coin/utility/endian.hpp>\n#include <UChain/coin/utility/serializer.hpp>\n#include <UChain/coin/wallet/ec_public.hpp>\n#include <UChain/coin/wallet/hd_private.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\nconst uint32_t hd_public::mainnet = 76067358;\n\n// hd_public\n// ----------------------------------------------------------------------------\n\nhd_public::hd_public()\n    : valid_(false), chain_(null_hash), lineage_({0, 0, 0, 0}),\n      point_(null_compressed_point)\n{\n}\n\nhd_public::hd_public(const hd_public &other)\n    : valid_(other.valid_), chain_(other.chain_), lineage_(other.lineage_),\n      point_(other.point_)\n{\n}\n\n// This cannot validate the version.\nhd_public::hd_public(const hd_key &public_key)\n    : hd_public(from_key(public_key))\n{\n}\n\n// This cannot validate the version.\nhd_public::hd_public(const std::string &encoded)\n    : hd_public(from_string(encoded))\n{\n}\n\n// This validates the version.\nhd_public::hd_public(const hd_key &public_key, uint32_t prefix)\n    : hd_public(from_key(public_key, prefix))\n{\n}\n\n// This validates the version.\nhd_public::hd_public(const std::string &encoded, uint32_t prefix)\n    : hd_public(from_string(encoded, prefix))\n{\n}\n\nhd_public::hd_public(const ec_compressed &point,\n                     const hd_chain_code &chain_code, const hd_lineage &lineage)\n    : valid_(true), point_(point), chain_(chain_code), lineage_(lineage)\n{\n}\n\n// Factories.\n// ----------------------------------------------------------------------------\n\nhd_public hd_public::from_secret(const ec_secret &secret,\n                                 const hd_chain_code &chain_code, const hd_lineage &lineage)\n{\n    ec_compressed point;\n    return secret_to_public(point, secret) ? hd_public(point, chain_code, lineage) : hd_public();\n}\n\nhd_public hd_public::from_key(const hd_key &key)\n{\n    const auto prefix = from_big_endian_unsafe<uint32_t>(key.begin());\n    return from_key(key, prefix);\n}\n\nhd_public hd_public::from_string(const std::string &encoded)\n{\n    hd_key key;\n    if (!decode_base58(key, encoded))\n        return hd_public();\n\n    return hd_public(from_key(key));\n}\n\nhd_public hd_public::from_key(const hd_key &key, uint32_t prefix)\n{\n    // TODO: convert to istream_reader\n    auto stream = make_deserializer(key.begin(), key.end());\n    const auto actual_prefix = stream.read_big_endian<uint32_t>();\n    const auto depth = stream.read_big_endian<uint8_t>();\n    const auto parent = stream.read_big_endian<uint32_t>();\n    const auto child = stream.read_big_endian<uint32_t>();\n    const auto chain = stream.read_bytes<hd_chain_code_size>();\n    const auto compressed = stream.read_bytes<ec_compressed_size>();\n    //    const auto point = to_array<ec_compressed_size>(compressed);\n\n    // Validate the prefix against the provided value.\n    if (actual_prefix != prefix)\n        return hd_public();\n\n    // The private prefix will be zero'd here, but there's no way to access it.\n    const hd_lineage lineage{\n        prefix,\n        depth,\n        parent,\n        child};\n\n    return hd_public(compressed, chain, lineage);\n}\n\nhd_public hd_public::from_string(const std::string &encoded,\n                                 uint32_t prefix)\n{\n    hd_key key;\n    if (!decode_base58(key, encoded))\n        return hd_public();\n\n    return hd_public(from_key(key, prefix));\n}\n\n// Cast operators.\n// ----------------------------------------------------------------------------\n\nhd_public::operator const bool() const\n{\n    return valid_;\n}\n\nhd_public::operator const ec_compressed &() const\n{\n    return point_;\n}\n\n// Serializer.\n// ----------------------------------------------------------------------------\n\nstd::string hd_public::encoded() const\n{\n    return encode_base58(to_hd_key());\n}\n\n// Accessors.\n// ----------------------------------------------------------------------------\n\nconst hd_chain_code &hd_public::chain_code() const\n{\n    return chain_;\n}\n\nconst hd_lineage &hd_public::lineage() const\n{\n    return lineage_;\n}\n\nconst ec_compressed &hd_public::point() const\n{\n    return point_;\n}\n\n// Methods.\n// ----------------------------------------------------------------------------\n\n// HD keys do not carry a payment address prefix (just like WIF).\n// So we are currently not converting to ec_public or ec_private.\n\nhd_key hd_public::to_hd_key() const\n{\n    hd_key out;\n    build_checked_array(out,\n                        {to_big_endian(to_prefix(lineage_.prefixes)),\n                         to_array(lineage_.depth),\n                         to_big_endian(lineage_.parent_fingerprint),\n                         to_big_endian(lineage_.child_number),\n                         chain_,\n                         point_});\n\n    return out;\n}\n\nhd_public hd_public::derive_public(uint32_t index) const\n{\n    if (index >= hd_first_hardened_key)\n        return hd_public();\n\n    const auto data = splice(point_, to_big_endian(index));\n    const auto intermediate = split(hmac_sha512_hash(data, chain_));\n\n    // The returned child key Ki is point(parse256(IL)) + Kpar.\n    auto combined = point_;\n    if (!ec_add(combined, intermediate.left))\n        return hd_public();\n\n    if (lineage_.depth == max_uint8)\n        return hd_public();\n\n    const hd_lineage lineage{\n        lineage_.prefixes,\n        static_cast<uint8_t>(lineage_.depth + 1),\n        fingerprint(),\n        index};\n\n    return hd_public(combined, intermediate.right, lineage);\n}\n\n// Helpers.\n// ----------------------------------------------------------------------------\n\nuint32_t hd_public::fingerprint() const\n{\n    const auto message_digest = bitcoin_short_hash(point_);\n    return from_big_endian_unsafe<uint32_t>(message_digest.begin());\n}\n\n// Operators.\n// ----------------------------------------------------------------------------\n\nhd_public &hd_public::operator=(const hd_public &other)\n{\n    valid_ = other.valid_;\n    chain_ = other.chain_;\n    lineage_ = other.lineage_;\n    point_ = other.point_;\n    return *this;\n}\n\nbool hd_public::operator<(const hd_public &other) const\n{\n    return encoded() < other.encoded();\n}\n\nbool hd_public::operator==(const hd_public &other) const\n{\n    return valid_ == other.valid_ && chain_ == other.chain_ &&\n           lineage_ == other.lineage_ && point_ == other.point_;\n}\n\nbool hd_public::operator!=(const hd_public &other) const\n{\n    return !(*this == other);\n}\n\nstd::istream &operator>>(std::istream &in, hd_public &to)\n{\n    std::string value;\n    in >> value;\n    to = hd_public(value);\n\n    if (!to)\n    {\n        using namespace boost::program_options;\n        BOOST_THROW_EXCEPTION(invalid_option_value(value));\n    }\n\n    return in;\n}\n\nstd::ostream &operator<<(std::ostream &out, const hd_public &of)\n{\n    out << of.encoded();\n    return out;\n}\n\n// hd_lineage\n// ----------------------------------------------------------------------------\n\nbool hd_lineage::operator==(const hd_lineage &other) const\n{\n    return prefixes == other.prefixes && depth == other.depth &&\n           parent_fingerprint == other.parent_fingerprint &&\n           child_number == other.child_number;\n}\n\nbool hd_lineage::operator!=(const hd_lineage &other) const\n{\n    return !(*this == other);\n}\n\n} // namespace wallet\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/wallet/mini_keys.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/wallet/mini_keys.hpp>\n\n#include <cstdint>\n#include <string>\n#include <UChain/coin/math/elliptic_curve.hpp>\n#include <UChain/coin/math/hash.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\nbool check_minikey(const std::string &minikey)\n{\n    // Legacy minikeys are 22 chars long\n    bool valid = minikey.size() == 22 || minikey.size() == 30;\n    return valid && sha256_hash(to_chunk(minikey + \"?\"))[0] == 0x00;\n}\n\nbool minikey_to_secret(ec_secret &out_secret, const std::string &key)\n{\n    if (!check_minikey(key))\n        return false;\n\n    out_secret = sha256_hash(to_chunk(key));\n    return true;\n}\n\n} // namespace wallet\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/wallet/mnemonic.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/wallet/mnemonic.hpp>\n\n#include <algorithm>\n#include <cstdint>\n#include <boost/locale.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/unicode/unicode.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/binary.hpp>\n#include <UChain/coin/utility/collection.hpp>\n#include <UChain/coin/utility/string.hpp>\n#include <UChain/coin/wallet/dictionary.hpp>\n#include \"../math/external/pkcs5_pbkdf2.h\"\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\n// BIP-39 private constants.\nstatic constexpr size_t bits_per_word = 11;\nstatic constexpr size_t entropy_bit_divisor = 32;\nstatic constexpr size_t hmac_iterations = 2048;\nstatic const char *passphrase_prefix = \"mnemonic\";\n\ninline uint8_t bip39_shift(size_t bit)\n{\n    return (1 << (byte_bits - (bit % byte_bits) - 1));\n}\n\nbool validate_mnemonic(const word_list &words, const dictionary &lexicon)\n{\n    const auto word_count = words.size();\n    if ((word_count % mnemonic_word_multiple) != 0)\n        return false;\n\n    const auto total_bits = bits_per_word * word_count;\n    const auto check_bits = total_bits / (entropy_bit_divisor + 1);\n    const auto entropy_bits = total_bits - check_bits;\n\n    BITCOIN_ASSERT((entropy_bits % byte_bits) == 0);\n\n    size_t bit = 0;\n    data_chunk data((total_bits + byte_bits - 1) / byte_bits, 0);\n\n    for (const auto &word : words)\n    {\n        const auto position = find_position(lexicon, word);\n        if (position == -1)\n            return false;\n\n        for (size_t loop = 0; loop < bits_per_word; loop++, bit++)\n        {\n            if (position & (1 << (bits_per_word - loop - 1)))\n            {\n                const auto byte = bit / byte_bits;\n                data[byte] |= bip39_shift(bit);\n            }\n        }\n    }\n\n    data.resize(entropy_bits / byte_bits);\n\n    const auto mnemonic = create_mnemonic(data, lexicon);\n    return std::equal(mnemonic.begin(), mnemonic.end(), words.begin());\n}\n\nword_list create_mnemonic(data_slice entropy, const dictionary &lexicon)\n{\n    if ((entropy.size() % mnemonic_seed_multiple) != 0)\n        return word_list();\n\n    const size_t entropy_bits = (entropy.size() * byte_bits);\n    const size_t check_bits = (entropy_bits / entropy_bit_divisor);\n    const size_t total_bits = (entropy_bits + check_bits);\n    const size_t word_count = (total_bits / bits_per_word);\n\n    BITCOIN_ASSERT((total_bits % bits_per_word) == 0);\n    BITCOIN_ASSERT((word_count % mnemonic_word_multiple) == 0);\n\n    const auto data = build_chunk({entropy, sha256_hash(entropy)});\n\n    size_t bit = 0;\n    word_list words;\n\n    for (size_t word = 0; word < word_count; word++)\n    {\n        size_t position = 0;\n        for (size_t loop = 0; loop < bits_per_word; loop++)\n        {\n            bit = (word * bits_per_word + loop);\n            position <<= 1;\n\n            const auto byte = bit / byte_bits;\n\n            if ((data[byte] & bip39_shift(bit)) > 0)\n                position++;\n        }\n\n        BITCOIN_ASSERT(position < dictionary_size);\n        words.push_back(lexicon[position]);\n    }\n\n    BITCOIN_ASSERT(words.size() == ((bit + 1) / bits_per_word));\n    return words;\n}\n\nbool validate_mnemonic(const word_list &mnemonic,\n                       const dictionary_list &lexicons)\n{\n    for (const auto &lexicon : lexicons)\n        if (validate_mnemonic(mnemonic, *lexicon))\n            return true;\n\n    return false;\n}\n\nlong_hash decode_mnemonic(const word_list &mnemonic)\n{\n    const auto sentence = join(mnemonic);\n    const std::string salt(passphrase_prefix);\n    return pkcs5_pbkdf2_hmac_sha512(to_chunk(sentence),\n                                    to_chunk(salt), hmac_iterations);\n}\n\n#ifdef WITH_ICU\n\nlong_hash decode_mnemonic(const word_list &mnemonic,\n                          const std::string &passphrase)\n{\n    const auto sentence = join(mnemonic);\n    const std::string prefix(passphrase_prefix);\n    const auto salt = to_normal_nfkd_form(prefix + passphrase);\n    return pkcs5_pbkdf2_hmac_sha512(to_chunk(sentence),\n                                    to_chunk(salt), hmac_iterations);\n}\n\n#endif\n\n} // namespace wallet\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/wallet/parse_encrypted_keys/parse_encrypted_key.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_PARSE_ENCRYPTED_KEY_HPP\n#define UC_PARSE_ENCRYPTED_KEY_HPP\n\n#include <cstdint>\n#include <cstddef>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/wallet/encrypted_keys.hpp>\n#include \"parse_encrypted_prefix.hpp\"\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\ntemplate <size_t PrefixSize>\nclass parse_encrypted_key\n    : public parse_encrypted_prefix<PrefixSize>\n{\n  public:\n    parse_encrypted_key(const byte_array<PrefixSize> &prefix,\n                        const one_byte &flags, const ek_salt &salt, const ek_entropy &entropy);\n\n    bool compressed() const;\n    bool lot_sequence() const;\n    data_chunk owner_salt() const;\n\n    uint8_t flags() const;\n    ek_salt salt() const;\n    ek_entropy entropy() const;\n\n  private:\n    const one_byte flags_;\n    const ek_salt salt_;\n    const ek_entropy entropy_;\n};\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#include \"parse_encrypted_key.ipp\"\n\n#endif\n"
  },
  {
    "path": "src/UChain/coin/wallet/parse_encrypted_keys/parse_encrypted_key.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_PARSE_ENCRYPTED_KEY_IPP\n#define UC_PARSE_ENCRYPTED_KEY_IPP\n\n#include <cstdint>\n#include <cstddef>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/wallet/encrypted_keys.hpp>\n#include \"parse_encrypted_prefix.hpp\"\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\ntemplate <size_t PrefixSize>\nparse_encrypted_key<PrefixSize>::parse_encrypted_key(\n    const byte_array<PrefixSize> &prefix, const one_byte &flags,\n    const ek_salt &salt, const ek_entropy &entropy)\n    : parse_encrypted_prefix<PrefixSize>(prefix),\n      flags_(flags), salt_(salt), entropy_(entropy)\n{\n}\n\ntemplate <size_t PrefixSize>\nbool parse_encrypted_key<PrefixSize>::compressed() const\n{\n    return (flags() & ek_flag::ec_compressed_key) != 0;\n}\n\ntemplate <size_t PrefixSize>\nek_entropy parse_encrypted_key<PrefixSize>::entropy() const\n{\n    // The owner salt + lot-sequence or owner entropy.\n    return entropy_;\n}\n\ntemplate <size_t PrefixSize>\nuint8_t parse_encrypted_key<PrefixSize>::flags() const\n{\n    return flags_.front();\n}\n\ntemplate <size_t PrefixSize>\nbool parse_encrypted_key<PrefixSize>::lot_sequence() const\n{\n    return (flags() & ek_flag::lot_sequence_key) != 0;\n}\n\ntemplate <size_t PrefixSize>\ndata_chunk parse_encrypted_key<PrefixSize>::owner_salt() const\n{\n    // Either 4 or 8 bytes, depending on the lot sequence flags.\n    if (lot_sequence())\n        return to_chunk(slice<0, ek_salt_size>(entropy()));\n    else\n        return to_chunk(entropy());\n}\n\ntemplate <size_t PrefixSize>\nek_salt parse_encrypted_key<PrefixSize>::salt() const\n{\n    // The address hash salt.\n    return salt_;\n}\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "src/UChain/coin/wallet/parse_encrypted_keys/parse_encrypted_prefix.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_PARSE_ENCRYPTED_PREFIX_HPP\n#define UC_PARSE_ENCRYPTED_PREFIX_HPP\n\n#include <cstdint>\n#include <cstddef>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/wallet/encrypted_keys.hpp>\n\n// BIP38\n// Alt-chain implementers should exploit the address hash for [identification].\n// Since each operation in this proposal involves hashing a text representation\n// of a coin address which (for Bitcoin) includes the leading '1', an alt-chain\n// can easily be denoted simply by using the alt-chain's preferred format for\n// representing an address.... Alt-chain implementers may also change the prefix\n// such that encrypted addresses do not start with \"6P\".\n\nnamespace libbitcoin {\nnamespace wallet {\n\ntemplate<size_t Size>\nclass parse_encrypted_prefix\n{\npublic:\n    bool valid() const;\n\n    static constexpr uint8_t prefix_size = Size;\n\nprotected:\n    explicit parse_encrypted_prefix(const byte_array<Size>& value);\n\n    uint8_t context() const;\n    byte_array<Size> prefix() const;\n    void valid(bool value);\n\n    static constexpr uint8_t magic_size = Size - 1;\n\nprivate:\n    bool verify_magic() const;\n\n    const byte_array<Size> prefix_;\n    bool valid_;\n};\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#include \"parse_encrypted_prefix.ipp\"\n\n#endif\n"
  },
  {
    "path": "src/UChain/coin/wallet/parse_encrypted_keys/parse_encrypted_prefix.ipp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_PARSE_ENCRYPTED_PREFIX_IPP\n#define UC_PARSE_ENCRYPTED_PREFIX_IPP\n\n#include <cstdint>\n#include <cstddef>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/wallet/encrypted_keys.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\ntemplate <size_t Size>\nparse_encrypted_prefix<Size>::parse_encrypted_prefix(\n    const byte_array<Size> &value)\n    : prefix_(value), valid_(false)\n{\n}\n\ntemplate <size_t Size>\nuint8_t parse_encrypted_prefix<Size>::context() const\n{\n    return prefix_.back();\n}\n\ntemplate <size_t Size>\nbyte_array<Size> parse_encrypted_prefix<Size>::prefix() const\n{\n    return prefix_;\n}\n\ntemplate <size_t Size>\nbool parse_encrypted_prefix<Size>::valid() const\n{\n    return valid_;\n}\n\ntemplate <size_t Size>\nvoid parse_encrypted_prefix<Size>::valid(bool value)\n{\n    valid_ = value;\n}\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "src/UChain/coin/wallet/parse_encrypted_keys/parse_encrypted_private.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include \"parse_encrypted_private.hpp\"\n\n#include <cstdint>\n#include <cstddef>\n#include <UChain/coin/math/checksum.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/wallet/encrypted_keys.hpp>\n#include \"parse_encrypted_key.hpp\"\n#include \"parse_encrypted_prefix.hpp\"\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\nconst byte_array<parse_encrypted_private::magic_size>\n    parse_encrypted_private::magic_{\n        {0x01}};\n\nbyte_array<parse_encrypted_private::prefix_size>\nparse_encrypted_private::prefix_factory(uint8_t address, bool multiplied)\n{\n    const auto base = multiplied ? multiplied_context_ : default_context_;\n    const auto context = base + address;\n    return splice(magic_, to_array(context));\n}\n\nparse_encrypted_private::parse_encrypted_private(const encrypted_private &key)\n    : parse_encrypted_key<prefix_size>(\n          slice<0, 2>(key),\n          slice<2, 3>(key),\n          slice<3, 7>(key),\n          slice<7, 15>(key)),\n      data1_(slice<15, 23>(key)),\n      data2_(slice<23, 39>(key))\n{\n    valid(verify_magic() && verify_checksum(key));\n}\n\nuint8_t parse_encrypted_private::address_version() const\n{\n    const auto base = multiplied() ? multiplied_context_ : default_context_;\n    return context() - base;\n}\n\nquarter_hash parse_encrypted_private::data1() const\n{\n    return data1_;\n}\n\nhalf_hash parse_encrypted_private::data2() const\n{\n    return data2_;\n}\n\nbool parse_encrypted_private::multiplied() const\n{\n    // This is a double negative (multiplied = not not multiplied).\n    return (flags() & ek_flag::ec_non_multiplied) == 0;\n}\n\nbool parse_encrypted_private::verify_magic() const\n{\n    return slice<0, magic_size>(prefix()) == magic_;\n}\n\n} // namespace wallet\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/wallet/parse_encrypted_keys/parse_encrypted_private.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_PARSE_ENCRYPTED_PRIVATE_HPP\n#define UC_PARSE_ENCRYPTED_PRIVATE_HPP\n\n#include <cstdint>\n#include <cstddef>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include \"parse_encrypted_key.hpp\"\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\nclass parse_encrypted_private\n    : public parse_encrypted_key<2u>\n{\n  public:\n    static byte_array<prefix_size> prefix_factory(uint8_t address,\n                                                  bool multiplied);\n\n    explicit parse_encrypted_private(const encrypted_private &key);\n\n    bool multiplied() const;\n    uint8_t address_version() const;\n\n    quarter_hash data1() const;\n    half_hash data2() const;\n\n  private:\n    bool verify_magic() const;\n\n    static constexpr uint8_t default_context_ = 0x42;\n    static constexpr uint8_t multiplied_context_ = 0x43;\n    static const byte_array<magic_size> magic_;\n\n    const quarter_hash data1_;\n    const half_hash data2_;\n};\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "src/UChain/coin/wallet/parse_encrypted_keys/parse_encrypted_public.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include \"parse_encrypted_public.hpp\"\n\n#include <cstdint>\n#include <cstddef>\n#include <UChain/coin/math/checksum.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/wallet/encrypted_keys.hpp>\n#include \"parse_encrypted_key.hpp\"\n#include \"parse_encrypted_prefix.hpp\"\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\n// This prefix results in the prefix \"cfrm\" in the base58 encoding but is\n// modified when the payment address is Bitcoin mainnet (0).\nconst byte_array<parse_encrypted_public::magic_size>\n    parse_encrypted_public::magic_{\n        {0x64, 0x3b, 0xf6, 0xa8}};\n\nbyte_array<parse_encrypted_public::prefix_size>\nparse_encrypted_public::prefix_factory(uint8_t address)\n{\n    const auto context = default_context_ + address;\n    return splice(magic_, to_array(context));\n}\n\nparse_encrypted_public::parse_encrypted_public(const encrypted_public &key)\n    : parse_encrypted_key<prefix_size>(\n          slice<0, 5>(key),\n          slice<5, 6>(key),\n          slice<6, 10>(key),\n          slice<10, 18>(key)),\n      sign_(slice<18, 19>(key)),\n      data_(slice<19, 51>(key))\n{\n    valid(verify_magic() && verify_checksum(key));\n}\n\nuint8_t parse_encrypted_public::address_version() const\n{\n    return context() - default_context_;\n}\n\nhash_digest parse_encrypted_public::data() const\n{\n    return data_;\n}\n\none_byte parse_encrypted_public::sign() const\n{\n    return sign_;\n}\n\nbool parse_encrypted_public::verify_magic() const\n{\n    return slice<0, magic_size>(prefix()) == magic_;\n}\n\n} // namespace wallet\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/wallet/parse_encrypted_keys/parse_encrypted_public.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_PARSE_ENCRYPTED_PUBLIC_HPP\n#define UC_PARSE_ENCRYPTED_PUBLIC_HPP\n\n#include <cstdint>\n#include <cstddef>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include \"parse_encrypted_key.hpp\"\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\nclass parse_encrypted_public\n    : public parse_encrypted_key<5u>\n{\npublic:\n  static byte_array<prefix_size> prefix_factory(uint8_t address);\n\n  explicit parse_encrypted_public(const encrypted_public &key);\n\n  uint8_t address_version() const;\n\n  one_byte sign() const;\n  hash_digest data() const;\n\nprivate:\n  bool verify_magic() const;\n\n  static constexpr uint8_t default_context_ = 0x9a;\n  static const byte_array<magic_size> magic_;\n\n  const one_byte sign_;\n  const hash_digest data_;\n};\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "src/UChain/coin/wallet/parse_encrypted_keys/parse_encrypted_token.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include \"parse_encrypted_token.hpp\"\n\n#include <cstdint>\n#include <cstddef>\n#include <UChain/coin/math/checksum.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/wallet/encrypted_keys.hpp>\n#include \"parse_encrypted_prefix.hpp\"\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\n// This prefix results in the prefix \"passphrase\" in the base58 encoding.\n// The prefix is not modified as the result of variations to address.\nconst byte_array<parse_encrypted_token::magic_size> parse_encrypted_token::magic_{\n    {0x2c, 0xe9, 0xb3, 0xe1, 0xff, 0x39, 0xe2}};\n\nbyte_array<parse_encrypted_token::prefix_size>\nparse_encrypted_token::prefix_factory(bool lot_sequence)\n{\n    const auto context = lot_sequence ? lot_context_ : default_context_;\n    return splice(magic_, to_array(context));\n}\n\nparse_encrypted_token::parse_encrypted_token(const encrypted_token &value)\n    : parse_encrypted_prefix(slice<0, 8>(value)),\n      entropy_(slice<8, 16>(value)),\n      sign_(slice<16, 17>(value)),\n      data_(slice<17, 49>(value))\n{\n    valid(verify_magic() && verify_context() && verify_checksum(value));\n}\n\nhash_digest parse_encrypted_token::data() const\n{\n    return data_;\n}\n\nek_entropy parse_encrypted_token::entropy() const\n{\n    return entropy_;\n}\n\nbool parse_encrypted_token::lot_sequence() const\n{\n    // There is no \"flags\" byte in token, we rely on prefix context.\n    return context() == lot_context_;\n}\n\none_byte parse_encrypted_token::sign() const\n{\n    return sign_;\n}\n\nbool parse_encrypted_token::verify_context() const\n{\n    return context() == default_context_ || context() == lot_context_;\n}\n\nbool parse_encrypted_token::verify_magic() const\n{\n    return slice<0, magic_size>(prefix()) == magic_;\n}\n\n} // namespace wallet\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/wallet/parse_encrypted_keys/parse_encrypted_token.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_PARSE_ENCRYPTED_TOKEN_HPP\n#define UC_PARSE_ENCRYPTED_TOKEN_HPP\n\n#include <cstdint>\n#include <cstddef>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/wallet/encrypted_keys.hpp>\n#include \"parse_encrypted_key.hpp\"\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\nclass parse_encrypted_token\n    : public parse_encrypted_prefix<8u>\n{\npublic:\n  static byte_array<prefix_size> prefix_factory(bool lot_sequence);\n\n  explicit parse_encrypted_token(const encrypted_token &value);\n\n  bool lot_sequence() const;\n  hash_digest data() const;\n  ek_entropy entropy() const;\n  one_byte sign() const;\n\nprivate:\n  bool verify_context() const;\n  bool verify_magic() const;\n\n  static constexpr uint8_t lot_context_ = 0x51;\n  static constexpr uint8_t default_context_ = 0x53;\n  static const byte_array<magic_size> magic_;\n\n  const ek_entropy entropy_;\n  const one_byte sign_;\n  const hash_digest data_;\n};\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "src/UChain/coin/wallet/payment_address.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/wallet/payment_address.hpp>\n\n#include <algorithm>\n#include <cstdint>\n#include <string>\n#include <boost/program_options.hpp>\n#include <UChain/coin/formats/base_58.hpp>\n#include <UChain/coin/math/checksum.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/wallet/ec_private.hpp>\n#include <UChain/coin/wallet/ec_public.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\nuint8_t payment_address::mainnet_p2kh = 0x44;\nconst uint8_t payment_address::mainnet_p2sh = 0x05;\n\nconst std::string payment_address::blackhole_address = \"1111111111111111111114oLvT2\";\n\npayment_address::payment_address()\n    : valid_(false), version_(0), hash_(null_short_hash)\n{\n}\n\npayment_address::payment_address(const payment_address &other)\n    : valid_(other.valid_), version_(other.version_), hash_(other.hash_)\n{\n}\n\npayment_address::payment_address(const payment &decoded)\n    : payment_address(from_payment(decoded))\n{\n}\n\npayment_address::payment_address(const std::string &address)\n    : payment_address(from_string(address))\n{\n}\n\n// MSVC (CTP) casts this down to 8 bits if a variable is not used:\n// const payment_address address({ ec_secret, 0x806F });\n// Alternatively explicit construction of the ec_private also works.\n// const payment_address address(ec_private(ec_secret, 0x806F));\n// const payment_address address(ec_private{ ec_secret, 0x806F });\n// However this doesn't impact payment_address, since it only uses the LSB.\npayment_address::payment_address(const ec_private &secret)\n    : payment_address(from_private(secret))\n{\n}\n\npayment_address::payment_address(const ec_public &point, uint8_t version)\n    : payment_address(from_public(point, version))\n{\n}\n\npayment_address::payment_address(const chain::script &script, uint8_t version)\n    : payment_address(from_script(script, version))\n{\n}\n\npayment_address::payment_address(const short_hash &hash, uint8_t version)\n    : valid_(true), version_(version), hash_(hash)\n{\n}\n\n// Validators.\n// ----------------------------------------------------------------------------\n\nbool payment_address::is_address(data_slice decoded)\n{\n    return (decoded.size() == payment_size) && verify_checksum(decoded);\n}\n\n// Factories.\n// ----------------------------------------------------------------------------\n\npayment_address payment_address::from_string(const std::string &address)\n{\n    payment decoded;\n    if (!decode_base58(decoded, address) || !is_address(decoded))\n        return payment_address();\n\n    return payment_address(decoded);\n}\n\npayment_address payment_address::from_payment(const payment &decoded)\n{\n    if (!is_address(decoded))\n        return payment_address();\n\n    const auto hash = slice<1, short_hash_size + 1>(decoded);\n    return payment_address(hash, decoded.front());\n}\n\npayment_address payment_address::from_private(const ec_private &secret)\n{\n    if (!secret)\n        return payment_address();\n\n    return payment_address(secret.to_public(), secret.payment_version());\n}\n\npayment_address payment_address::from_public(const ec_public &point,\n                                             uint8_t version)\n{\n    if (!point)\n        return payment_address();\n\n    data_chunk data;\n    return point.to_data(data) ? payment_address(bitcoin_short_hash(data), version) : payment_address();\n}\n\npayment_address payment_address::from_script(const chain::script &script,\n                                             uint8_t version)\n{\n    return payment_address(bitcoin_short_hash(script.to_data(false)), version);\n}\n\n// Cast operators.\n// ----------------------------------------------------------------------------\n\npayment_address::operator const bool() const\n{\n    return valid_;\n}\n\npayment_address::operator const short_hash &() const\n{\n    return hash_;\n}\n\n// Serializer.\n// ----------------------------------------------------------------------------\n\nstd::string payment_address::encoded() const\n{\n    return encode_base58(wrap(version_, hash_));\n}\n\n// Accessors.\n// ----------------------------------------------------------------------------\n\nuint8_t payment_address::version() const\n{\n    return version_;\n}\n\nconst short_hash &payment_address::hash() const\n{\n    return hash_;\n}\n\n// Methods.\n// ----------------------------------------------------------------------------\n\npayment payment_address::to_payment() const\n{\n    return wrap(version_, hash_);\n}\n\n// Operators.\n// ----------------------------------------------------------------------------\n\npayment_address &payment_address::operator=(const payment_address &other)\n{\n    valid_ = other.valid_;\n    version_ = other.version_;\n    hash_ = other.hash_;\n    return *this;\n}\n\nbool payment_address::operator<(const payment_address &other) const\n{\n    return encoded() < other.encoded();\n}\n\nbool payment_address::operator==(const payment_address &other) const\n{\n    return valid_ == other.valid_ && version_ == other.version_ &&\n           hash_ == other.hash_;\n}\n\nbool payment_address::operator!=(const payment_address &other) const\n{\n    return !(*this == other);\n}\n\nstd::istream &operator>>(std::istream &in, payment_address &to)\n{\n    std::string value;\n    in >> value;\n    to = payment_address(value);\n\n    if (!to)\n    {\n        using namespace boost::program_options;\n        BOOST_THROW_EXCEPTION(invalid_option_value(value));\n    }\n\n    return in;\n}\n\nstd::ostream &operator<<(std::ostream &out, const payment_address &of)\n{\n    out << of.encoded();\n    return out;\n}\n\n// Static functions.\n// ----------------------------------------------------------------------------\n\npayment_address payment_address::extract(const chain::script &script,\n                                         uint8_t p2kh_version, uint8_t p2sh_version)\n{\n    if (!script.is_valid())\n        return payment_address();\n\n    short_hash hash;\n    const auto &ops = script.operations;\n\n    // Split out the assertions for readability.\n    // We know that the script is valid and can therefore rely on these.\n    switch (script.pattern())\n    {\n    // pay\n    // --------------------------------------------------------------------\n    case chain::script_pattern::pay_multisig:\n        break;\n    case chain::script_pattern::pay_public_key:\n        BITCOIN_ASSERT(ops.size() == 2);\n        BITCOIN_ASSERT(\n            ops[0].data.size() == ec_compressed_size ||\n            ops[0].data.size() == ec_uncompressed_size);\n        break;\n    case chain::script_pattern::pay_key_hash:\n        BITCOIN_ASSERT(ops.size() == 5);\n        BITCOIN_ASSERT(ops[2].data.size() == short_hash_size);\n        break;\n    case chain::script_pattern::pay_key_hash_with_lock_height:\n        BITCOIN_ASSERT(ops.size() == 7);\n        BITCOIN_ASSERT(ops[4].data.size() == short_hash_size);\n        break;\n    case chain::script_pattern::pay_script_hash:\n        BITCOIN_ASSERT(ops.size() == 3);\n        BITCOIN_ASSERT(ops[1].data.size() == short_hash_size);\n        break;\n    case chain::script_pattern::pay_blackhole_address:\n        BITCOIN_ASSERT(ops.size() == 1);\n        break;\n\n    // sign\n    // --------------------------------------------------------------------\n    case chain::script_pattern::sign_multisig:\n        break;\n    case chain::script_pattern::sign_public_key:\n        break;\n    case chain::script_pattern::sign_key_hash:\n        BITCOIN_ASSERT(ops.size() == 2);\n        BITCOIN_ASSERT(\n            ops[1].data.size() == ec_compressed_size ||\n            ops[1].data.size() == ec_uncompressed_size);\n        break;\n    case chain::script_pattern::sign_key_hash_with_lock_height:\n        BITCOIN_ASSERT(ops.size() == 3);\n        BITCOIN_ASSERT(\n            ops[1].data.size() == ec_compressed_size ||\n            ops[1].data.size() == ec_uncompressed_size);\n        break;\n    case chain::script_pattern::sign_script_hash:\n        BITCOIN_ASSERT(ops.size() > 1);\n        break;\n    case chain::script_pattern::pay_key_hash_with_attenuation_model:\n        BITCOIN_ASSERT(ops.size() == 8);\n        BITCOIN_ASSERT(ops[5].data.size() == short_hash_size);\n        break;\n    case chain::script_pattern::non_standard:\n    default:;\n    }\n\n    // Convert data to hash or point and construct address.\n    switch (script.pattern())\n    {\n        // pay\n        // --------------------------------------------------------------------\n\n    case chain::script_pattern::pay_multisig:\n        return payment_address();\n\n    case chain::script_pattern::pay_public_key:\n    {\n        const auto &data = ops[0].data;\n        if (data.size() == ec_compressed_size)\n        {\n            const auto point = to_array<ec_compressed_size>(data);\n            return payment_address(point, p2kh_version);\n        }\n\n        const auto point = to_array<ec_uncompressed_size>(data);\n        return payment_address(point, p2kh_version);\n    }\n\n    case chain::script_pattern::pay_key_hash:\n        hash = to_array<short_hash_size>(ops[2].data);\n        return payment_address(hash, p2kh_version);\n\n    case chain::script_pattern::pay_key_hash_with_lock_height:\n        hash = to_array<short_hash_size>(ops[4].data);\n        return payment_address(hash, p2kh_version);\n\n    case chain::script_pattern::pay_script_hash:\n        hash = to_array<short_hash_size>(ops[1].data);\n        return payment_address(hash, p2sh_version);\n\n    case chain::script_pattern::pay_blackhole_address:\n        return payment_address(blackhole_address);\n\n    case chain::script_pattern::pay_key_hash_with_attenuation_model:\n        hash = to_array<short_hash_size>(ops[5].data);\n        return payment_address(hash, p2kh_version);\n\n        // sign\n        // --------------------------------------------------------------------\n\n    case chain::script_pattern::sign_multisig:\n    {\n        bc::chain::script redeem_script;\n        // extract address from multisig payment script\n        // zero sig1 sig2 ... encoded-multisig\n        const auto &redeem_data = ops.back().data;\n\n        if (redeem_data.empty())\n            return payment_address(); //throw std::logic_error{\"empty redeem script.\"};\n\n        if (!redeem_script.from_data(redeem_data, false, bc::chain::script::parse_mode::strict))\n            return payment_address(); //throw std::logic_error{\"error occured when parse redeem script data.\"};\n\n        // Is the redeem script a standard pay (output) script?\n        const auto redeem_script_pattern = redeem_script.pattern();\n        if (redeem_script_pattern != chain::script_pattern::pay_multisig)\n            return payment_address(); //throw std::logic_error{\"redeem script is not pay multisig pattern.\"};\n\n        const payment_address address(redeem_script, 5);\n        //auto addr_str = address.encoded(); // pay address\n        //log::trace(\"input_addr\")<<redeem_script.to_string(false);\n        //log::trace(\"input_addr\")<<addr_str;\n        return address;\n    }\n\n    case chain::script_pattern::sign_public_key:\n        return payment_address();\n\n    case chain::script_pattern::sign_key_hash:\n    case chain::script_pattern::sign_key_hash_with_lock_height:\n    {\n        const auto &data = ops[1].data;\n        if (data.size() == ec_compressed_size)\n        {\n            const auto point = to_array<ec_compressed_size>(data);\n            return payment_address(point, p2kh_version);\n        }\n\n        const auto point = to_array<ec_uncompressed_size>(data);\n        return payment_address(point, p2kh_version);\n    }\n\n    case chain::script_pattern::sign_script_hash:\n        hash = bitcoin_short_hash(ops.back().data);\n        return payment_address(hash, p2sh_version);\n\n    case chain::script_pattern::non_standard:\n    default:\n        return payment_address();\n    }\n}\n\n} // namespace wallet\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/wallet/qrcode.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/wallet/qrcode.hpp>\n\n#include <iostream>\n#include <string>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/constants.hpp>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/utility/data.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\n#ifdef WITH_QRENCODE\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\ndata_chunk qr::encode(const data_chunk &data)\n{\n    return qr::encode(data, version, level, mode, case_sensitive);\n}\n\ndata_chunk qr::encode(const data_chunk &data, uint32_t version,\n                      error_recovery_level level, encode_mode mode, bool case_sensitive)\n{\n    data_chunk out;\n    data_sink ostream(out);\n    data_source istream(data);\n\n    if (qr::encode(istream, version, level, mode, case_sensitive, ostream))\n        return out;\n\n    return {};\n}\n\nbool qr::encode(std::istream &in, std::ostream &out)\n{\n    return qr::encode(in, version, level, mode, case_sensitive, out);\n}\n\nbool qr::encode(std::istream &in, uint32_t version, error_recovery_level level,\n                encode_mode mode, bool case_sensitive, std::ostream &out)\n{\n    std::string qr_string;\n    getline(in, qr_string);\n\n    const auto qrcode = QRcode_encodeString(qr_string.c_str(), version,\n                                            level, mode, case_sensitive);\n\n    if (qrcode == nullptr)\n        return false;\n\n    if (bc::max_size_t / qrcode->width < qrcode->width)\n        return false;\n\n    const auto area = qrcode->width * qrcode->width;\n    auto width_ptr = reinterpret_cast<const uint8_t *>(&qrcode->width);\n    auto version_ptr = reinterpret_cast<const uint8_t *>(&qrcode->version);\n\n    // Write out raw format of QRcode structure (defined in qrencode.h).\n    // Format written is:\n    // uint32_t version\n    // uint32_t width\n    // unsigned char* data (of width^2 length)\n    ostream_writer sink(out);\n    sink.write_data(version_ptr, sizeof(uint32_t));\n    sink.write_data(width_ptr, sizeof(uint32_t));\n    sink.write_data(qrcode->data, area);\n    out.flush();\n\n    return true;\n}\n\n} // namespace wallet\n} // namespace libbitcoin\n\n#endif // WITH_QRENCODE\n"
  },
  {
    "path": "src/UChain/coin/wallet/select_outputs.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/wallet/select_outputs.hpp>\n\n#include <algorithm>\n#include <cstdint>\n#include <UChain/coin/constants.hpp>\n#include <UChain/coin/formats/base_16.hpp>\n#include <UChain/coin/utility/assert.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\nusing namespace bc::chain;\n\nvoid select_outputs::select(points_info &out, output_info::list unspent,\n                            uint64_t minimum_value, algorithm DEBUG_ONLY(option))\n{\n    out.change = 0;\n    out.points.clear();\n\n    if (unspent.empty())\n        return;\n\n    const auto below_minimum = [minimum_value](const output_info &out_info) {\n        return out_info.value < minimum_value;\n    };\n\n    const auto lesser = [](const output_info &left, const output_info &right) {\n        return left.value < right.value;\n    };\n\n    const auto greater = [](const output_info &left, const output_info &right) {\n        return left.value > right.value;\n    };\n\n    const auto lesser_begin = unspent.begin();\n    const auto lesser_end = std::partition(unspent.begin(), unspent.end(),\n                                           below_minimum);\n\n    const auto greater_begin = lesser_end;\n    const auto greater_end = unspent.end();\n    const auto minimum_greater = std::min_element(greater_begin, greater_end,\n                                                  lesser);\n\n    if (minimum_greater != greater_end)\n    {\n        BITCOIN_ASSERT(minimum_greater->value >= minimum_value);\n        out.change = minimum_greater->value - minimum_value;\n        out.points.push_back(minimum_greater->point);\n        return;\n    }\n\n    // Not found in greaters so try several lessers instead.\n    // Sort descending, to use the fewest inputs possible.\n    std::sort(lesser_begin, lesser_end, greater);\n\n    for (auto it = lesser_begin; it != lesser_end; ++it)\n    {\n        BITCOIN_ASSERT(out.change <= max_uint64 - it->value);\n        out.change += it->value;\n        out.points.push_back(it->point);\n\n        if (out.change >= minimum_value)\n        {\n            out.change -= minimum_value;\n            return;\n        }\n    }\n\n    out.change = 0;\n    out.points.clear();\n}\n\n} // namespace wallet\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/wallet/stealth_address.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/wallet/stealth_address.hpp>\n\n#include <algorithm>\n#include <cstdint>\n#include <boost/program_options.hpp>\n#include <UChain/coin/formats/base_58.hpp>\n#include <UChain/coin/math/checksum.hpp>\n#include <UChain/coin/math/elliptic_curve.hpp>\n#include <UChain/coin/math/hash.hpp>\n#include <UChain/coin/math/stealth.hpp>\n#include <UChain/coin/utility/assert.hpp>\n#include <UChain/coin/utility/binary.hpp>\n#include <UChain/coin/utility/data.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\nusing namespace bc::chain;\n\nstatic constexpr uint8_t version_size = sizeof(uint8_t);\nstatic constexpr uint8_t options_size = sizeof(uint8_t);\nstatic constexpr uint8_t number_keys_size = sizeof(uint8_t);\nstatic constexpr uint8_t number_sigs_size = sizeof(uint8_t);\nstatic constexpr uint8_t filter_length_size = sizeof(uint8_t);\nstatic constexpr uint8_t max_spend_key_count = max_uint8;\n\n// wiki.unsystem.net/index.php/DarkWallet/Stealth#Address_format\n// [version:1=0x2a][options:1][scan_pubkey:33][N:1][spend_pubkey_1:33]..\n// [spend_pubkey_N:33][number_signatures:1][prefix_number_bits:1]\n// [filter:prefix_number_bits / 8, round up][checksum:4]\n// Estimate assumes N = 0 and prefix_length = 0:\nconstexpr size_t min_address_size = version_size + options_size +\n                                    ec_compressed_size + number_keys_size + number_sigs_size +\n                                    filter_length_size + checksum_size;\n\n// Document the assumption that the prefix is defined with an 8 bit block size.\nstatic_assert(binary::bits_per_block == byte_bits,\n              \"The stealth prefix must use an 8 bit block size.\");\n\nconst uint8_t stealth_address::mainnet_p2kh = 0x2a;\nconst uint8_t stealth_address::reuse_key_flag = 1 << 0;\nconst uint8_t stealth_address::max_filter_bits = sizeof(uint32_t) * byte_bits;\n\nstealth_address::stealth_address()\n    : valid_(false), version_(0), scan_key_(null_compressed_point),\n      spend_keys_(), signatures_(0), filter_()\n{\n}\n\nstealth_address::stealth_address(const stealth_address &other)\n    : valid_(other.valid_), version_(other.version_), scan_key_(other.scan_key_),\n      spend_keys_(other.spend_keys_), signatures_(other.signatures_),\n      filter_(other.filter_)\n{\n}\n\nstealth_address::stealth_address(const std::string &encoded)\n    : stealth_address(from_string(encoded))\n{\n}\n\nstealth_address::stealth_address(const data_chunk &decoded)\n    : stealth_address(from_stealth(decoded))\n{\n}\n\nstealth_address::stealth_address(const binary &filter,\n                                 const ec_compressed &scan_key, const point_list &spend_keys,\n                                 uint8_t signatures, uint8_t version)\n    : stealth_address(from_stealth(filter, scan_key, spend_keys, signatures,\n                                   version))\n{\n}\n\nstealth_address::stealth_address(uint8_t version, const binary &filter,\n                                 const ec_compressed &scan_key, const point_list &spend_keys,\n                                 uint8_t signatures)\n    : valid_(true), filter_(filter), scan_key_(scan_key),\n      spend_keys_(spend_keys), signatures_(signatures), version_(version)\n{\n}\n\n// Factories.\n// ----------------------------------------------------------------------------\n\nstealth_address stealth_address::from_string(const std::string &encoded)\n{\n    data_chunk decoded;\n    return decode_base58(decoded, encoded) ? stealth_address(decoded) : stealth_address();\n}\n\n// This is the stealth address parser.\nstealth_address stealth_address::from_stealth(const data_chunk &decoded)\n{\n    // Size is guarded until we get to N.\n    auto required_size = min_address_size;\n    if (decoded.size() < required_size || !verify_checksum(decoded))\n        return stealth_address();\n\n    // [version:1 = 0x2a]\n    auto iterator = decoded.begin();\n    const auto version = *iterator;\n\n    // [options:1]\n    ++iterator;\n    const auto options = *iterator;\n    if (options > reuse_key_flag)\n        return stealth_address();\n\n    // [scan_pubkey:33]\n    ++iterator;\n    auto scan_key_begin = iterator;\n    iterator += ec_compressed_size;\n    ec_compressed scan_key;\n    std::copy(scan_key_begin, iterator, scan_key.begin());\n\n    // [N:1]\n    auto number_spend_pubkeys = *iterator;\n    ++iterator;\n\n    // Adjust and retest required size. for pubkey list.\n    required_size += number_spend_pubkeys * ec_compressed_size;\n    if (decoded.size() < required_size)\n        return stealth_address();\n\n    // We don't explicitly save 'reuse', instead we add to spend_keys_.\n    point_list spend_keys;\n    if (options == reuse_key_flag)\n        spend_keys.emplace_back(scan_key);\n\n    // [spend_pubkey_1:33]..[spend_pubkey_N:33]\n    for (auto key = 0; key < number_spend_pubkeys; ++key)\n    {\n        auto spend_key_begin = iterator;\n        iterator += ec_compressed_size;\n        ec_compressed point;\n        std::copy(spend_key_begin, iterator, point.begin());\n        spend_keys.emplace_back(point);\n    }\n\n    // [number_signatures:1]\n    const auto signatures = *iterator;\n    ++iterator;\n\n    // [prefix_number_bits:1]\n    const auto filter_bits = *iterator;\n    if (filter_bits > max_filter_bits)\n        return stealth_address();\n\n    // [prefix:prefix_number_bits / 8, round up]\n    ++iterator;\n    const auto filter_bytes = (filter_bits + (byte_bits - 1)) / byte_bits;\n\n    // Adjust and retest required size.\n    required_size += filter_bytes;\n    if (decoded.size() != required_size)\n        return stealth_address();\n\n    // Deserialize the filter bytes/blocks.\n    const data_chunk raw_filter(iterator, iterator + filter_bytes);\n    const binary filter(filter_bits, raw_filter);\n    return stealth_address(filter, scan_key, spend_keys, signatures, version);\n}\n\n// This corrects signature and spend_keys.\nstealth_address stealth_address::from_stealth(const binary &filter,\n                                              const ec_compressed &scan_key, const point_list &spend_keys,\n                                              uint8_t signatures, uint8_t version)\n{\n    // Ensure there is at least one spend key.\n    auto spenders = spend_keys;\n    if (spenders.empty())\n        spenders.push_back(scan_key);\n\n    // Guard against too many keys.\n    const auto spend_keys_size = spenders.size();\n    if (spend_keys_size > max_spend_key_count)\n        return stealth_address();\n\n    // Guard against prefix too long.\n    auto prefix_number_bits = static_cast<uint8_t>(filter.size());\n    if (prefix_number_bits > max_filter_bits)\n        return stealth_address();\n\n    // Coerce signatures to a valid range.\n    const auto maximum = signatures == 0 || signatures > spend_keys_size;\n    const auto coerced = maximum ? static_cast<uint8_t>(spend_keys_size) : signatures;\n\n    // Parameter order is used to change the constructor signature.\n    return stealth_address(version, filter, scan_key, spenders, coerced);\n}\n\n// Cast operators.\n// ----------------------------------------------------------------------------\n\nstealth_address::operator bool() const\n{\n    return valid_;\n}\n\nstealth_address::operator data_chunk() const\n{\n    return to_chunk();\n}\n\n// Serializer.\n// ----------------------------------------------------------------------------\n\nstd::string stealth_address::encoded() const\n{\n    return encode_base58(to_chunk());\n}\n\nuint8_t stealth_address::version() const\n{\n    return version_;\n}\n\n// Accessors.\n// ----------------------------------------------------------------------------\n\nconst binary &stealth_address::filter() const\n{\n    return filter_;\n}\n\nconst ec_compressed &stealth_address::scan_key() const\n{\n    return scan_key_;\n}\n\nuint8_t stealth_address::signatures() const\n{\n    return signatures_;\n}\n\nconst point_list &stealth_address::spend_keys() const\n{\n    return spend_keys_;\n}\n\n// Methods.\n// ----------------------------------------------------------------------------\n\ndata_chunk stealth_address::to_chunk() const\n{\n    data_chunk address;\n    address.push_back(version());\n    address.push_back(options());\n    extend_data(address, scan_key_);\n\n    // Spend_pubkeys must have been guarded against a max size of 255.\n    auto number_spend_pubkeys = static_cast<uint8_t>(spend_keys_.size());\n\n    // Adjust for key reuse.\n    if (reuse_key())\n        --number_spend_pubkeys;\n\n    address.push_back(number_spend_pubkeys);\n\n    // Serialize the spend keys, excluding any that match the scan key.\n    for (const auto &key : spend_keys_)\n        if (key != scan_key_)\n            extend_data(address, key);\n\n    address.push_back(signatures_);\n\n    // The prefix must be guarded against a size greater than 32\n    // so that the bitfield can convert into uint32_t and sized by uint8_t.\n    const auto prefix_number_bits = static_cast<uint8_t>(filter_.size());\n\n    // Serialize the prefix bytes/blocks.\n    address.push_back(prefix_number_bits);\n    extend_data(address, filter_.blocks());\n\n    append_checksum(address);\n    return address;\n}\n\n// Helpers.\n// ----------------------------------------------------------------------------\n\nbool stealth_address::reuse_key() const\n{\n    // If the spend_keys_ contains the scan_key_ then the key is reused.\n    return std::find(spend_keys_.begin(), spend_keys_.end(), scan_key_) !=\n           spend_keys_.end();\n}\n\nuint8_t stealth_address::options() const\n{\n    // There is currently only one option.\n    return reuse_key() ? reuse_key_flag : 0x00;\n}\n\n// Operators.\n// ----------------------------------------------------------------------------\n\nstealth_address &stealth_address::operator=(const stealth_address &other)\n{\n    valid_ = other.valid_;\n    version_ = other.version_;\n    scan_key_ = other.scan_key_;\n    spend_keys_ = other.spend_keys_;\n    signatures_ = other.signatures_;\n    filter_ = other.filter_;\n    return *this;\n}\n\nbool stealth_address::operator<(const stealth_address &other) const\n{\n    return encoded() < other.encoded();\n}\n\nbool stealth_address::operator==(const stealth_address &other) const\n{\n    return valid_ == other.valid_ && version_ == other.version_ &&\n           scan_key_ == other.scan_key_ && spend_keys_ == other.spend_keys_ &&\n           signatures_ == other.signatures_ && filter_ == other.filter_;\n}\n\nbool stealth_address::operator!=(const stealth_address &other) const\n{\n    return !(*this == other);\n}\n\nstd::istream &operator>>(std::istream &in, stealth_address &to)\n{\n    std::string value;\n    in >> value;\n    to = stealth_address(value);\n\n    if (!to)\n    {\n        using namespace boost::program_options;\n        BOOST_THROW_EXCEPTION(invalid_option_value(value));\n    }\n\n    return in;\n}\n\nstd::ostream &operator<<(std::ostream &out, const stealth_address &of)\n{\n    out << of.encoded();\n    return out;\n}\n\n} // namespace wallet\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/coin/wallet/uri.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/coin/wallet/uri.hpp>\n\n#include <iomanip>\n#include <sstream>\n#include <UChain/coin/define.hpp>\n#include <UChain/coin/formats/base_16.hpp>\n\nnamespace libbitcoin\n{\nnamespace wallet\n{\n\n// These character classification functions correspond to RFC 3986.\n// They avoid C standard library character classification functions,\n// since those give different answers based on the current locale.\nstatic bool is_alpha(const char c)\n{\n    return ('A' <= c && c <= 'Z') ||\n           ('a' <= c && c <= 'z');\n}\n\nstatic bool is_scheme(const char c)\n{\n    return is_alpha(c) || ('0' <= c && c <= '9') ||\n           '+' == c || '-' == c || '.' == c;\n}\n\nstatic bool is_path_char(const char c)\n{\n    return is_alpha(c) || ('0' <= c && c <= '9') ||\n           '-' == c || '.' == c || '_' == c || '~' == c || // unreserved\n           '!' == c || '$' == c || '&' == c || '\\'' == c ||\n           '(' == c || ')' == c || '*' == c || '+' == c ||\n           ',' == c || ';' == c || '=' == c || // sub-delims\n           ':' == c || '@' == c;\n}\n\nstatic bool is_path(const char c)\n{\n    return is_path_char(c) || '/' == c;\n}\n\nstatic bool is_query(const char c)\n{\n    return is_path_char(c) || '/' == c || '?' == c;\n}\n\nstatic bool is_query_char(const char c)\n{\n    return is_query(c) && '&' != c && '=' != c;\n}\n\n// Verifies that all RFC 3986 escape sequences in a string are valid, and that\n// all characters belong to the given class.\nstatic bool validate(const std::string &in, bool (*is_valid)(const char))\n{\n    auto i = in.begin();\n    while (in.end() != i)\n    {\n        if ('%' == *i)\n        {\n            if (!(2 < in.end() - i && is_base16(i[1]) && is_base16(i[2])))\n                return false;\n\n            i += 3;\n        }\n        else\n        {\n            if (!is_valid(*i))\n                return false;\n\n            i += 1;\n        }\n    }\n\n    return true;\n}\n\n// Decodes all RFC 3986 escape sequences in a string.\nstatic std::string unescape(const std::string &in)\n{\n    // Do the conversion:\n    std::string out;\n    out.reserve(in.size());\n\n    auto i = in.begin();\n    while (in.end() != i)\n    {\n        if ('%' == *i && 2 < in.end() - i && is_base16(i[1]) &&\n            is_base16(i[2]))\n        {\n            const char temp[] = {i[1], i[2], 0};\n            out.push_back(base16_literal(temp)[0]);\n            i += 3;\n        }\n        else\n        {\n            out.push_back(*i);\n            i += 1;\n        }\n    }\n\n    return out;\n}\n\n// URI encodes a string (i.e. percent encoding).\n// is_valid a function returning true for acceptable characters.\nstatic std::string escape(const std::string &in, bool (*is_valid)(char))\n{\n    std::ostringstream stream;\n    stream << std::hex << std::uppercase << std::setfill('0');\n    for (const auto c : in)\n    {\n        if (is_valid(c))\n            stream << c;\n        else\n            stream << '%' << std::setw(2) << +c;\n    }\n\n    return stream.str();\n}\n\nbool uri::decode(const std::string &encoded, bool strict)\n{\n    auto i = encoded.begin();\n\n    // Store the scheme:\n    auto start = i;\n    while (encoded.end() != i && ':' != *i)\n        ++i;\n\n    scheme_ = std::string(start, i);\n    if (scheme_.empty() || !is_alpha(scheme_[0]))\n        return false;\n\n    if (!std::all_of(scheme_.begin(), scheme_.end(), is_scheme))\n        return false;\n\n    // Consume ':':\n    if (encoded.end() == i)\n        return false;\n\n    ++i;\n\n    // Consume \"//\":\n    authority_.clear();\n    has_authority_ = false;\n    if (1 < encoded.end() - i && '/' == i[0] && '/' == i[1])\n    {\n        has_authority_ = true;\n        i += 2;\n\n        // Store authority part:\n        start = i;\n        while (encoded.end() != i && '#' != *i && '?' != *i && '/' != *i)\n            ++i;\n\n        authority_ = std::string(start, i);\n        if (strict && !validate(authority_, is_path_char))\n            return false;\n    }\n\n    // Store the path part:\n    start = i;\n    while (encoded.end() != i && '#' != *i && '?' != *i)\n        ++i;\n\n    path_ = std::string(start, i);\n    if (strict && !validate(path_, is_path))\n        return false;\n\n    // Consume '?':\n    has_query_ = false;\n    if (encoded.end() != i && '#' != *i)\n    {\n        has_query_ = true;\n        ++i;\n    }\n\n    // Store the query part:\n    start = i;\n    while (encoded.end() != i && '#' != *i)\n        ++i;\n\n    query_ = std::string(start, i);\n    if (strict && !validate(query_, is_query))\n        return false;\n\n    // Consume '#':\n    has_fragment_ = false;\n    if (encoded.end() != i)\n    {\n        has_fragment_ = true;\n        ++i;\n    }\n\n    // Store the fragment part:\n    fragment_ = std::string(i, encoded.end());\n    return !strict || validate(fragment_, is_query);\n}\n\nstd::string uri::encoded() const\n{\n    std::ostringstream out;\n    out << scheme_ << ':';\n    if (has_authority_)\n        out << \"//\" << authority_;\n\n    out << path_;\n    if (has_query_)\n        out << '?' << query_;\n\n    if (has_fragment_)\n        out << '#' << fragment_;\n\n    return out.str();\n}\n\n// Scheme accessors:\n\nstd::string uri::scheme() const\n{\n    auto out = scheme_;\n    for (auto &c : out)\n        if ('A' <= c && c <= 'Z')\n            c = c - 'A' + 'a';\n\n    return out;\n}\n\nvoid uri::set_scheme(const std::string &scheme)\n{\n    scheme_ = scheme;\n}\n\n// Authority accessors:\n\nstd::string uri::authority() const\n{\n    return unescape(authority_);\n}\n\nbool uri::has_authority() const\n{\n    return has_authority_;\n}\n\nvoid uri::set_authority(const std::string &authority)\n{\n    has_authority_ = true;\n    authority_ = escape(authority, is_path_char);\n}\n\nvoid uri::remove_authority()\n{\n    has_authority_ = false;\n}\n\n// Path accessors:\n\nstd::string uri::path() const\n{\n    return unescape(path_);\n}\n\nvoid uri::set_path(const std::string &path)\n{\n    path_ = escape(path, is_path);\n}\n\n// Query accessors:\n\nstd::string uri::query() const\n{\n    return unescape(query_);\n}\n\nbool uri::has_query() const\n{\n    return has_query_;\n}\n\nvoid uri::set_query(const std::string &query)\n{\n    has_query_ = true;\n    query_ = escape(query, is_query);\n}\n\nvoid uri::remove_query()\n{\n    has_query_ = false;\n}\n\n// Fragment accessors:\n\nstd::string uri::fragment() const\n{\n    return unescape(fragment_);\n}\n\nbool uri::has_fragment() const\n{\n    return has_fragment_;\n}\n\nvoid uri::set_fragment(const std::string &fragment)\n{\n    has_fragment_ = true;\n    fragment_ = escape(fragment, is_query);\n}\n\nvoid uri::remove_fragment()\n{\n    has_fragment_ = false;\n}\n\n// Query interpretation:\n\nuri::query_map uri::decode_query() const\n{\n    query_map out;\n    auto i = query_.begin();\n    while (query_.end() != i)\n    {\n        // Read the key:\n        auto begin = i;\n        while (query_.end() != i && '&' != *i && '=' != *i)\n            ++i;\n\n        auto key = unescape(std::string(begin, i));\n\n        // Consume '=':\n        if (query_.end() != i && '&' != *i)\n            ++i;\n\n        // Read the value:\n        begin = i;\n        while (query_.end() != i && '&' != *i)\n            ++i;\n\n        out[key] = unescape(std::string(begin, i));\n\n        // Consume '&':\n        if (query_.end() != i)\n            ++i;\n    }\n\n    return out;\n}\n\nvoid uri::encode_query(const query_map &map)\n{\n    auto first = true;\n    std::ostringstream query;\n    for (const auto &term : map)\n    {\n        if (!first)\n            query << '&';\n\n        first = false;\n        query << escape(term.first, is_query_char);\n        if (!term.second.empty())\n            query << '=' << escape(term.second, is_query_char);\n    }\n\n    has_query_ = !map.empty();\n    query_ = query.str();\n}\n\n} // namespace wallet\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/database/CMakeLists.txt",
    "content": "FILE(GLOB_RECURSE database_SOURCES \"*.c\" \"*.h\" \"*.cpp\")\n\nADD_DEFINITIONS(-DBCD_STATIC=1)\n\nSET(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -Wno-braced-scalar-init\")\n\nADD_LIBRARY(database_static STATIC ${database_SOURCES})\nSET_TARGET_PROPERTIES(database_static PROPERTIES OUTPUT_NAME uc_database)\nTARGET_LINK_LIBRARIES(database_static ${Boost_LIBRARIES} ${txs_LIBRARY} ${bitcoin_LIBRARY})\nINSTALL(TARGETS database_static DESTINATION lib)\n\nIF(ENABLE_SHARED_LIBS)\n    ADD_DEFINITIONS(-DBCD_DLL=1)\n  ADD_LIBRARY(database_shared SHARED ${database_SOURCES})\n  SET_TARGET_PROPERTIES(database_shared PROPERTIES OUTPUT_NAME uc_database)\n  TARGET_LINK_LIBRARIES(database_shared ${Boost_LIBRARIES} ${txs_LIBRARY} ${bitcoin_LIBRARY})\n  INSTALL(TARGETS database_shared DESTINATION lib)\nENDIF()\n"
  },
  {
    "path": "src/UChain/database/data_base.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/database/data_base.hpp>\n\n#include <cstdint>\n#include <cstddef>\n#include <memory>\n#include <stdexcept>\n#include <algorithm>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChainService/txs/utility/path.hpp>\n#include <UChain/coin/config/base16.hpp> // used by db_metadata and push_asset\n#include <UChain/database/memory/memory_map.hpp>\n#include <UChain/database/settings.hpp>\n#include <UChain/database/version.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nusing namespace boost::filesystem;\nusing namespace bc::chain;\nusing namespace bc::wallet;\nusing namespace libbitcoin::config;\n\n// BIP30 exception blocks.\n// github.com/bitcoin/bips/blob/master/bip-0030.mediawiki#specification\nstatic const config::checkpoint exception1 =\n    {\"00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec\", 91842};\nstatic const config::checkpoint exception2 =\n    {\"00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721\", 91880};\n\nbool data_base::touch_file(const path &file_path)\n{\n    bc::ofstream file(file_path.string());\n    if (file.bad())\n        return false;\n\n    // Write one byte so file is nonzero size.\n    file.write(\"X\", 1);\n    return true;\n}\n\nbool data_base::initialize(const path &prefix, const chain::block &genesis)\n{\n    // Create paths.\n    const store paths(prefix);\n\n    if (!paths.touch_all())\n        return false;\n\n    data_base instance(paths, 0, 0);\n\n    if (!instance.create())\n    {\n        return false;\n    }\n    auto metadata_path = prefix / db_metadata::file_name;\n    auto metadata = db_metadata(db_metadata::current_version);\n    data_base::write_metadata(metadata_path, metadata);\n    instance.push(genesis);\n    return instance.stop();\n}\n\nbool data_base::initialize_uids(const path &prefix)\n{\n    const store paths(prefix);\n    if (paths.uids_exist())\n        return true;\n    if (!paths.touch_uids())\n        return false;\n\n    data_base instance(prefix, 0, 0);\n    if (!instance.create_uids())\n        return false;\n\n    instance.set_blackhole_uid();\n\n    log::info(LOG_DATABASE)\n        << \"Upgrading uid table is complete.\";\n\n    return instance.stop();\n}\n\nbool data_base::initialize_tokens(const path &prefix)\n{\n    const store paths(prefix);\n    if (paths.tokens_exist())\n        return true;\n    if (!paths.touch_tokens())\n        return false;\n\n    data_base instance(prefix, 0, 0);\n    if (!instance.create_tokens())\n        return false;\n    instance.set_block_vote_token();\n\n    log::info(LOG_DATABASE)\n        << \"Upgrading token table is complete.\";\n\n    return instance.stop();\n}\n\nbool data_base::initialize_certs(const path &prefix)\n{\n    const store paths(prefix);\n    if (paths.certs_exist())\n        return true;\n    if (!paths.touch_certs())\n        return false;\n\n    data_base instance(prefix, 0, 0);\n    if (!instance.create_certs())\n        return false;\n\n    log::info(LOG_DATABASE)\n        << \"Upgrading cert table is complete.\";\n\n    return instance.stop();\n}\n\nbool data_base::initialize_candidates(const path &prefix)\n{\n    const store paths(prefix);\n    if (paths.candidates_exist())\n        return true;\n    if (!paths.touch_candidates())\n        return false;\n\n    data_base instance(prefix, 0, 0);\n    if (!instance.create_candidates())\n        return false;\n\n    instance.set_reward_pool_candidate();\n\n    log::info(LOG_DATABASE)\n        << \"Upgrading candidate table is complete.\";\n\n    return instance.stop();\n}\n\nbool data_base::upgrade_version_63(const path &prefix)\n{\n    auto metadata_path = prefix / db_metadata::file_name;\n    if (!boost::filesystem::exists(metadata_path))\n        return false;\n\n    data_base::db_metadata metadata;\n    data_base::read_metadata(metadata_path, metadata);\n    if (metadata.version_.empty())\n    {\n        return false; // no version before, initialize all intead of upgrade.\n    }\n\n    if (!initialize_uids(prefix))\n    {\n        log::error(LOG_DATABASE)\n            << \"Failed to upgrade uid database.\";\n        return false;\n    }\n\n    if (!initialize_certs(prefix))\n    {\n        log::error(LOG_DATABASE)\n            << \"Failed to upgrade cert database.\";\n        return false;\n    }\n\n    if (!initialize_candidates(prefix))\n    {\n        log::error(LOG_DATABASE)\n            << \"Failed to upgrade candidate database.\";\n        return false;\n    }\n\n    if (metadata.version_ != db_metadata::current_version)\n    {\n        // write new db version to metadata\n        metadata = db_metadata(db_metadata::current_version);\n        data_base::write_metadata(metadata_path, metadata);\n    }\n\n    return true;\n}\n\nvoid data_base::set_admin(const std::string &name, const std::string &passwd)\n{\n    wallets.set_admin(name, passwd);\n}\n\nvoid data_base::set_blackhole_uid()\n{\n    const std::string uid_symbol = UC_BLACKHOLE_UID_SYMBOL;\n    const std::string &uid_address = bc::wallet::payment_address::blackhole_address;\n    uid_detail blackholeuiddetail(uid_symbol, uid_address);\n    data_chunk blackholedata(uid_address.begin(), uid_address.end());\n    short_hash blackholedatahash = ripemd160_hash(blackholedata);\n\n    /*const std::string rewardpool_uid_symbol = UC_REWARD_POOL_UID_SYMBOL;\n    const std::string& rewardpool_uid_address = get_reward_pool_address(false);\n    uid_detail rewardpooluiddetail(rewardpool_uid_symbol, rewardpool_uid_address);\n    data_chunk rewardpooldata(rewardpool_uid_address.begin(), rewardpool_uid_address.end());\n    short_hash rewardpoolhash = ripemd160_hash(rewardpooldata);*/\n\n    output_point outpoint = {null_hash, max_uint32};\n    uint64_t value = 0;\n\n    push_uid_detail(blackholeuiddetail, blackholedatahash, outpoint, max_uint32, value);\n    //push_uid_detail(rewardpooluiddetail, rewardpoolhash, outpoint, 0, value);\n\n    //synchronize_uids();\n}\n\nvoid data_base::set_block_vote_token()\n{\n    const std::string &uid_address = bc::wallet::payment_address::blackhole_address;\n    token_detail blocktokendetail(\n        UC_BLOCK_TOKEN_SYMBOL, 0,\n        1, 0, UC_BLACKHOLE_UID_SYMBOL,\n        bc::wallet::payment_address::blackhole_address, \"'BLOCK' token is issued by blackhole.Miners can use it to get reward\");\n\n    token_detail votetokendetail(\n        UC_VOTE_TOKEN_SYMBOL, 0,\n        1, 0, UC_BLACKHOLE_UID_SYMBOL,\n        bc::wallet::payment_address::blackhole_address, \"'VOTE' token is issued by blackhole.Users can use it to vote.\");\n\n    data_chunk data(uid_address.begin(), uid_address.end());\n    short_hash hash = ripemd160_hash(data);\n\n    output_point outpoint = {null_hash, max_uint32};\n    uint32_t output_height = max_uint32;\n    uint64_t value = 0;\n\n    push_token_detail(blocktokendetail, hash, outpoint, output_height, value);\n    push_token_detail(votetokendetail, hash, outpoint, output_height, value);\n    //synchronize_tokens();\n}\n\nvoid data_base::set_reward_pool_candidate()\n{\n    const std::string &uid_address = get_reward_pool_address(false);\n    candidate candidatedetail(\n        UC_REWARD_POOL_CANDIDATE_SYMBOL, uid_address,\n        \"'reward_pool_miner' candidate is issued by reward_pool just to maintain blockchain when there is no any other miner.\", CANDIDATE_STATUS_REGISTER);\n\n    data_chunk data(uid_address.begin(), uid_address.end());\n    short_hash hash = ripemd160_hash(data);\n\n    output_point outpoint = {null_hash, max_uint32};\n    uint32_t output_height = max_uint32;\n    uint64_t value = 0;\n\n    push_candidate(candidatedetail, hash, outpoint, output_height, value, UC_REWARD_POOL_UID_SYMBOL, UC_REWARD_POOL_UID_SYMBOL);\n    //synchronize_candidates();\n}\n\ndata_base::store::store(const path &prefix)\n{\n    // Hash-based lookup (hash tables).\n    blocks_lookup = prefix / \"block_table\";\n    history_lookup = prefix / \"history_table\";\n    spends_lookup = prefix / \"spend_table\";\n    transactions_lookup = prefix / \"transaction_table\";\n    /* begin database for wallet, token, address_token relationship */\n    wallets_lookup = prefix / \"wallet_table\";\n    tokens_lookup = prefix / \"token_table\";                 // for blockchain tokens\n    certs_lookup = prefix / \"cert_table\";                   // for blockchain certs\n    address_tokens_lookup = prefix / \"address_token_table\"; // for blockchain\n    address_tokens_rows = prefix / \"address_token_row\";     // for blockchain\n    wallet_tokens_lookup = prefix / \"wallet_token_table\";\n    wallet_tokens_rows = prefix / \"wallet_token_row\";\n    uids_lookup = prefix / \"uid_table\";\n    address_uids_lookup = prefix / \"address_uid_table\"; // for blockchain\n    address_uids_rows = prefix / \"address_uid_row\";     // for blockchain\n    wallet_addresses_lookup = prefix / \"wallet_address_table\";\n    wallet_addresses_rows = prefix / \"wallet_address_rows\";\n    /* end database for wallet, token, address_token relationship */\n    candidates_lookup = prefix / \"candidate_table\";\n    address_candidates_lookup = prefix / \"address_candidate_table\"; // for blockchain\n    address_candidates_rows = prefix / \"address_candidate_row\";     // for blockchain\n    candidate_history_lookup = prefix / \"candidate_history_table\";  // for blockchain\n    candidate_history_rows = prefix / \"candidate_history_row\";      // for blockchain\n\n    // Height-based (reverse) lookup.\n    blocks_index = prefix / \"block_index\";\n\n    // One (address) to many (rows).\n    history_rows = prefix / \"history_rows\";\n    stealth_rows = prefix / \"stealth_rows\";\n\n    // Exclusive database access reserved by this process.\n    database_lock = prefix / \"process_lock\";\n}\n\nbool data_base::store::touch_all() const\n{\n    // Return the result of the database file create.\n    return touch_file(blocks_lookup) &&\n           touch_file(blocks_index) &&\n           touch_file(history_lookup) &&\n           touch_file(history_rows) &&\n           touch_file(stealth_rows) &&\n           touch_file(spends_lookup) &&\n           touch_file(transactions_lookup) &&\n           /* begin database for wallet, token, address_token relationship */\n           touch_file(wallets_lookup) &&\n           touch_file(tokens_lookup) &&\n           touch_file(certs_lookup) &&\n           touch_file(address_tokens_lookup) &&\n           touch_file(address_tokens_rows) &&\n           touch_file(wallet_tokens_lookup) &&\n           touch_file(wallet_tokens_rows) &&\n           touch_file(uids_lookup) &&\n           touch_file(address_uids_lookup) &&\n           touch_file(address_uids_rows) &&\n           touch_file(wallet_addresses_lookup) &&\n           touch_file(wallet_addresses_rows) &&\n           /* end database for wallet, token, address_token relationship */\n           touch_file(candidates_lookup) &&\n           touch_file(address_candidates_lookup) &&\n           touch_file(address_candidates_rows) &&\n           touch_file(candidate_history_lookup) &&\n           touch_file(candidate_history_rows);\n}\n\nbool data_base::store::uids_exist() const\n{\n    return boost::filesystem::exists(uids_lookup) ||\n           boost::filesystem::exists(address_uids_lookup) ||\n           boost::filesystem::exists(address_uids_rows);\n}\n\nbool data_base::store::touch_uids() const\n{\n    return touch_file(uids_lookup) &&\n           touch_file(address_uids_lookup) &&\n           touch_file(address_uids_rows);\n}\n\nbool data_base::store::tokens_exist() const\n{\n    return boost::filesystem::exists(tokens_lookup) ||\n           boost::filesystem::exists(address_tokens_lookup) ||\n           boost::filesystem::exists(address_tokens_rows);\n}\n\nbool data_base::store::touch_tokens() const\n{\n    return touch_file(tokens_lookup) &&\n           touch_file(address_tokens_lookup) &&\n           touch_file(address_tokens_rows);\n}\n\nbool data_base::store::certs_exist() const\n{\n    return boost::filesystem::exists(certs_lookup);\n}\n\nbool data_base::store::touch_certs() const\n{\n    return touch_file(certs_lookup);\n}\n\nbool data_base::store::candidates_exist() const\n{\n    return boost::filesystem::exists(candidates_lookup) ||\n           boost::filesystem::exists(address_candidates_lookup) ||\n           boost::filesystem::exists(address_candidates_rows) ||\n           boost::filesystem::exists(candidate_history_lookup) ||\n           boost::filesystem::exists(candidate_history_rows);\n}\n\nbool data_base::store::touch_candidates() const\n{\n    return touch_file(candidates_lookup) &&\n           touch_file(address_candidates_lookup) &&\n           touch_file(address_candidates_rows) &&\n           touch_file(candidate_history_lookup) &&\n           touch_file(candidate_history_rows);\n}\n\ndata_base::db_metadata::db_metadata() : version_(\"\")\n{\n}\n\ndata_base::db_metadata::db_metadata(std::string version) : version_(version)\n{\n}\n\nvoid data_base::db_metadata::reset()\n{\n    version_ = \"\";\n}\n\nbool data_base::db_metadata::from_data(const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(istream);\n}\n\nbool data_base::db_metadata::from_data(std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(source);\n}\n\nbool data_base::db_metadata::from_data(reader &source)\n{\n    reset();\n    version_ = source.read_string();\n    //auto result = static_cast<bool>(source);\n    return true;\n}\n\ndata_chunk data_base::db_metadata::to_data() const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream);\n    ostream.flush();\n    //BITCOIN_ASSERT(data.size() == serialized_size());\n    return data;\n}\n\nvoid data_base::db_metadata::to_data(std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(sink);\n}\n\nvoid data_base::db_metadata::to_data(writer &sink) const\n{\n    sink.write_string(version_);\n}\n\nuint64_t data_base::db_metadata::serialized_size() const\n{\n    return sizeof(version_);\n}\n\n#ifdef UC_DEBUG\nstd::string data_base::db_metadata::to_string() const\n{\n    std::ostringstream ss;\n\n    ss << \"\\t version = \" << version_ << \"\\n\";\n    return ss.str();\n}\n#endif\n\nstd::istream &operator>>(std::istream &input, data_base::db_metadata &metadata)\n{\n    std::string hexcode;\n    input >> hexcode;\n\n    metadata.from_data(base16(hexcode));\n\n    return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const data_base::db_metadata &metadata)\n{\n    // tx base16 is a private encoding in bx, used to pass between commands.\n    const auto bytes = metadata.to_data();\n    output << base16(bytes);\n    return output;\n}\n\nconst std::string data_base::db_metadata::current_version = UC_DATABASE_VERSION;\nconst std::string data_base::db_metadata::file_name = \"metadata\";\n\ndata_base::file_lock data_base::initialize_lock(const path &lock)\n{\n    // Touch the lock file to ensure its existence.\n    const auto lock_file_path = lock.string();\n    bc::ofstream file(lock_file_path, std::ios::app);\n    file.close();\n#ifdef UNICODE\n    std::function<std::string(std::wstring)> f = [&](std::wstring wide) -> std::string {\n        int ansiiLen = WideCharToMultiByte(CP_ACP, 0, wide.c_str(), -1, nullptr, 0, nullptr, nullptr);\n        char *pAssii = new char[ansiiLen];\n        WideCharToMultiByte(CP_ACP, 0, wide.c_str(), -1, pAssii, ansiiLen, nullptr, nullptr);\n        std::string str(pAssii);\n        delete[] pAssii;\n        return str;\n    };\n    std::string path_str = f(lock.wstring());\n#else\n    std::string path_str = lock_file_path;\n#endif\n    // BOOST:\n    // Opens a file lock. Throws interprocess_exception if the file does not\n    // exist or there are no operating system resources. The file lock is\n    // destroyed on its destruct and does not throw.\n    return file_lock(path_str.c_str());\n}\n\nvoid data_base::uninitialize_lock(const path &lock)\n{\n    // BUGBUG: Throws if the lock is not held (i.e. in error condition).\n    boost::filesystem::remove(lock);\n}\n\ndata_base::data_base(const settings &settings)\n    : data_base(settings.directory, settings.history_start_height,\n                settings.stealth_start_height)\n{\n}\n\ndata_base::data_base(const path &prefix, size_t history_height,\n                     size_t stealth_height)\n    : data_base(store(prefix), history_height, stealth_height)\n{\n}\n\ndata_base::data_base(const store &paths, size_t history_height,\n                     size_t stealth_height)\n    : lock_file_path_(paths.database_lock),\n      history_height_(history_height),\n      stealth_height_(stealth_height),\n      sequential_lock_(0),\n      mutex_(std::make_shared<shared_mutex>()),\n      blocks(paths.blocks_lookup, paths.blocks_index, mutex_),\n      history(paths.history_lookup, paths.history_rows, mutex_),\n      stealth(paths.stealth_rows, mutex_),\n      spends(paths.spends_lookup, mutex_),\n      transactions(paths.transactions_lookup, mutex_),\n      /* begin database for wallet, token, address_token, uid relationship */\n      wallets(paths.wallets_lookup, mutex_),\n      tokens(paths.tokens_lookup, mutex_),\n      address_tokens(paths.address_tokens_lookup, paths.address_tokens_rows, mutex_),\n      wallet_tokens(paths.wallet_tokens_lookup, paths.wallet_tokens_rows, mutex_),\n      certs(paths.certs_lookup, mutex_),\n      uids(paths.uids_lookup, mutex_),\n      address_uids(paths.address_uids_lookup, paths.address_uids_rows, mutex_),\n      wallet_addresses(paths.wallet_addresses_lookup, paths.wallet_addresses_rows, mutex_),\n      /* end database for wallet, token, address_token, uid relationship */\n      candidates(paths.candidates_lookup, mutex_),\n      candidate_history(paths.candidate_history_lookup, paths.candidate_history_rows, mutex_)\n{\n}\n\n// Close does not call stop because there is no way to detect thread join.\ndata_base::~data_base()\n{\n    close();\n}\n\nvoid data_base::write_metadata(const path &metadata_path, data_base::db_metadata &metadata)\n{\n    bc::ofstream file_output(metadata_path.string(), std::ofstream::out);\n    file_output << metadata;\n    file_output << std::flush;\n    file_output.close();\n}\n\nvoid data_base::read_metadata(const path &metadata_path, data_base::db_metadata &metadata)\n{\n    if (!boost::filesystem::exists(metadata_path))\n    {\n        metadata = data_base::db_metadata();\n        return;\n    }\n    bc::ifstream file_input(metadata_path.string(), std::ofstream::in);\n    if (!file_input.good())\n    {\n        throw std::logic_error{std::string(\"read_metadata error : \") + strerror(errno)};\n    }\n    file_input >> metadata;\n    file_input.close();\n}\n\n// Startup and shutdown.\n// ----------------------------------------------------------------------------\n\n// Leaves database in started state.\n// Throws if there is insufficient disk space.\n// TODO: merge this with file creation (initialization above).\n// This is actually first initialization of existing files, not file creation.\nbool data_base::create()\n{\n    // Return the result of the database create.\n    return blocks.create() &&\n           history.create() &&\n           spends.create() &&\n           stealth.create() &&\n           transactions.create() &&\n           /* begin database for wallet, token, address_token relationship */\n           wallets.create() &&\n           tokens.create() &&\n           address_tokens.create() &&\n           wallet_tokens.create() &&\n           certs.create() &&\n           uids.create() &&\n           address_uids.create() &&\n           wallet_addresses.create() &&\n           /* end database for wallet, token, address_token relationship */\n           candidates.create() &&\n           candidate_history.create();\n}\n\nbool data_base::create_uids()\n{\n    return uids.create() &&\n           address_uids.create();\n}\n\nbool data_base::create_tokens()\n{\n    return tokens.create() &&\n           address_tokens.create();\n}\n\nbool data_base::create_certs()\n{\n    return certs.create();\n}\n\nbool data_base::create_candidates()\n{\n    return candidates.create() &&\n           candidate_history.create();\n}\n\n// Start must be called before performing queries.\n// Start may be called after stop and/or after close in order to restart.\nbool data_base::start()\n{\n    // TODO: create a class to encapsulate the full file lock concept.\n    file_lock_ = std::make_shared<file_lock>(initialize_lock(lock_file_path_));\n\n    // BOOST:\n    // Effects: The calling thread tries to acquire exclusive ownership of the\n    // mutex without waiting. If no other thread has exclusive, or sharable\n    // ownership of the mutex this succeeds. Returns: If it can acquire\n    // exclusive ownership immediately returns true. If it has to wait, returns\n    // false. Throws: interprocess_exception on error. Note that a file lock\n    // can't guarantee synchronization between threads of the same process so\n    // just use file locks to synchronize threads from different processes.\n    if (!file_lock_->try_lock())\n        return false;\n\n    const auto start_exclusive = begin_write();\n    const auto start_result =\n        blocks.start() &&\n        history.start() &&\n        spends.start() &&\n        stealth.start() &&\n        transactions.start() &&\n        /* begin database for wallet, token, address_token relationship */\n        wallets.start() &&\n        tokens.start() &&\n        address_tokens.start() &&\n        wallet_tokens.start() &&\n        certs.start() &&\n        uids.start() &&\n        address_uids.start() &&\n        wallet_addresses.start() &&\n        /* end database for wallet, token, address_token relationship */\n        candidates.start() &&\n        candidate_history.start();\n    const auto end_exclusive = end_write();\n\n    // Return the result of the database start.\n    return start_exclusive && start_result && end_exclusive;\n}\n\n// Stop only accelerates work termination, only required if restarting.\nbool data_base::stop()\n{\n    const auto start_exclusive = begin_write();\n    const auto blocks_stop = blocks.stop();\n    const auto history_stop = history.stop();\n    const auto spends_stop = spends.stop();\n    const auto stealth_stop = stealth.stop();\n    const auto transactions_stop = transactions.stop();\n    /* begin database for wallet, token, address_token relationship */\n    const auto wallets_stop = wallets.stop();\n    const auto tokens_stop = tokens.stop();\n    const auto address_tokens_stop = address_tokens.stop();\n    const auto wallet_tokens_stop = wallet_tokens.stop();\n    const auto certs_stop = certs.stop();\n    const auto uids_stop = uids.stop();\n    const auto address_uids_stop = address_uids.stop();\n    const auto wallet_addresses_stop = wallet_addresses.stop();\n    /* end database for wallet, token, address_token relationship */\n    const auto candidates_stop = candidates.stop();\n    const auto candidate_history_stop = candidate_history.stop();\n    const auto end_exclusive = end_write();\n\n    // This should remove the lock file. This is not important for locking\n    // purposes, but it provides a sentinel to indicate hard shutdown.\n    file_lock_ = nullptr;\n    uninitialize_lock(lock_file_path_);\n\n    // Return the cumulative result of the database shutdowns.\n    return start_exclusive &&\n           blocks_stop &&\n           history_stop &&\n           spends_stop &&\n           stealth_stop &&\n           transactions_stop &&\n           /* begin database for wallet, token, address_token relationship */\n           wallets_stop &&\n           tokens_stop &&\n           address_tokens_stop &&\n           wallet_tokens_stop &&\n           certs_stop &&\n           uids_stop &&\n           address_uids_stop &&\n           wallet_addresses_stop &&\n           /* end database for wallet, token, address_token relationship */\n           candidates_stop &&\n           candidate_history_stop &&\n           end_exclusive;\n}\n\n// Close is optional as the database will close on destruct.\nbool data_base::close()\n{\n    const auto blocks_close = blocks.close();\n    const auto history_close = history.close();\n    const auto spends_close = spends.close();\n    const auto stealth_close = stealth.close();\n    const auto transactions_close = transactions.close();\n    /* begin database for wallet, token, address_token relationship */\n    const auto wallets_close = wallets.close();\n    const auto tokens_close = tokens.close();\n    const auto address_tokens_close = address_tokens.close();\n    const auto address_uids_close = address_uids.close();\n    const auto wallet_tokens_close = wallet_tokens.close();\n    const auto certs_close = certs.close();\n    const auto uids_close = uids.close();\n    const auto wallet_addresses_close = wallet_addresses.close();\n    /* end database for wallet, token, address_token relationship */\n    const auto candidates_close = candidates.close();\n    const auto candidate_history_close = candidate_history.close();\n\n    // Return the cumulative result of the database closes.\n    return blocks_close &&\n           history_close &&\n           spends_close &&\n           stealth_close &&\n           transactions_close &&\n           /* begin database for wallet, token, address_token relationship */\n           wallets_close &&\n           tokens_close &&\n           address_tokens_close &&\n           address_uids_close &&\n           wallet_tokens_close &&\n           certs_close &&\n           uids_close &&\n           wallet_addresses_close &&\n           /* end database for wallet, token, address_token relationship */\n           candidates_close &&\n           candidate_history_close;\n}\n\n// Locking.\n// ----------------------------------------------------------------------------\n\nhandle data_base::begin_read()\n{\n    return sequential_lock_.load();\n}\n\nbool data_base::is_read_valid(handle value)\n{\n    return value == sequential_lock_.load();\n}\n\nbool data_base::is_write_locked(handle value)\n{\n    return (value % 2) == 1;\n}\n\n// TODO: drop a file as a write sentinel that we can use to detect uncontrolled\n// shutdown during write. Use a similar approach around initial block download.\n// Fail startup if the sentinel is detected. (file: write_lock).\nbool data_base::begin_write()\n{\n    // slock is now odd.\n    return is_write_locked(++sequential_lock_);\n}\n\n// TODO: clear the write sentinel.\nbool data_base::end_write()\n{\n    // slock_ is now even again.\n    return !is_write_locked(++sequential_lock_);\n}\n\n// Query engines.\n// ----------------------------------------------------------------------------\n\nstatic size_t get_next_height(const block_database &blocks)\n{\n    size_t current_height;\n    const auto empty_chain = !blocks.top(current_height);\n    return empty_chain ? 0 : current_height + 1;\n}\n\nstatic bool is_allowed_duplicate(const header &head, size_t height)\n{\n    return (height == exception1.height() && head.hash() == exception1.hash()) ||\n           (height == exception2.height() && head.hash() == exception2.hash());\n}\n\nvoid data_base::synchronize()\n{\n    spends.sync();\n    history.sync();\n    stealth.sync();\n    transactions.sync();\n    /* begin database for wallet, token, address_token relationship */\n    wallets.sync();\n    tokens.sync();\n    address_tokens.sync();\n    wallet_tokens.sync();\n    certs.sync();\n    uids.sync();\n    address_uids.sync();\n    wallet_addresses.sync();\n    /* end database for wallet, token, address_token relationship */\n    candidates.sync();\n    candidate_history.sync();\n    blocks.sync();\n}\n\nvoid data_base::synchronize_uids()\n{\n    uids.sync();\n    address_uids.sync();\n}\n\nvoid data_base::synchronize_certs()\n{\n    certs.sync();\n}\n\nvoid data_base::synchronize_candidates()\n{\n    candidates.sync();\n    candidate_history.sync();\n}\n\nvoid data_base::synchronize_tokens()\n{\n    tokens.sync();\n    address_tokens.sync();\n    wallet_tokens.sync();\n}\n\nvoid data_base::push(const block &block)\n{\n    // Height is unsafe unless database locked.\n    push(block, get_next_height(blocks));\n}\n\nvoid data_base::push(const block &block, uint64_t height)\n{\n    for (size_t index = 0; index < block.transactions.size(); ++index)\n    {\n        // Skip BIP30 allowed duplicates (coinbase txs of excepted blocks).\n        // We handle here because this is the lowest public level exposed.\n        if (index == 0 && is_allowed_duplicate(block.header, height))\n            continue;\n\n        const auto &tx = block.transactions[index];\n        const auto tx_hash = tx.hash();\n\n        timestamp_ = block.header.timestamp; // for address_token_database store_input/store_output used only\n        // Add inputs\n        if (!tx.is_strict_coinbase())\n            push_inputs(tx_hash, height, tx.inputs);\n\n        // std::string uidaddress = tx.get_uid_transfer_old_address();\n        // if (!uidaddress.empty()) {\n        //     data_chunk data(uidaddress.begin(), uidaddress.end());\n        //     short_hash key = ripemd160_hash(data);\n        //     address_uids.delete_old_uid(key);\n        // }\n\n        // Add outputs\n        push_outputs(tx_hash, height, tx.outputs);\n\n        // Add stealth outputs\n        push_stealth(tx_hash, height, tx.outputs);\n\n        // Add transaction\n        transactions.store(height, index, tx);\n    }\n\n    // Add block itself.\n    blocks.store(block, height);\n\n    // Synchronise everything that was added.\n    synchronize();\n}\n\nvoid data_base::push_inputs(const hash_digest &tx_hash, size_t height,\n                            const input::list &inputs)\n{\n    for (uint32_t index = 0; index < inputs.size(); ++index)\n    {\n        // We also push spends in the inputs loop.\n        const auto &input = inputs[index];\n        const chain::input_point point{tx_hash, index};\n        spends.store(input.previous_output, point);\n\n        if (height < history_height_)\n            continue;\n\n        // Try to extract an address.\n        const auto address = payment_address::extract(input.script);\n        if (!address)\n            continue;\n\n        const auto &previous = input.previous_output;\n        history.add_input(address.hash(), point, height, previous);\n\n        /* begin added for token issue/transfer */\n        auto address_str = address.encoded();\n        data_chunk data(address_str.begin(), address_str.end());\n        short_hash key = ripemd160_hash(data);\n        address_tokens.store_input(key, point, height, previous, timestamp_);\n        address_tokens.sync();\n        /* end added for token issue/transfer */\n    }\n}\n\nvoid data_base::push_outputs(const hash_digest &tx_hash, size_t height,\n                             const output::list &outputs)\n{\n    if (height < history_height_)\n        return;\n\n    for (uint32_t index = 0; index < outputs.size(); ++index)\n    {\n        const auto &output = outputs[index];\n        const chain::output_point point{tx_hash, index};\n\n        // Try to extract an address.\n        const auto address = payment_address::extract(output.script);\n        if (!address)\n            continue;\n\n        const auto value = output.value;\n        history.add_output(address.hash(), point, height, value);\n\n        push_asset(output.attach_data, address, point, height, value);\n    }\n}\n\nvoid data_base::push_stealth(const hash_digest &tx_hash, size_t height,\n                             const output::list &outputs)\n{\n    if (height < stealth_height_ || outputs.empty())\n        return;\n\n    // Stealth outputs are paired by convention.\n    for (size_t index = 0; index < (outputs.size() - 1); ++index)\n    {\n        const auto &ephemeral_script = outputs[index].script;\n        const auto &payment_script = outputs[index + 1].script;\n\n        // Try to extract an unsigned ephemeral key from the first output.\n        hash_digest unsigned_ephemeral_key;\n        if (!extract_ephemeral_key(unsigned_ephemeral_key, ephemeral_script))\n            continue;\n\n        // Try to extract a stealth prefix from the first output.\n        uint32_t prefix;\n        if (!to_stealth_prefix(prefix, ephemeral_script))\n            continue;\n\n        // Try to extract the payment address from the second output.\n        const auto address = payment_address::extract(payment_script);\n        if (!address)\n            continue;\n\n        // The payment address versions are arbitrary and unused here.\n        const chain::stealth_compact row{\n            unsigned_ephemeral_key,\n            address.hash(),\n            tx_hash};\n\n        stealth.store(prefix, height, row);\n    }\n}\n\nchain::block data_base::pop()\n{\n    size_t height;\n    DEBUG_ONLY(const auto result =)\n    blocks.top(height);\n    BITCOIN_ASSERT_MSG(result, \"Pop on empty database.\");\n\n    const auto block_result = blocks.get(height);\n    const auto count = block_result.transaction_count();\n\n    // Build the block for return.\n    chain::block block;\n    block.header = block_result.header();\n    block.transactions.reserve(count);\n    auto &txs = block.transactions;\n\n    for (size_t tx = 0; tx < count; ++tx)\n    {\n        const auto tx_hash = block_result.transaction_hash(tx);\n        const auto tx_result = transactions.get(tx_hash);\n\n        //fix a bug ,synchronize block may destroy the database\n        /*if (!tx_result) {\n            continue;\n        }*/\n\n        BITCOIN_ASSERT(tx_result);\n        BITCOIN_ASSERT(tx_result.height() == height);\n        BITCOIN_ASSERT(tx_result.index() == static_cast<size_t>(tx));\n\n        // TODO: the deserialization should cache the hash on the tx.\n        // Deserialize the transaction and move it to the block.\n        txs.emplace_back(tx_result.transaction());\n    }\n\n    // Loop txs backwards, the reverse of how they are added.\n    // Remove txs, then outputs, then inputs (also reverse order).\n    for (auto tx = txs.rbegin(); tx != txs.rend(); ++tx)\n    {\n        transactions.remove(tx->hash());\n        pop_outputs(tx->outputs, height);\n\n        if (!tx->is_strict_coinbase())\n            pop_inputs(tx->inputs, height);\n    }\n\n    // Stealth unlink is not implemented.\n    stealth.unlink(height);\n    blocks.unlink(height);\n    blocks.remove(block.header.hash()); // wdy remove block from block hash table\n\n    // Synchronise everything that was changed.\n    synchronize();\n\n    // Return the block.\n    return block;\n}\n\nvoid data_base::pop_inputs(const input::list &inputs, size_t height)\n{\n    // Loop in reverse.\n    for (auto input = inputs.rbegin(); input != inputs.rend(); ++input)\n    {\n        spends.remove(input->previous_output);\n\n        if (height < history_height_)\n            continue;\n\n        // Try to extract an address.\n        const auto address = payment_address::extract(input->script);\n\n        if (address)\n        {\n            history.delete_last_row(address.hash());\n            // delete address token record\n            auto address_str = address.encoded();\n            data_chunk data(address_str.begin(), address_str.end());\n            short_hash hash = ripemd160_hash(data);\n            address_tokens.delete_last_row(hash);\n        }\n    }\n}\n\nvoid data_base::pop_outputs(const output::list &outputs, size_t height)\n{\n    if (height < history_height_)\n        return;\n\n    // Loop in reverse.\n    for (auto output = outputs.rbegin(); output != outputs.rend(); ++output)\n    {\n        // Try to extract an address.\n        const auto address = payment_address::extract(output->script);\n\n        if (address)\n        {\n            history.delete_last_row(address.hash());\n            // delete address token record\n            auto address_str = address.encoded();\n            data_chunk data(address_str.begin(), address_str.end());\n            short_hash hash = ripemd160_hash(data);\n            bc::chain::output op = *output;\n            // NOTICE: pop only the pushed row, at present uid and candidate is\n            // not stored in address_token, but stored separately\n            // in address_uid and address_uid\n            if (!op.is_uid() && !op.is_candidate())\n            {\n                address_tokens.delete_last_row(hash);\n            }\n            // remove token or uid from database\n            if (op.is_token_issue() || op.is_token_secondaryissue())\n            {\n                auto symbol = op.get_token_symbol();\n                const data_chunk &symbol_data = data_chunk(symbol.begin(), symbol.end());\n                const auto symbol_hash = sha256_hash(symbol_data);\n                tokens.remove(symbol_hash);\n            }\n            else if (op.is_uid())\n            {\n                auto symbol = op.get_uid_symbol();\n                const data_chunk &symbol_data = data_chunk(symbol.begin(), symbol.end());\n                const auto symbol_hash = sha256_hash(symbol_data);\n\n                if (op.is_uid_register())\n                {\n                    address_uids.delete_last_row(hash);\n                    address_uids.sync();\n                    uids.remove(symbol_hash);\n                    uids.sync();\n                }\n                else if (op.is_uid_transfer())\n                {\n                    std::shared_ptr<blockchain_uid> blockchain_uid_ = uids.pop_uid_transfer(symbol_hash);\n                    uids.sync();\n\n                    if (blockchain_uid_)\n                    {\n                        auto old_address = blockchain_uid_->get_uid().get_address();\n                        data_chunk data_old(old_address.begin(), old_address.end());\n                        short_hash old_hash = ripemd160_hash(data_old);\n\n                        address_uids.delete_last_row(old_hash);\n                        address_uids.delete_last_row(hash);\n\n                        address_uids.store_output(old_hash, blockchain_uid_->get_tx_point(), blockchain_uid_->get_height(), 0,\n                                                  static_cast<typename std::underlying_type<business_kind>::type>(business_kind::uid_register),\n                                                  timestamp_, blockchain_uid_->get_uid());\n                        address_uids.sync();\n                    }\n                }\n            }\n            else if (op.is_token_cert())\n            {\n                const auto token_cert = op.get_token_cert();\n                if (token_cert.is_newly_generated())\n                {\n                    const auto key_str = token_cert.get_key();\n                    const data_chunk &data = data_chunk(key_str.begin(), key_str.end());\n                    const auto key_hash = sha256_hash(data);\n                    certs.remove(key_hash);\n                }\n            }\n            else if (op.is_candidate())\n            {\n\n                const auto candidate = op.get_candidate();\n                auto symbol = candidate.get_symbol();\n                const data_chunk &symbol_data = data_chunk(symbol.begin(), symbol.end());\n\n                const auto symbol_short_hash = ripemd160_hash(symbol_data);\n                candidate_history.delete_last_row(symbol_short_hash);\n\n                if (candidate.is_register_status())\n                {\n                    const auto symbol_hash = sha256_hash(symbol_data);\n                    candidates.remove(symbol_hash);\n                }\n            }\n        }\n    }\n}\n\n/* begin store token related info into database */\n#include <UChain/coin/config/base16.hpp>\nusing namespace libbitcoin::config;\n\nvoid data_base::push_asset(const asset &attach, const payment_address &address,\n                           const output_point &outpoint, uint32_t output_height, uint64_t value)\n{\n    auto address_str = address.encoded();\n    log::trace(LOG_DATABASE) << \"push_asset address_str=\" << address_str;\n    log::trace(LOG_DATABASE) << \"push_asset address hash=\" << base16(address.hash());\n    data_chunk data(address_str.begin(), address_str.end());\n    short_hash hash = ripemd160_hash(data);\n    auto visitor = asset_visitor(this, hash, outpoint, output_height, value,\n                                 attach.get_from_uid(), attach.get_to_uid());\n    boost::apply_visitor(visitor, const_cast<asset &>(attach).get_attach());\n}\n\nvoid data_base::push_ucn(const ucn &ucn, const short_hash &key,\n                         const output_point &outpoint, uint32_t output_height, uint64_t value)\n{\n    address_tokens.store_output(key, outpoint, output_height, value,\n                                static_cast<typename std::underlying_type<business_kind>::type>(business_kind::ucn),\n                                timestamp_, ucn);\n    address_tokens.sync();\n}\n\nvoid data_base::push_ucn_award(const ucn_award &award, const short_hash &key,\n                               const output_point &outpoint, uint32_t output_height, uint64_t value)\n{\n    address_tokens.store_output(key, outpoint, output_height, value,\n                                static_cast<typename std::underlying_type<business_kind>::type>(business_kind::ucn_award),\n                                timestamp_, award);\n    address_tokens.sync();\n}\n\nvoid data_base::push_message(const chain::blockchain_message &msg, const short_hash &key,\n                             const output_point &outpoint, uint32_t output_height, uint64_t value)\n{\n    address_tokens.store_output(key, outpoint, output_height, value,\n                                static_cast<typename std::underlying_type<business_kind>::type>(business_kind::message),\n                                timestamp_, msg);\n    address_tokens.sync();\n}\n\nvoid data_base::push_token(const token &sp, const short_hash &key,\n                           const output_point &outpoint, uint32_t output_height, uint64_t value) // sp = smart property\n{\n    auto visitor = token_visitor(this, key, outpoint, output_height, value);\n    boost::apply_visitor(visitor, const_cast<token &>(sp).get_data());\n}\n\nvoid data_base::push_token_cert(const token_cert &sp_cert, const short_hash &key,\n                                const output_point &outpoint, uint32_t output_height, uint64_t value)\n{\n    if (sp_cert.is_newly_generated())\n    {\n        certs.store(sp_cert);\n        certs.sync();\n    }\n    address_tokens.store_output(key, outpoint, output_height, value,\n                                static_cast<typename std::underlying_type<business_kind>::type>(business_kind::token_cert),\n                                timestamp_, sp_cert);\n    address_tokens.sync();\n}\n\nvoid data_base::push_token_detail(const token_detail &sp_detail, const short_hash &key,\n                                  const output_point &outpoint, uint32_t output_height, uint64_t value)\n{\n    const data_chunk &data = data_chunk(sp_detail.get_symbol().begin(), sp_detail.get_symbol().end());\n    const auto hash = sha256_hash(data);\n    auto bc_token = blockchain_token(0, outpoint, output_height, sp_detail);\n    tokens.store(hash, bc_token);\n    tokens.sync();\n    address_tokens.store_output(key, outpoint, output_height, value,\n                                static_cast<typename std::underlying_type<business_kind>::type>(business_kind::token_issue),\n                                timestamp_, sp_detail);\n    address_tokens.sync();\n}\n\nvoid data_base::push_token_transfer(const token_transfer &sp_transfer, const short_hash &key,\n                                    const output_point &outpoint, uint32_t output_height, uint64_t value)\n{\n    address_tokens.store_output(key, outpoint, output_height, value,\n                                static_cast<typename std::underlying_type<business_kind>::type>(business_kind::token_transfer),\n                                timestamp_, sp_transfer);\n    address_tokens.sync();\n}\n/* end store token related info into database */\n\n/* begin store uid related info into database */\nvoid data_base::push_uid(const uid &sp, const short_hash &key,\n                         const output_point &outpoint, uint32_t output_height, uint64_t value) // sp = smart property\n{\n    push_uid_detail(sp.get_data(), key, outpoint, output_height, value);\n}\n\nvoid data_base::push_uid_detail(const uid_detail &sp_detail, const short_hash &key,\n                                const output_point &outpoint, uint32_t output_height, uint64_t value)\n{\n    const data_chunk &data = data_chunk(sp_detail.get_symbol().begin(), sp_detail.get_symbol().end());\n    const auto hash = sha256_hash(data);\n    auto bc_uid = blockchain_uid(0, outpoint, output_height, blockchain_uid::address_current, sp_detail);\n    uids.store(hash, bc_uid);\n    uids.sync();\n    address_uids.store_output(key, outpoint, output_height, value,\n                              static_cast<typename std::underlying_type<business_kind>::type>(business_kind::uid_register),\n                              timestamp_, sp_detail);\n    address_uids.sync();\n}\n\n/* end store uid related info into database */\n\n/* begin store candidate related info into database */\nvoid data_base::push_candidate(const candidate &candidate, const short_hash &key,\n                               const output_point &outpoint, uint32_t output_height, uint64_t value,\n                               const std::string from_uid, std::string to_uid)\n{\n    candidate_info candidate_info{output_height, timestamp_, 0, to_uid, candidate};\n\n    if (candidate.is_register_status())\n    {\n        candidates.store(candidate_info);\n        candidates.sync();\n    }\n    if (candidate.is_transfer_status())\n    {\n        candidates.store(candidate_info);\n        candidates.sync();\n        candidate_history.update_address_status(candidate_info, CANDIDATE_STATUS_HISTORY);\n    }\n    candidate_info.candidate.set_status(CANDIDATE_STATUS_CURRENT);\n    candidate_history.store(candidate_info);\n    candidate_history.sync();\n}\n/* end store candidate related info into database */\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/database/memory/accessor.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/database/memory/accessor.hpp>\n\n#include <cstdint>\n#include <cstddef>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n#ifdef REMAP_SAFETY\n\naccessor::accessor(shared_mutex &mutex, uint8_t *&data)\n    : mutex_(mutex)\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Begin Critical Section\n\n    // Acquire shared lock.\n    mutex_.lock_shared();\n\n    BITCOIN_ASSERT_MSG(data != nullptr, \"Invalid pointer value.\");\n\n    // Save protected pointer.\n    data_ = data;\n}\n\nuint8_t *accessor::buffer()\n{\n    return data_;\n}\n\nvoid accessor::increment(size_t value)\n{\n    BITCOIN_ASSERT((size_t)data_ <= bc::max_size_t - value);\n    data_ += value;\n}\n\naccessor::~accessor()\n{\n    // Release shared lock.\n    mutex_.unlock_shared();\n\n    // End Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n#endif // REMAP_SAFETY\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/database/memory/allocator.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/database/memory/allocator.hpp>\n\n#include <cstdint>\n#include <cstddef>\n#include <UChain/coin.hpp>\n#include <UChain/database/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n#ifdef REMAP_SAFETY\n\nallocator::allocator(shared_mutex &mutex)\n    : mutex_(mutex),\n      data_(nullptr)\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Begin Critical Section\n\n    // Acquire exclusive downgradable lock.\n    mutex_.lock();\n}\n\nuint8_t *allocator::buffer()\n{\n    BITCOIN_ASSERT_MSG(data_ != nullptr, \"Downgrade must be called.\");\n    return data_;\n}\n\nvoid allocator::increment(size_t value)\n{\n    BITCOIN_ASSERT((size_t)data_ <= bc::max_size_t - value);\n    data_ += value;\n}\n\n// protected/friend\nvoid allocator::downgrade(uint8_t *data)\n{\n    BITCOIN_ASSERT_MSG(data != nullptr, \"Invalid pointer value.\");\n\n    // Downgrade the exclusive lock.\n    mutex_.unlock_and_lock_shared();\n\n    // Save protected pointer.\n    data_ = data;\n}\n\nallocator::~allocator()\n{\n    // Release downgraded (shared) lock.\n    mutex_.unlock_shared();\n\n    // End Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n#endif // REMAP_SAFETY\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/database/memory/memory_map.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/database/memory/memory_map.hpp>\n\n#include <iostream>\n\n#ifdef _WIN32\n#include <io.h>\n#ifdef __MINGW32__\n#include \"../mman-mingw/mman.h\"\n#else\n#include \"../mman-win32/mman.h\"\n#endif\n#define FILE_OPEN_PERMISSIONS _S_IREAD | _S_IWRITE\n#else\n#include <unistd.h>\n#include <stddef.h>\n#include <sys/mman.h>\n#define FILE_OPEN_PERMISSIONS S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH\n#endif\n#include <cstddef>\n#include <cstdint>\n#include <fcntl.h>\n#include <memory>\n#include <stdexcept>\n#include <string>\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/memory/accessor.hpp>\n#include <UChain/database/memory/allocator.hpp>\n#include <UChain/database/memory/memory.hpp>\n\n// memory_map is be able to support 32 bit but because the database\n// requires a larger file this is not validated or supported.\n#ifndef __ANDROID__\nstatic_assert(sizeof(void *) == sizeof(uint64_t), \"Not a 64 bit system!\");\n#endif\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nusing boost::filesystem::path;\n\n#define EXPANSION_NUMERATOR 150\n#define EXPANSION_DENOMINATOR 100\n\nsize_t memory_map::file_size(int file_handle)\n{\n    if (file_handle == -1)\n        return 0;\n\n        // This is required because off_t is defined as long, whcih is 32 bits in\n        // msvc and 64 bits in linux/osx, and stat contains off_t.\n#ifdef _WIN32\n#ifdef _WIN64\n    struct _stat64 sbuf;\n    if (_fstat64(file_handle, &sbuf) == -1)\n        return 0;\n#else\n    struct _stat32 sbuf;\n    if (_fstat32(file_handle, &sbuf) == -1)\n        return 0;\n#endif\n#else\n    struct stat sbuf;\n    if (fstat(file_handle, &sbuf) == -1)\n        return 0;\n#endif\n\n    // Convert signed to unsigned size.\n    BITCOIN_ASSERT_MSG(sbuf.st_size > 0, \"File size cannot be 0 bytes.\");\n    return static_cast<size_t>(sbuf.st_size);\n}\n\nint memory_map::open_file(const path &filename)\n{\n#ifdef _WIN32\n    int handle = _wopen(filename.wstring().c_str(), O_RDWR,\n                        FILE_OPEN_PERMISSIONS);\n#else\n    int handle = open(filename.string().c_str(), O_RDWR,\n                      FILE_OPEN_PERMISSIONS);\n#endif\n    return handle;\n}\n\nbool memory_map::handle_error(const std::string &context,\n                              const path &filename)\n{\n#ifdef _WIN32\n    const auto error = GetLastError();\n#else\n    const auto error = errno;\n#endif\n    log::fatal(LOG_DATABASE)\n        << \"The file failed to \" << context << \": \"\n        << filename << \" : \" << error;\n    return false;\n}\n\nvoid memory_map::log_mapping()\n{\n    log::debug(LOG_DATABASE)\n        << \"Mapping: \" << filename_ << \" [\" << file_size_\n        << \"] (\" << page() << \")\";\n}\n\nvoid memory_map::log_resizing(size_t size)\n{\n    log::debug(LOG_DATABASE)\n        << \"Resizing: \" << filename_ << \" [\" << size << \"]\";\n}\n\nvoid memory_map::log_unmapped()\n{\n    log::debug(LOG_DATABASE)\n        << \"Unmapped: \" << filename_ << \" [\" << logical_size_ << \"]\";\n}\n\n// mmap documentation: tinyurl.com/hnbw8t5\nmemory_map::memory_map(const path &filename)\n    : file_handle_(open_file(filename)),\n      filename_(filename),\n      data_(nullptr),\n      file_size_(file_size(file_handle_)),\n      logical_size_(file_size_),\n      closed_(true),\n      stopped_(true)\n{\n}\n\nmemory_map::memory_map(const path &filename, mutex_ptr mutex)\n    : memory_map(filename)\n{\n    remap_mutex_ = mutex;\n}\n\n// Database threads must be joined before close is called (or destruct).\nmemory_map::~memory_map()\n{\n    close();\n}\n\n// Startup and shutdown.\n// ----------------------------------------------------------------------------\n\n// Map the database file and signal start.\nbool memory_map::start()\n{\n    // Critical Section (internal/unconditional)\n    ///////////////////////////////////////////////////////////////////////////\n    mutex_.lock_upgrade();\n\n    if (!stopped_)\n    {\n        mutex_.unlock_upgrade();\n        //---------------------------------------------------------------------\n        // Start is not idempotent (should be called on single thread).\n        return false;\n    }\n\n    mutex_.unlock_upgrade_and_lock();\n    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n    std::string error_name;\n\n    // Initialize data_.\n    if (!map(file_size_))\n        error_name = \"map\";\n    else if (madvise(data_, 0, MADV_RANDOM) == -1)\n        error_name = \"madvise\";\n    else\n    {\n        closed_ = false;\n        stopped_ = false;\n    }\n\n    mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n\n    // Keep logging out of the critical section.\n    if (!error_name.empty())\n        return handle_error(error_name, filename_);\n\n    log_mapping();\n    return true;\n}\n\nbool memory_map::stop()\n{\n    // Critical Section (internal/unconditional)\n    ///////////////////////////////////////////////////////////////////////////\n    mutex_.lock_upgrade();\n\n    if (stopped_)\n    {\n        mutex_.unlock_upgrade();\n        //---------------------------------------------------------------------\n        // Stop is idempotent (may be called from multiple threads).\n        return true;\n    }\n\n    mutex_.unlock_upgrade_and_lock();\n    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n    stopped_ = true;\n\n    mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n\n    return true;\n}\n\n// Close does not call stop because there is no way to detect thread join.\nbool memory_map::close()\n{\n    std::string error_name;\n\n    // Critical Section (internal/unconditional)\n    ///////////////////////////////////////////////////////////////////////////\n    mutex_.lock_upgrade();\n\n    if (closed_)\n    {\n        mutex_.unlock_upgrade();\n        //---------------------------------------------------------------------\n        // Close is idempotent (may be called from multiple threads).\n        return true;\n    }\n\n    mutex_.unlock_upgrade_and_lock();\n    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n\n    closed_ = true;\n\n    if (msync(data_, logical_size_, MS_SYNC) == -1)\n        error_name = \"msync\";\n    else if (munmap(data_, file_size_) == -1)\n        error_name = \"munmap\";\n    else if (ftruncate(file_handle_, logical_size_) == -1)\n        error_name = \"ftruncate\";\n    else if (fsync(file_handle_) == -1)\n        error_name = \"fsync\";\n    else if (::close(file_handle_) == -1)\n        error_name = \"close\";\n\n    mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n\n    // Keep logging out of the critical section.\n    if (!error_name.empty())\n        return handle_error(error_name, filename_);\n\n    log_unmapped();\n    return true;\n}\n\nbool memory_map::stopped() const\n{\n    // Critical Section (internal/unconditional)\n    ///////////////////////////////////////////////////////////////////////////\n    shared_lock lock(mutex_);\n\n    return stopped_;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n// Operations.\n// ----------------------------------------------------------------------------\n\nsize_t memory_map::size() const\n{\n    // Critical Section (internal)\n    ///////////////////////////////////////////////////////////////////////////\n    REMAP_READ(mutex_);\n\n    return file_size_;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n// throws runtime_error\nmemory_ptr memory_map::access()\n{\n    return REMAP_ACCESSOR(data_, mutex_);\n}\n\n// throws runtime_error\nmemory_ptr memory_map::resize(size_t size)\n{\n    return reserve(size, EXPANSION_DENOMINATOR);\n}\n\n// throws runtime_error\nmemory_ptr memory_map::reserve(size_t size)\n{\n    return reserve(size, EXPANSION_NUMERATOR);\n}\n\n// throws runtime_error\n// There is no way to gracefully recover from a resize failure because there\n// are integrity relationships across multiple database files. Stopping a write\n// in one would require rolling back preceding write operations in others.\n// To handle this situation without database corruption would require predicting\n// the required allocation and all resizing before writing a block.\nmemory_ptr memory_map::reserve(size_t size, size_t expansion)\n{\n    // Critical Section (internal)\n    ///////////////////////////////////////////////////////////////////////////\n    const auto memory = REMAP_ALLOCATOR(mutex_);\n\n    if (size > file_size_)\n    {\n        const auto target = size * expansion / EXPANSION_DENOMINATOR;\n\n        if (!truncate_mapped(target))\n        {\n            handle_error(\"resize\", filename_);\n            throw std::runtime_error(\"Resize failure, disk space may be low.\");\n        }\n    }\n\n    logical_size_ = size;\n    REMAP_DOWNGRADE(memory, data_);\n\n    return memory;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n// privates\n// ----------------------------------------------------------------------------\n\nsize_t memory_map::page()\n{\n#ifdef _WIN32\n    SYSTEM_INFO configuration;\n    GetSystemInfo(&configuration);\n    return configuration.dwPageSize;\n#else\n    errno = 0;\n    const auto page_size = sysconf(_SC_PAGESIZE);\n\n    // -1 is both a return code and a potentially valid value, so use errno.\n    if (errno != 0)\n        handle_error(\"sysconf\", filename_);\n\n    BITCOIN_ASSERT(static_cast<size_t>(page_size) <= max_size_t);\n    return static_cast<size_t>(page_size == -1 ? 0 : page_size);\n#endif\n}\n\nbool memory_map::unmap()\n{\n    const auto success = (munmap(data_, file_size_) != -1);\n    file_size_ = 0;\n    data_ = nullptr;\n    return success;\n}\n\nbool memory_map::map(size_t size)\n{\n    if (size == 0)\n        return false;\n\n    data_ = reinterpret_cast<uint8_t *>(mmap(0, size, PROT_READ | PROT_WRITE,\n                                             MAP_SHARED, file_handle_, 0));\n\n    return validate(size);\n}\n\nbool memory_map::remap(size_t size)\n{\n#ifdef MREMAP_MAYMOVE\n    data_ = reinterpret_cast<uint8_t *>(mremap(data_, file_size_, size,\n                                               MREMAP_MAYMOVE));\n\n    return validate(size);\n#else\n    return unmap() && map(size);\n#endif\n}\n\nbool memory_map::truncate(size_t size)\n{\n    return ftruncate(file_handle_, size) != -1;\n}\n\nbool memory_map::truncate_mapped(size_t size)\n{\n    log_resizing(size);\n\n    // Critical Section (conditional/external)\n    ///////////////////////////////////////////////////////////////////////////\n    conditional_lock lock(remap_mutex_);\n\n#ifndef MREMAP_MAYMOVE\n    if (!unmap())\n        return false;\n#endif\n\n    if (!truncate(size))\n        return false;\n\n#ifndef MREMAP_MAYMOVE\n    return map(size);\n#else\n    return remap(size);\n#endif\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nbool memory_map::validate(size_t size)\n{\n    if (data_ == MAP_FAILED)\n    {\n        file_size_ = 0;\n        data_ = nullptr;\n        return false;\n    }\n\n    file_size_ = size;\n    return true;\n}\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/database/mman-mingw/mman.c",
    "content": "/* mman-win32 from code.google.com/p/mman-win32 (MIT License). */\n\n#include \"mman.h\"\n\n#ifdef _WIN32\n\n#include <stdint.h>\n#include <windows.h>\n#include <errno.h>\n#include <io.h>\n\n#ifndef FILE_MAP_EXECUTE\n#define FILE_MAP_EXECUTE 0x0020\n#endif\n\n/* private functions */\n\nstatic int error(const DWORD err, const int deferr)\n{\n    if (err == 0)\n        return 0;\n\n    /* TODO: implement. */\n\n    return err;\n}\n\nstatic DWORD protect_page(const int prot)\n{\n    DWORD protect = 0;\n\n    if (prot == PROT_NONE)\n        return protect;\n\n    if ((prot & PROT_EXEC) != 0)\n    {\n        protect = ((prot & PROT_WRITE) != 0) ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;\n    }\n    else\n    {\n        protect = ((prot & PROT_WRITE) != 0) ? PAGE_READWRITE : PAGE_READONLY;\n    }\n\n    return protect;\n}\n\nstatic DWORD protect_file(const int prot)\n{\n    DWORD desired_access = 0;\n\n    if (prot == PROT_NONE)\n        return desired_access;\n\n    if ((prot & PROT_READ) != 0)\n        desired_access |= FILE_MAP_READ;\n\n    if ((prot & PROT_WRITE) != 0)\n        desired_access |= FILE_MAP_WRITE;\n\n    if ((prot & PROT_EXEC) != 0)\n        desired_access |= FILE_MAP_EXECUTE;\n\n    return desired_access;\n}\n\n/* public interface */\n\nvoid *mmap(void *addr, size_t len, int prot, int flags, int fildes, oft__ off)\n{\n#ifdef _MSC_VER\n#pragma warning(push)\n#pragma warning(disable : 4293)\n#endif\n\n    const DWORD access = protect_file(prot);\n    const DWORD protect = protect_page(prot);\n\n    const oft__ max = off + (oft__)len;\n    const int less = (sizeof(oft__) <= sizeof(DWORD));\n\n    const DWORD max_lo = less ? (DWORD)max : (DWORD)((max)&MAXDWORD);\n    const DWORD max_hi = less ? (DWORD)0 : (DWORD)((max >> 32) & MAXDWORD);\n    const DWORD file_lo = less ? (DWORD)off : (DWORD)((off)&MAXDWORD);\n    const DWORD file_hi = less ? (DWORD)0 : (DWORD)((off >> 32) & MAXDWORD);\n\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n\n    errno = 0;\n\n    if (len == 0 || (flags & MAP_FIXED) != 0 || prot == PROT_EXEC)\n    {\n        errno = EINVAL;\n        return MAP_FAILED;\n    }\n\n    const HANDLE handle = ((flags & MAP_ANONYMOUS) == 0) ? (HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE;\n\n    if ((flags & MAP_ANONYMOUS) == 0 && handle == INVALID_HANDLE_VALUE)\n    {\n        errno = EBADF;\n        return MAP_FAILED;\n    }\n\n    const HANDLE mapping = CreateFileMapping(handle, NULL, protect, max_hi,\n                                             max_lo, NULL);\n\n    if (mapping == NULL)\n    {\n        errno = error(GetLastError(), EPERM);\n        return MAP_FAILED;\n    }\n\n    const LPVOID map = MapViewOfFile(mapping, access, file_hi, file_lo, len);\n\n    /* TODO: verify mapping handle may be closed here and then use the map. */\n    if (map == NULL || CloseHandle(mapping) == FALSE)\n    {\n        errno = error(GetLastError(), EPERM);\n        return MAP_FAILED;\n    }\n\n    return map;\n}\n\nint munmap(void *addr, size_t len)\n{\n    if (UnmapViewOfFile(addr) != FALSE)\n        return 0;\n\n    errno = error(GetLastError(), EPERM);\n    return -1;\n}\n\nint madvise(void *addr, size_t len, int advice)\n{\n\n#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)\n    PrefetchVirtualMemory(GetCurrentProcess(), len, addr, 0);\n#endif\n    return 0;\n}\n\nint mprotect(void *addr, size_t len, int prot)\n{\n    DWORD old_protect = 0;\n    const DWORD new_protect = protect_page(prot);\n\n    if (VirtualProtect(addr, len, new_protect, &old_protect) != FALSE)\n        return 0;\n\n    errno = error(GetLastError(), EPERM);\n    return -1;\n}\n\nint msync(void *addr, size_t len, int flags)\n{\n    if (FlushViewOfFile(addr, len) != FALSE)\n        return 0;\n\n    errno = error(GetLastError(), EPERM);\n    return -1;\n}\n\nint mlock(const void *addr, size_t len)\n{\n    if (VirtualLock((LPVOID)addr, len) != FALSE)\n        return 0;\n\n    errno = error(GetLastError(), EPERM);\n    return -1;\n}\n\nint munlock(const void *addr, size_t len)\n{\n    if (VirtualUnlock((LPVOID)addr, len) != FALSE)\n        return 0;\n\n    errno = error(GetLastError(), EPERM);\n    return -1;\n}\n\n/* Calling fsync() does not necessarily ensure that the entry in the directory\n   containing the file has also reached disk. For that an explicit fsync() on\n   a file descriptor for the directory is also needed. */\nint fsync(int fd)\n{\n    const HANDLE handle = (HANDLE)(_get_osfhandle(fd));\n\n    if (FlushFileBuffers(handle) != FALSE)\n        return 0;\n\n    errno = error(GetLastError(), EPERM);\n    return -1;\n}\n\n/* www.gitorious.org/git-win32/mainline/source/9ae6b7513158e0b1523766c9ad4a1ad286a96e2c:win32/ftruncate.c */\nint ftruncate(int fd, oft__ size)\n{\n    LARGE_INTEGER big;\n\n    if (fd < 0)\n        return -1;\n\n    /* guard against overflow from unsigned to signed */\n    if (size >= MAXINT64)\n        return -1;\n\n    /* unsigned to signed, splits to high and low */\n    big.QuadPart = (LONGLONG)size;\n\n    const HANDLE handle = (HANDLE)_get_osfhandle(fd);\n    const BOOL ret = SetFilePointerEx(handle, big, NULL, FILE_BEGIN);\n\n    if (!ret || !SetEndOfFile(handle))\n    {\n        const DWORD error = GetLastError();\n\n        switch (error)\n        {\n        case ERROR_INVALID_HANDLE:\n            errno = EBADF;\n            break;\n        case ERROR_DISK_FULL:\n            errno = ENOSPC;\n            break;\n        default:\n            errno = EIO;\n            break;\n        }\n\n        return -1;\n    }\n\n    return 0;\n}\n\n#endif\n"
  },
  {
    "path": "src/UChain/database/mman-mingw/mman.h",
    "content": "\n/* mman-win32 from code.google.com/p/mman-win32 (MIT License). */\n\n#ifndef UC_DATABASE_MMAN_H\n#define UC_DATABASE_MMAN_H\n\n#ifdef _WIN32\n\n/* DO NOT USE off_t/_off_t AS THE SIZE VARIES. */\n#include <stddef.h>\ntypedef size_t oft__;\n\n/* mman-win32 from code.google.com/p/mman-win32 (MIT License). */\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n#define PROT_NONE 0\n#define PROT_READ 1\n#define PROT_WRITE 2\n#define PROT_EXEC 4\n\n#define MAP_FILE 0\n#define MAP_SHARED 1\n#define MAP_PRIVATE 2\n#define MAP_TYPE 0xf\n#define MAP_FIXED 0x10\n#define MAP_ANONYMOUS 0x20\n#define MAP_ANON MAP_ANONYMOUS\n\n#define MAP_FAILED ((void *)-1)\n\n/* Flags for msync. */\n#define MS_ASYNC 1\n#define MS_SYNC 2\n#define MS_INVALIDATE 4\n\n/* Flags for madvise (stub). */\n#define MADV_RANDOM 0\n\n    void *mmap(void *addr, size_t len, int prot, int flags, int fildes, oft__ off);\n    int munmap(void *addr, size_t len);\n    int madvise(void *addr, size_t len, int advice);\n    int mprotect(void *addr, size_t len, int prot);\n    int msync(void *addr, size_t len, int flags);\n    int mlock(const void *addr, size_t len);\n    int munlock(const void *addr, size_t len);\n    int fsync(int fd);\n    int ftruncate(int fd, oft__ size);\n\n#ifdef __cplusplus\n};\n#endif\n\n#else\ntypedef int make_iso_compiler_not_complain;\n#endif\n\n#endif\n"
  },
  {
    "path": "src/UChain/database/mman-win32/mman.c",
    "content": "/* mman-win32 from code.google.com/p/mman-win32 (MIT License). */\n\n#include \"mman.h\"\n\n#ifdef _WIN32\n\n#include <stdint.h>\n#include <windows.h>\n#include <errno.h>\n#include <io.h>\n\n#ifndef FILE_MAP_EXECUTE\n#define FILE_MAP_EXECUTE 0x0020\n#endif\n\n/* private functions */\n\nstatic int error(const DWORD err, const int deferr)\n{\n    if (err == 0)\n        return 0;\n\n    /* TODO: implement. */\n\n    return err;\n}\n\nstatic DWORD protect_page(const int prot)\n{\n    DWORD protect = 0;\n\n    if (prot == PROT_NONE)\n        return protect;\n\n    if ((prot & PROT_EXEC) != 0)\n    {\n        protect = ((prot & PROT_WRITE) != 0) ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;\n    }\n    else\n    {\n        protect = ((prot & PROT_WRITE) != 0) ? PAGE_READWRITE : PAGE_READONLY;\n    }\n\n    return protect;\n}\n\nstatic DWORD protect_file(const int prot)\n{\n    DWORD desired_access = 0;\n\n    if (prot == PROT_NONE)\n        return desired_access;\n\n    if ((prot & PROT_READ) != 0)\n        desired_access |= FILE_MAP_READ;\n\n    if ((prot & PROT_WRITE) != 0)\n        desired_access |= FILE_MAP_WRITE;\n\n    if ((prot & PROT_EXEC) != 0)\n        desired_access |= FILE_MAP_EXECUTE;\n\n    return desired_access;\n}\n\n/* public interface */\n\nvoid *mmap(void *addr, size_t len, int prot, int flags, int fildes, oft__ off)\n{\n#ifdef _MSC_VER\n#pragma warning(push)\n#pragma warning(disable : 4293)\n#endif\n\n    const DWORD access = protect_file(prot);\n    const DWORD protect = protect_page(prot);\n\n    const oft__ max = off + (oft__)len;\n    const int less = (sizeof(oft__) <= sizeof(DWORD));\n\n    const DWORD max_lo = less ? (DWORD)max : (DWORD)((max)&MAXDWORD);\n    const DWORD max_hi = less ? (DWORD)0 : (DWORD)((max >> 32) & MAXDWORD);\n    const DWORD file_lo = less ? (DWORD)off : (DWORD)((off)&MAXDWORD);\n    const DWORD file_hi = less ? (DWORD)0 : (DWORD)((off >> 32) & MAXDWORD);\n\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n\n    errno = 0;\n\n    if (len == 0 || (flags & MAP_FIXED) != 0 || prot == PROT_EXEC)\n    {\n        errno = EINVAL;\n        return MAP_FAILED;\n    }\n\n    const HANDLE handle = ((flags & MAP_ANONYMOUS) == 0) ? (HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE;\n\n    if ((flags & MAP_ANONYMOUS) == 0 && handle == INVALID_HANDLE_VALUE)\n    {\n        errno = EBADF;\n        return MAP_FAILED;\n    }\n\n    const HANDLE mapping = CreateFileMapping(handle, NULL, protect, max_hi,\n                                             max_lo, NULL);\n\n    if (mapping == NULL)\n    {\n        errno = error(GetLastError(), EPERM);\n        return MAP_FAILED;\n    }\n\n    const LPVOID map = MapViewOfFile(mapping, access, file_hi, file_lo, len);\n\n    /* TODO: verify mapping handle may be closed here and then use the map. */\n    if (map == NULL || CloseHandle(mapping) == FALSE)\n    {\n        errno = error(GetLastError(), EPERM);\n        return MAP_FAILED;\n    }\n\n    return map;\n}\n\nint munmap(void *addr, size_t len)\n{\n    if (UnmapViewOfFile(addr) != FALSE)\n        return 0;\n\n    errno = error(GetLastError(), EPERM);\n    return -1;\n}\n\nint madvise(void *addr, size_t len, int advice)\n{\n    /* Not implemented. */\n    return 0;\n}\n\nint mprotect(void *addr, size_t len, int prot)\n{\n    DWORD old_protect = 0;\n    const DWORD new_protect = protect_page(prot);\n\n    if (VirtualProtect(addr, len, new_protect, &old_protect) != FALSE)\n        return 0;\n\n    errno = error(GetLastError(), EPERM);\n    return -1;\n}\n\nint msync(void *addr, size_t len, int flags)\n{\n    if (FlushViewOfFile(addr, len) != FALSE)\n        return 0;\n\n    errno = error(GetLastError(), EPERM);\n    return -1;\n}\n\nint mlock(const void *addr, size_t len)\n{\n    if (VirtualLock((LPVOID)addr, len) != FALSE)\n        return 0;\n\n    errno = error(GetLastError(), EPERM);\n    return -1;\n}\n\nint munlock(const void *addr, size_t len)\n{\n    if (VirtualUnlock((LPVOID)addr, len) != FALSE)\n        return 0;\n\n    errno = error(GetLastError(), EPERM);\n    return -1;\n}\n\n/* Calling fsync() does not necessarily ensure that the entry in the directory\n   containing the file has also reached disk. For that an explicit fsync() on\n   a file descriptor for the directory is also needed. */\nint fsync(int fd)\n{\n    const HANDLE handle = (HANDLE)(_get_osfhandle(fd));\n\n    if (FlushFileBuffers(handle) != FALSE)\n        return 0;\n\n    errno = error(GetLastError(), EPERM);\n    return -1;\n}\n\n/* www.gitorious.org/git-win32/mainline/source/9ae6b7513158e0b1523766c9ad4a1ad286a96e2c:win32/ftruncate.c */\nint ftruncate(int fd, oft__ size)\n{\n    LARGE_INTEGER big;\n\n    if (fd < 0)\n        return -1;\n\n    /* guard against overflow from unsigned to signed */\n    if (size >= MAXINT64)\n        return -1;\n\n    /* unsigned to signed, splits to high and low */\n    big.QuadPart = (LONGLONG)size;\n\n    const HANDLE handle = (HANDLE)_get_osfhandle(fd);\n    const BOOL ret = SetFilePointerEx(handle, big, NULL, FILE_BEGIN);\n\n    if (!ret || !SetEndOfFile(handle))\n    {\n        const DWORD error = GetLastError();\n\n        switch (error)\n        {\n        case ERROR_INVALID_HANDLE:\n            errno = EBADF;\n            break;\n        case ERROR_DISK_FULL:\n            errno = ENOSPC;\n            break;\n        default:\n            errno = EIO;\n            break;\n        }\n\n        return -1;\n    }\n\n    return 0;\n}\n\n#endif\n"
  },
  {
    "path": "src/UChain/database/mman-win32/mman.h",
    "content": "\n/* mman-win32 from code.google.com/p/mman-win32 (MIT License). */\n\n#ifndef UC_DATABASE_MMAN_H\n#define UC_DATABASE_MMAN_H\n\n#ifdef _WIN32\n\n/* DO NOT USE off_t/_off_t AS THE SIZE VARIES. */\n#include <stddef.h>\ntypedef size_t oft__;\n\n/* mman-win32 from code.google.com/p/mman-win32 (MIT License). */\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n#define PROT_NONE 0\n#define PROT_READ 1\n#define PROT_WRITE 2\n#define PROT_EXEC 4\n\n#define MAP_FILE 0\n#define MAP_SHARED 1\n#define MAP_PRIVATE 2\n#define MAP_TYPE 0xf\n#define MAP_FIXED 0x10\n#define MAP_ANONYMOUS 0x20\n#define MAP_ANON MAP_ANONYMOUS\n\n#define MAP_FAILED ((void *)-1)\n\n/* Flags for msync. */\n#define MS_ASYNC 1\n#define MS_SYNC 2\n#define MS_INVALIDATE 4\n\n/* Flags for madvise (stub). */\n#define MADV_RANDOM 0\n\n    void *mmap(void *addr, size_t len, int prot, int flags, int fildes, oft__ off);\n    int munmap(void *addr, size_t len);\n    int madvise(void *addr, size_t len, int advice);\n    int mprotect(void *addr, size_t len, int prot);\n    int msync(void *addr, size_t len, int flags);\n    int mlock(const void *addr, size_t len);\n    int munlock(const void *addr, size_t len);\n    int fsync(int fd);\n    int ftruncate(int fd, oft__ size);\n\n#ifdef __cplusplus\n};\n#endif\n\n#else\ntypedef int make_iso_compiler_not_complain;\n#endif\n\n#endif\n"
  },
  {
    "path": "src/UChain/database/primitives/record_list.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/database/primitives/record_list.hpp>\n\n#include <cstdint>\n#include <UChain/coin.hpp>\n#include <UChain/database/memory/memory.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n// std::numeric_limits<array_index>::max()\nconst array_index record_list::empty = bc::max_uint32;\n\nrecord_list::record_list(record_manager &manager)\n    : manager_(manager)\n{\n    static_assert(sizeof(array_index) == sizeof(uint32_t),\n                  \"array_index incorrect size\");\n}\n\narray_index record_list::create()\n{\n    // Insert new record with null next value.\n    return insert(empty);\n}\n\narray_index record_list::insert(array_index index)\n{\n    // Create new record and return its index.\n    auto new_index = manager_.new_records(1);\n    const auto memory = manager_.get(new_index);\n    auto serial = make_serializer(REMAP_ADDRESS(memory));\n    //*************************************************************************\n    serial.template write_little_endian<array_index>(index);\n    //*************************************************************************\n    return new_index;\n}\n\narray_index record_list::next(array_index index) const\n{\n    const auto memory = manager_.get(index);\n    const auto next_address = REMAP_ADDRESS(memory);\n    //*************************************************************************\n    return from_little_endian_unsafe<array_index>(next_address);\n    //*************************************************************************\n}\n\nconst memory_ptr record_list::get(array_index index) const\n{\n    auto memory = manager_.get(index);\n    REMAP_INCREMENT(memory, sizeof(array_index));\n    return memory;\n}\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/database/primitives/record_manager.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/database/primitives/record_manager.hpp>\n\n#include <cstddef>\n#include <stdexcept>\n#include <UChain/coin.hpp>\n#include <UChain/database/memory/memory.hpp>\n#include <UChain/database/memory/memory_map.hpp>\n\n/// -- file --\n/// [ header ]\n/// [ record_count ]\n/// [ payload ]\n\n/// -- header (hash table) --\n/// [ bucket ]\n/// ...\n/// [ bucket ]\n\n/// -- payload (fixed size records) --\n/// [ record ]\n/// ...\n/// [ record ]\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n// TODO: guard against overflows.\n\nrecord_manager::record_manager(memory_map &file, file_offset header_size,\n                               size_t record_size)\n    : file_(file),\n      header_size_(header_size),\n      record_count_(0),\n      record_size_(record_size)\n{\n}\n\nbool record_manager::create()\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    ALLOCATE_WRITE(mutex_);\n\n    // Existing file record count is nonzero.\n    if (record_count_ != 0)\n        return false;\n\n    // This currently throws if there is insufficient space.\n    file_.resize(header_size_ + record_to_position(record_count_));\n\n    write_count();\n    return true;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nbool record_manager::start()\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    ALLOCATE_WRITE(mutex_);\n\n    read_count();\n    const auto minimum = header_size_ + record_to_position(record_count_);\n\n    // Records size exceeds file size.\n    return minimum <= file_.size();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid record_manager::sync()\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    ALLOCATE_WRITE(mutex_);\n\n    write_count();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\narray_index record_manager::count() const\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    ALLOCATE_READ(mutex_);\n\n    return record_count_;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid record_manager::set_count(const array_index value)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    ALLOCATE_WRITE(mutex_);\n\n    BITCOIN_ASSERT(value <= record_count_);\n\n    record_count_ = value;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n// Return the next index, regardless of the number created.\n// The file is thread safe, the critical section is to protect record_count_.\narray_index record_manager::new_records(size_t count)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    ALLOCATE_WRITE(mutex_);\n\n    // Always write after the last index.\n    const auto next_record_index = record_count_;\n\n    const size_t position = record_to_position(record_count_ + count);\n    const size_t required_size = header_size_ + position;\n    file_.reserve(required_size);\n    record_count_ += count;\n\n    return next_record_index;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nconst memory_ptr record_manager::get(array_index record) const\n{\n    // If record >= count() then we should still be within the file. The\n    // condition implies a block has been popped between a guard and this read.\n    // The read will be invalidated and should not cause any other fault.\n\n    auto memory = file_.access();\n    REMAP_INCREMENT(memory, header_size_ + record_to_position(record));\n    return memory;\n}\n\n// privates\n\n// Read the count value from the first 32 bits of the file after the header.\nvoid record_manager::read_count()\n{\n    BITCOIN_ASSERT(header_size_ + sizeof(array_index) <= file_.size());\n\n    // The accessor must remain in scope until the end of the block.\n    const auto memory = file_.access();\n    const auto count_address = REMAP_ADDRESS(memory) + header_size_;\n    record_count_ = from_little_endian_unsafe<array_index>(count_address);\n}\n\n// Write the count value to the first 32 bits of the file after the header.\nvoid record_manager::write_count()\n{\n    BITCOIN_ASSERT(header_size_ + sizeof(array_index) <= file_.size());\n\n    // The accessor must remain in scope until the end of the block.\n    auto memory = file_.access();\n    auto payload_size_address = REMAP_ADDRESS(memory) + header_size_;\n    auto serial = make_serializer(payload_size_address);\n    serial.write_little_endian(record_count_);\n}\n\narray_index record_manager::position_to_record(file_offset position) const\n{\n    return (position - sizeof(array_index)) / record_size_;\n}\n\nfile_offset record_manager::record_to_position(array_index record) const\n{\n    return sizeof(array_index) + record * record_size_;\n}\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/database/primitives/record_multimap_iterable.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/database/primitives/record_multimap_iterable.hpp>\n\n#include <UChain/database/primitives/record_list.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nrecord_multimap_iterable::record_multimap_iterable(\n    const record_list &records, array_index begin)\n    : begin_(begin), records_(records)\n{\n}\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/database/primitives/record_multimap_iterator.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/database/primitives/record_multimap_iterator.hpp>\n\n#include <UChain/database/primitives/record_list.hpp>\n#include <UChain/database/primitives/record_multimap_iterable.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nrecord_multimap_iterator::record_multimap_iterator(const record_list &records,\n                                                   array_index index)\n    : index_(index), records_(records)\n{\n}\n\nvoid record_multimap_iterator::operator++()\n{\n    index_ = records_.next(index_);\n}\narray_index record_multimap_iterator::operator*() const\n{\n    return index_;\n}\n\nrecord_multimap_iterator record_multimap_iterable::begin() const\n{\n    return record_multimap_iterator(records_, begin_);\n}\nrecord_multimap_iterator record_multimap_iterable::end() const\n{\n    return record_multimap_iterator(records_, records_.empty);\n}\n\nbool record_multimap_iterator::operator==(record_multimap_iterator other) const\n{\n    return this->index_ == other.index_;\n}\n\nbool record_multimap_iterator::operator!=(record_multimap_iterator other) const\n{\n    return this->index_ != other.index_;\n}\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/database/primitives/slab_manager.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/database/primitives/slab_manager.hpp>\n\n#include <cstddef>\n#include <stdexcept>\n#include <UChain/coin.hpp>\n#include <UChain/database/memory/memory.hpp>\n#include <UChain/database/memory/memory_map.hpp>\n\n/// -- file --\n/// [ header ]\n/// [ payload_size ] (includes self)\n/// [ payload ]\n\n/// -- header (hash table) --\n/// [ bucket ]\n/// ...\n/// [ bucket ]\n\n/// -- payload (variable size records) --\n/// [ slab ]\n/// ...\n/// [ slab ]\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\n// TODO: guard against overflows.\n\nslab_manager::slab_manager(memory_map &file, file_offset header_size)\n    : file_(file),\n      header_size_(header_size),\n      payload_size_(sizeof(file_offset))\n{\n}\n\nbool slab_manager::create()\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    ALLOCATE_WRITE(mutex_);\n\n    // Existing slabs size is incorrect for new file.\n    if (payload_size_ != sizeof(file_offset))\n        return false;\n\n    // This currently throws if there is insufficient space.\n    file_.resize(header_size_ + payload_size_);\n\n    write_size();\n    return true;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nbool slab_manager::start()\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    ALLOCATE_WRITE(mutex_);\n\n    read_size();\n    const auto minimum = header_size_ + payload_size_;\n\n    // Slabs size exceeds file size.\n    return minimum <= file_.size();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid slab_manager::sync() const\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    ALLOCATE_WRITE(mutex_);\n\n    write_size();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n// protected\nfile_offset slab_manager::payload_size() const\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    ALLOCATE_READ(mutex_);\n\n    return payload_size_;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n// Return is offset by header but not size storage (embedded in data files).\n// The file is thread safe, the critical section is to protect payload_size_.\nfile_offset slab_manager::new_slab(size_t size)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    ALLOCATE_WRITE(mutex_);\n\n    // Always write after the last slab.\n    const auto next_slab_position = payload_size_;\n\n    const size_t required_size = header_size_ + payload_size_ + size;\n    file_.reserve(required_size);\n    payload_size_ += size;\n\n    return next_slab_position;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n// Position is offset by header but not size storage (embedded in data files).\nconst memory_ptr slab_manager::get(file_offset position) const\n{\n    // Ensure requested position is within the file.\n    // We avoid a runtime error here to optimize out the payload_size lock.\n    BITCOIN_ASSERT_MSG(position < payload_size(), \"Read past end of file.\");\n\n    auto memory = file_.access();\n    REMAP_INCREMENT(memory, header_size_ + position);\n    return memory;\n}\n\n// privates\n\n// Read the size value from the first 64 bits of the file after the header.\nvoid slab_manager::read_size()\n{\n    BITCOIN_ASSERT(header_size_ + sizeof(file_offset) <= file_.size());\n\n    // The accessor must remain in scope until the end of the block.\n    const auto memory = file_.access();\n    const auto payload_size_address = REMAP_ADDRESS(memory) + header_size_;\n    payload_size_ = from_little_endian_unsafe<file_offset>(\n        payload_size_address);\n}\n\n// Write the size value to the first 64 bits of the file after the header.\nvoid slab_manager::write_size() const\n{\n    BITCOIN_ASSERT(header_size_ + sizeof(file_offset) <= file_.size());\n\n    // The accessor must remain in scope until the end of the block.\n    const auto memory = file_.access();\n    const auto payload_size_address = REMAP_ADDRESS(memory) + header_size_;\n    auto serial = make_serializer(payload_size_address);\n    serial.write_little_endian(payload_size_);\n}\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/database/result/block_result.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/database/result/block_result.hpp>\n\n#include <cstdint>\n#include <cstddef>\n#include <UChain/coin.hpp>\n#include <UChain/database/memory/memory.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nusing namespace bc::chain;\n\nstatic constexpr size_t header_size = 76;\nstatic constexpr size_t height_size = sizeof(uint32_t);\nstatic constexpr size_t count_size = sizeof(uint32_t);\n\nblock_result::block_result(const memory_ptr slab)\n    : slab_(slab)\n{\n}\n\nblock_result::operator bool() const\n{\n    return slab_ != nullptr;\n}\n\nchain::header block_result::header() const\n{\n    BITCOIN_ASSERT(slab_);\n    chain::header header;\n    const auto memory = REMAP_ADDRESS(slab_);\n    auto deserial = make_deserializer_unsafe(memory);\n    header.from_data(deserial, false);\n    return header;\n    //// return deserialize_header(memory, size_limit_);\n}\n\nsize_t block_result::height() const\n{\n    BITCOIN_ASSERT(slab_);\n    const auto memory = REMAP_ADDRESS(slab_);\n    return from_little_endian_unsafe<uint32_t>(memory + header_size);\n}\n\nsize_t block_result::transaction_count() const\n{\n    BITCOIN_ASSERT(slab_);\n    const auto memory = REMAP_ADDRESS(slab_);\n    const auto offset = header_size + height_size;\n    return from_little_endian_unsafe<uint32_t>(memory + offset);\n}\n\nhash_digest block_result::transaction_hash(size_t index) const\n{\n    BITCOIN_ASSERT(slab_);\n    BITCOIN_ASSERT(index < transaction_count());\n    const auto memory = REMAP_ADDRESS(slab_);\n    const auto offset = header_size + height_size + count_size;\n    const auto first = memory + offset + index * hash_size;\n    auto deserial = make_deserializer_unsafe(first);\n    return deserial.read_hash();\n}\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/database/result/token_result.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/database/result/token_result.hpp>\n#include <UChainService/txs/token/token_detail.hpp>\n#include <cstddef>\n#include <cstdint>\n#include <UChain/coin.hpp>\n#include <UChain/database/memory/memory.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\ntemplate <typename Iterator>\nstd::shared_ptr<token_detail> deserialize_wallet_detail(const Iterator first)\n{\n    auto detail = std::make_shared<token_detail>();\n    auto deserial = make_deserializer_unsafe(first);\n    detail->from_data(deserial);\n    return detail;\n}\ntoken_result::token_result(const memory_ptr slab)\n    : base_result(slab)\n{\n}\n\nstd::shared_ptr<token_detail> token_result::get_token_detail() const\n{\n    //BITCOIN_ASSERT(get_slab());\n    std::shared_ptr<token_detail> sp_acc(nullptr);\n    if (get_slab())\n    {\n        const auto memory = REMAP_ADDRESS(get_slab());\n        sp_acc = deserialize_wallet_detail(memory);\n    }\n    return sp_acc;\n}\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/database/result/tx_result.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/database/result/tx_result.hpp>\n\n#include <cstddef>\n#include <cstdint>\n#include <UChain/coin.hpp>\n#include <UChain/database/memory/memory.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nusing namespace bc::chain;\n\nstatic constexpr size_t height_size = sizeof(uint32_t);\nstatic constexpr size_t index_size = sizeof(uint32_t);\n\ntemplate <typename Iterator>\nchain::transaction deserialize_tx(const Iterator first)\n{\n    chain::transaction tx;\n    auto deserial = make_deserializer_unsafe(first);\n    tx.from_data(deserial);\n    return tx;\n}\n\ntx_result::tx_result(const memory_ptr slab)\n    : slab_(slab)\n{\n}\n\ntx_result::operator bool() const\n{\n    return slab_ != nullptr;\n}\n\nsize_t tx_result::height() const\n{\n    BITCOIN_ASSERT(slab_);\n    const auto memory = REMAP_ADDRESS(slab_);\n    return from_little_endian_unsafe<uint32_t>(memory);\n}\n\nsize_t tx_result::index() const\n{\n    BITCOIN_ASSERT(slab_);\n    const auto memory = REMAP_ADDRESS(slab_);\n    return from_little_endian_unsafe<uint32_t>(memory + height_size);\n}\n\nchain::transaction tx_result::transaction() const\n{\n    BITCOIN_ASSERT(slab_);\n    const auto memory = REMAP_ADDRESS(slab_);\n    return deserialize_tx(memory + height_size + index_size);\n    //// return deserialize_tx(memory + 8, size_limit_ - 8);\n}\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/database/result/wallet_result.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/database/result/wallet_result.hpp>\n#include <UChainService/txs/wallet/wallet.hpp>\n#include <cstddef>\n#include <cstdint>\n#include <UChain/coin.hpp>\n#include <UChain/database/memory/memory.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\ntemplate <typename Iterator>\nstd::shared_ptr<libbitcoin::chain::wallet> deserialize_wallet_detail(const Iterator first)\n{\n    auto detail = std::make_shared<libbitcoin::chain::wallet>();\n    auto deserial = make_deserializer_unsafe(first);\n    detail->from_data(deserial);\n    return detail;\n}\nwallet_result::wallet_result(const memory_ptr slab)\n    : base_result(slab)\n{\n}\n\nstd::shared_ptr<libbitcoin::chain::wallet> wallet_result::get_wallet_detail() const\n{\n    //BITCOIN_ASSERT(get_slab());\n    std::shared_ptr<libbitcoin::chain::wallet> sp_acc(nullptr);\n    if (get_slab())\n    {\n        const auto memory = REMAP_ADDRESS(get_slab());\n        sp_acc = deserialize_wallet_detail(memory);\n    }\n    return sp_acc;\n}\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/database/result/wallet_token_result.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/database/result/wallet_token_result.hpp>\n#include <UChainService/txs/token/token_transfer.hpp>\n#include <cstddef>\n#include <cstdint>\n#include <UChain/coin.hpp>\n#include <UChain/database/memory/memory.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\ntemplate <typename Iterator>\ntoken_transfer deserialize_token_transfer(const Iterator first)\n{\n    token_transfer sp_detail;\n    auto deserial = make_deserializer_unsafe(first);\n    sp_detail.from_data(deserial);\n    return sp_detail;\n}\n\nwallet_token_result::wallet_token_result(const memory_ptr slab)\n    : base_result(slab)\n{\n}\n\ntoken_transfer wallet_token_result::get_wallet_token_transfer() const\n{\n    BITCOIN_ASSERT(get_slab());\n    const auto memory = REMAP_ADDRESS(get_slab());\n    return deserialize_token_transfer(memory);\n}\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/database/result/walllet_address_result.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/database/result/wallet_address_result.hpp>\n#include <UChainService/txs/wallet/wallet_address.hpp>\n#include <cstddef>\n#include <cstdint>\n#include <UChain/coin.hpp>\n#include <UChain/database/memory/memory.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\ntemplate <typename Iterator>\nstd::shared_ptr<wallet_address> deserialize_wallet_address_detail(const Iterator first)\n{\n    auto detail = std::make_shared<wallet_address>();\n    auto deserial = make_deserializer_unsafe(first);\n    detail->from_data(deserial);\n    return detail;\n}\n\nwallet_address_result::wallet_address_result(const memory_ptr slab)\n    : base_result(slab)\n{\n}\n\nstd::shared_ptr<wallet_address> wallet_address_result::get_wallet_address_detail() const\n{\n    //BITCOIN_ASSERT(get_slab());\n    std::shared_ptr<wallet_address> addr(nullptr);\n    if (get_slab())\n    {\n        const auto memory = REMAP_ADDRESS(get_slab());\n        addr = deserialize_wallet_address_detail(memory);\n    }\n    return addr;\n}\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/database/settings.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/database/settings.hpp>\n\n#include <boost/filesystem.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nusing namespace boost::filesystem;\n\nsettings::settings()\n    : history_start_height(0),\n      stealth_start_height(0),\n      directory(\"database\")\n{\n}\n\nsettings::settings(bc::settings context)\n    : settings()\n{\n    switch (context)\n    {\n    case bc::settings::mainnet:\n    {\n        stealth_start_height = 350000;\n        directory = default_directory = {\"mainnet\"};\n        break;\n    }\n\n    case bc::settings::testnet:\n    {\n        stealth_start_height = 500000;\n        directory = default_directory = {\"testnet\"};\n        break;\n    }\n\n    default:\n    case bc::settings::none:\n    {\n    }\n    }\n}\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/CMakeLists.txt",
    "content": "FILE(GLOB_RECURSE explorer_SOURCES \"*.cpp\")\n\nADD_DEFINITIONS(-DBCX_STATIC=1)\n\nSET(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations\")\n\nif(MINGW OR MSYS)\n\tFIND_PACKAGE(iphlpapi REQUIRED)\n\tADD_LIBRARY(iphlpapi_static STATIC IMPORTED)                                         \n\tSET_TARGET_PROPERTIES(iphlpapi_static PROPERTIES IMPORTED_LOCATION ${Iphlpapi_ROOT_DIR}/lib/libiphlpapi.a)\nENDIF()\n\nADD_LIBRARY(zmq_static STATIC IMPORTED)                                         \nSET_TARGET_PROPERTIES(zmq_static PROPERTIES IMPORTED_LOCATION ${ZeroMQ_ROOT_DIR}/lib/libzmq.a)\n\nADD_LIBRARY(explorer_static STATIC ${explorer_SOURCES})\nSET_TARGET_PROPERTIES(explorer_static PROPERTIES OUTPUT_NAME uc_explorer)\nif(MINGW OR MSYS)\n    TARGET_LINK_LIBRARIES(explorer_static iphlpapi_static)\nENDIF()\nTARGET_LINK_LIBRARIES(explorer_static zmq_static ${Boost_LIBRARIES}\n    ${txs_LIBRARY} ${api_LIBRARY} ${bitcoin_LIBRARY} ${network_LIBRARY} ${protocol_LIBRARY} ${client_LIBRARY}\n    ${blockchain_LIBRARY} ${jsoncpp_LIBRARY})\nINSTALL(TARGETS explorer_static DESTINATION lib)\n\nIF(ENABLE_SHARED_LIBS)\n    ADD_DEFINITIONS(-DBCX_DLL=1)\n  ADD_LIBRARY(explorer_shared SHARED ${explorer_SOURCES})\n  SET_TARGET_PROPERTIES(explorer_shared PROPERTIES OUTPUT_NAME uc_explorer)\n  TARGET_LINK_LIBRARIES(explorer_shared ${ZeroMQ_LIBRARIES} ${Boost_LIBRARIES} \n    ${txs_LIBRARY} ${api_LIBRARY} ${bitcoin_LIBRARY} ${network_LIBRARY} ${protocol_LIBRARY} ${client_LIBRARY} \n    ${blockchain_LIBRARY} ${jsoncpp_LIBRARY})\n  INSTALL(TARGETS explorer_shared DESTINATION lib)\nENDIF()\n"
  },
  {
    "path": "src/UChain/explorer/callback_state.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/callback_state.hpp>\n\n#include <iostream>\n#include <cstdint>\n#include <string>\n#include <boost/format.hpp>\n#include <UChain/explorer/config/encoding.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/utility.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\n\ncallback_state::callback_state(std::ostream &error, std::ostream &output,\n                               const encoding_engine engine)\n    : stopped_(true), refcount_(0), result_(console_result::okay),\n      engine_(engine), error_(error), output_(output)\n\n{\n}\n\ncallback_state::callback_state(std::ostream &error, std::ostream &output)\n    : callback_state(error, output, encoding_engine::info)\n{\n}\n\n// std::endl adds \"/n\" and flushes the stream.\nvoid callback_state::error(const Json::Value &tree)\n{\n    write_stream(error_, tree, engine_);\n}\n\n// std::endl adds \"/n\" and flushes the stream.\nvoid callback_state::error(const format &message)\n{\n    error_ << message;\n    error_.flush();\n}\n\nvoid callback_state::error(const std::string &message)\n{\n    error(format(message));\n}\n\nvoid callback_state::output(const Json::Value &tree)\n{\n    write_stream(output_, tree, engine_);\n}\n\n// std::endl adds \"/n\" and flushes the stream.\nvoid callback_state::output(const format &message)\n{\n    output_ << message;\n    output_.flush();\n}\n\nvoid callback_state::output(const std::string &message)\n{\n    output(format(message));\n}\n\nvoid callback_state::output(uint64_t value)\n{\n    output(format(\"%1%\") % value);\n}\n\nvoid callback_state::start()\n{\n    refcount_ = 1;\n    stopped_ = false;\n    result_ = console_result::okay;\n}\n\nvoid callback_state::stop(console_result result)\n{\n    refcount_ = 0;\n    stopped_ = true;\n    result_ = result;\n}\n\nbool &callback_state::stopped()\n{\n    return stopped_;\n}\n\nbool callback_state::succeeded(const code &ec, const std::string &format)\n{\n    if (ec)\n    {\n        // May want to change the behavior to decrement vs. zeroizing refs.\n        error(boost::format(format) % ec.message());\n        stop(console_result::failure);\n        return false;\n    }\n\n    return true;\n}\n\nencoding_engine callback_state::get_engine()\n{\n    return engine_;\n}\n\nconsole_result callback_state::get_result()\n{\n    return result_;\n}\n\nvoid callback_state::set_result(console_result result)\n{\n    result_ = result;\n}\n\nsize_t callback_state::increment()\n{\n    if (++refcount_ != 0)\n        stopped_ = false;\n\n    return refcount_;\n}\n\nsize_t callback_state::decrement()\n{\n    if (--refcount_ == 0)\n        stopped_ = true;\n\n    return refcount_;\n}\n\ncallback_state::operator size_t() const\n{\n    return refcount_;\n}\n\ncallback_state &callback_state::operator++()\n{\n    increment();\n    return *this;\n}\n\ncallback_state &callback_state::operator--()\n{\n    decrement();\n    return *this;\n}\n\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/commands/fetch-history.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/commands/fetch-history.hpp>\n\n#include <iostream>\n#include <UChain/client.hpp>\n#include <UChain/explorer/callback_state.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/display.hpp>\n#include <UChain/explorer/json_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::chain;\nusing namespace bc::client;\nusing namespace bc::explorer::config;\n\n// When you restore your wallet, you should use fetch_history().\n// But for updating the wallet, use the [new] scan() method-\n// which is faster because you avoid pulling the entire history.\n// We can eventually increase privacy and performance (fewer calls to scan())\n// by 'mining' addresses with the same prefix, allowing us to fetch the\n// prefix group. Obelisk will eventually support privacy enhanced history for\n// address scan by prefix.\nconsole_result fetch_history::invoke(std::ostream &output, std::ostream &error)\n{\n    // Bound parameters.\n    const auto &encoding = get_format_option();\n    const auto &address = get_payment_address_argument();\n    const auto connection = get_connection(*this);\n\n    obelisk_client client(connection);\n\n    if (!client.connect(connection))\n    {\n        display_connection_failure(error, connection.server);\n        return console_result::failure;\n    }\n\n    callback_state state(error, output, encoding);\n\n    // This enables json-style array formatting.\n    const auto json = encoding == encoding_engine::json;\n\n    auto on_done = [&state, json](const history::list &rows) {\n        state.output(json_helper().prop_tree(rows, json));\n    };\n\n    auto on_error = [&state](const code &error) {\n        state.succeeded(error);\n    };\n\n    // The v3 client API works with and normalizes either server API.\n    //// client.address_fetch_history(on_error, on_done, address);\n    /* client.address_fetch_history2(on_error, on_done, address); */\n    client.address_fetch_history2(on_error, on_done, address);\n    client.wait();\n\n    return state.get_result();\n}\n\n} //namespace commands\n} //namespace explorer\n} //namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/commands/fetch-stealth.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/commands/fetch-stealth.hpp>\n\n#include <iostream>\n#include <UChain/client.hpp>\n#include <UChain/explorer/callback_state.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/display.hpp>\n#include <UChain/explorer/json_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::chain;\nusing namespace bc::client;\nusing namespace bc::explorer::config;\nusing namespace bc::wallet;\n\nconsole_result fetch_stealth::invoke(std::ostream &output, std::ostream &error)\n{\n    // Bound parameters.\n    const auto height = get_height_option();\n    const auto &encoding = get_format_option();\n    const auto &filter = get_filter_argument();\n    const auto connection = get_connection(*this);\n\n    obelisk_client client(connection);\n\n    if (!client.connect(connection))\n    {\n        display_connection_failure(error, connection.server);\n        return console_result::failure;\n    }\n\n    if (filter.size() > stealth_address::max_filter_bits)\n    {\n        error << BX_FETCH_STEALTH_FILTER_TOO_LONG << std::flush;\n        return console_result::failure;\n    }\n\n    callback_state state(error, output, encoding);\n\n    // This enables json-style array formatting.\n    const auto json = encoding == encoding_engine::json;\n\n    auto on_done = [&state, json](const stealth::list &list) {\n        // Write out the transaction hashes of *potential* matches.\n        state.output(json_helper().prop_tree(list, json));\n    };\n\n    auto on_error = [&state](const std::error_code &error) {\n        state.succeeded(error);\n    };\n\n    client.blockchain_fetch_stealth(on_error, on_done, filter, height);\n    client.wait();\n\n    return state.get_result();\n}\n\n} //namespace commands\n} //namespace explorer\n} //namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/commands/help.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/commands/help.hpp>\n\n#include <iostream>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/display.hpp>\n#include <UChain/explorer/generated.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nconsole_result help::invoke(std::ostream &output, std::ostream &error)\n{\n    // Bound parameters.\n    const auto &symbol = get_command_argument();\n\n    if (symbol.empty())\n    {\n        display_usage(output);\n        return console_result::okay;\n    }\n\n    auto command = find(symbol);\n    if (!command)\n    {\n        display_invalid_command(error, symbol);\n        return console_result::failure;\n    }\n\n    command->load_options();\n    command->load_arguments();\n    command->write_help(output);\n    return console_result::okay;\n}\n\n} //namespace commands\n} //namespace explorer\n} //namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/commands/offline/stealth-decode.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/commands/stealth-decode.hpp>\n\n#include <iostream>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/utility.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\nconsole_result stealth_decode::invoke(std::ostream &output,\n                                      std::ostream &error)\n{\n    // Bound parameters.\n    const auto &encoding = get_format_option();\n    const auto &address = get_stealth_address_argument();\n\n    // This enables json-style array formatting.\n    const auto json = encoding == encoding_engine::json;\n\n    write_stream(output, json_helper().prop_tree(address, json), encoding);\n    return console_result::okay;\n}\n\n} //namespace commands\n} //namespace explorer\n} //namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/commands/offline/stealth-encode.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/commands/stealth-encode.hpp>\n\n#include <algorithm>\n#include <cstddef>\n#include <iostream>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::wallet;\n\nconsole_result stealth_encode::invoke(std::ostream &output,\n                                      std::ostream &error)\n{\n    // Bound parameters.\n    const auto version = get_version_option();\n    const auto &filter = get_filter_option();\n    const auto &scan_pubkey = get_scan_pubkey_argument();\n    const auto &spend_pubkeys = get_spend_pubkeys_argument();\n    const auto &signatures = get_signatures_option();\n\n    const size_t maximum = std::max(size_t(1), spend_pubkeys.size());\n\n    if (signatures > maximum)\n    {\n        error << BX_STEALTH_ENCODE_SIGNATURES_OVERFLOW << std::flush;\n        return console_result::failure;\n    }\n\n    // TODO: finish stealth multisig implemetation.\n    // Issue a warning but don't prevent experimentation.\n    if (spend_pubkeys.size() > 1u)\n        error << BX_STEALTH_ENCODE_MULTISIG_NOT_SUPPORTED << std::flush;\n\n    if (filter.size() > stealth_address::max_filter_bits)\n    {\n        error << BX_STEALTH_ENCODE_FILTER_TOO_LONG << std::flush;\n        return console_result::failure;\n    }\n\n    const auto spend_points = cast<ec_public, ec_compressed>(spend_pubkeys);\n    const stealth_address address(filter, scan_pubkey, spend_points,\n                                  signatures, version);\n\n    output << address << std::flush;\n    return console_result::okay;\n}\n\n} //namespace commands\n} //namespace explorer\n} //namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/commands/offline/stealth-public.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/commands/stealth-public.hpp>\n\n#include <iostream>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::wallet;\n\n// This is nearly the same as ec-add.\nconsole_result stealth_public::invoke(std::ostream &output,\n                                      std::ostream &error)\n{\n    // Bound parameters.\n    const auto &spend_pubkey = get_spend_pubkey_argument();\n    const auto &shared_secret = get_shared_secret_argument();\n\n    ec_compressed sum(spend_pubkey);\n    if (!bc::ec_add(sum, shared_secret))\n    {\n        error << BX_STEALTH_PUBLIC_OUT_OF_RANGE << std::flush;\n        return console_result::failure;\n    }\n\n    output << ec_public(sum) << std::flush;\n    return console_result::okay;\n}\n\n} //namespace commands\n} //namespace explorer\n} //namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/commands/offline/stealth-secret.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/commands/stealth-secret.hpp>\n\n#include <iostream>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/config/ec_private.hpp>\n\n// This is nearly the same as ec-add-secrets.\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nconsole_result stealth_secret::invoke(std::ostream &output,\n                                      std::ostream &error)\n{\n    // Bound parameters.\n    const auto &scan_secret = get_spend_secret_argument();\n    const auto &shared_secret = get_shared_secret_argument();\n\n    ec_secret sum(scan_secret);\n    if (!bc::ec_add(sum, shared_secret))\n    {\n        error << BX_STEALTH_SECRET_OUT_OF_RANGE << std::flush;\n        return console_result::failure;\n    }\n\n    output << config::ec_private(sum) << std::flush;\n    return console_result::okay;\n}\n\n} //namespace commands\n} //namespace explorer\n} //namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/commands/offline/stealth-shared.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/commands/stealth-shared.hpp>\n\n#include <iostream>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\n// This is nearly the same as ec-multiply + sha256.\n// Pass either (ephem_secret, scan_pubkey) or (scan_secret, ephem_pubkey).\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nconsole_result stealth_shared::invoke(std::ostream &output,\n                                      std::ostream &error)\n{\n    // Bound parameters.\n    const auto &secret = get_secret_argument();\n    const auto &pubkey = get_pubkey_argument();\n\n    ec_compressed product(pubkey);\n    if (!bc::ec_multiply(product, secret))\n    {\n        error << BX_STEALTH_SHARED_OUT_OF_RANGE << std::flush;\n        return console_result::failure;\n    }\n\n    const auto hash = sha256_hash(product);\n\n    output << config::ec_private(hash) << std::flush;\n    return console_result::okay;\n}\n\n} //namespace commands\n} //namespace explorer\n} //namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/commands/offline/tx-decode.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/commands/tx-decode.hpp>\n\n#include <iostream>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/utility.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\nconsole_result tx_decode::invoke(std::ostream &output, std::ostream &error)\n{\n    // Bound parameters.\n    const auto &encoding = get_format_option();\n    const auto &transaction = get_transaction_argument();\n\n    // This enables json-style array formatting.\n    const auto json = encoding == encoding_engine::json;\n\n    write_stream(output, json_helper().prop_tree(transaction, json), encoding);\n\n    return console_result::okay;\n}\n\n} //namespace commands\n} //namespace explorer\n} //namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/commands/offline_commands_impl.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/commands/offline_commands_impl.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n//seed\ndata_chunk get_seed(uint16_t bit_length)\n{\n    // These are soft requirements for security and rationality.\n    // We use bit vs. byte length input as the more familiar convention.\n    if (bit_length < minimum_seed_size * byte_bits ||\n        bit_length % byte_bits != 0)\n    {\n        // - exception\n        throw seed_size_exception{UCCLI_SEED_BIT_LENGTH_UNSUPPORTED};\n    }\n\n    return new_seed(bit_length);\n}\n\n//mnemonic-new\nbw::word_list get_mnemonic_new(const bw::dictionary_list &language, const data_chunk &entropy)\n{\n    const auto entropy_size = entropy.size();\n\n    if ((entropy_size % bw::mnemonic_seed_multiple) != 0)\n    {\n        // - exception\n        throw seed_length_exception{UCCLI_EC_MNEMONIC_NEW_INVALID_ENTROPY};\n    }\n\n    // If 'any' default to first ('en'), otherwise the one specified.\n    const auto dictionary = language.front();\n    return bw::create_mnemonic(entropy, *dictionary);\n}\n\n//mnemonic-to-seed\ndata_chunk get_mnemonic_to_seed(const bw::dictionary_list &language,\n                                const bw::word_list &words,\n                                std::string passphrase)\n{\n    const auto word_count = words.size();\n\n    if (word_count == 0)\n    {\n        throw mnemonicwords_empty_exception{UCCLI_EC_MNEMONIC_TO_SEED_EMPTY_WORDS};\n    }\n\n    if ((word_count % bw::mnemonic_word_multiple) != 0)\n    {\n        // - exception\n        throw mnemonicwords_amount_exception{UCCLI_EC_MNEMONIC_TO_SEED_LENGTH_INVALID_SENTENCE};\n    }\n\n    // check if mnemonic words are all in someone/specified dictionary\n    bool all_word_in_dictionary = true;\n    for (const auto &lexicon : language)\n    {\n        all_word_in_dictionary = true;\n        for (const auto &word : words)\n        {\n            if (std::find(lexicon->begin(), lexicon->end(), word) == lexicon->end())\n            {\n                all_word_in_dictionary = false;\n                break;\n            }\n        }\n        if (all_word_in_dictionary)\n        {\n            break;\n        }\n    }\n    if (!all_word_in_dictionary)\n    {\n        throw mnemonicwords_content_exception{UCCLI_EC_MNEMONIC_TO_SEED_WORD_NOT_IN_DICTIONARY};\n    }\n\n    const auto valid = bw::validate_mnemonic(words, language);\n\n    if (!valid && language.size() == 1)\n    {\n        // This is fatal because a dictionary was specified explicitly.\n        // - exception\n        throw mnemonicwords_content_exception{UCCLI_EC_MNEMONIC_TO_SEED_INVALID_IN_LANGUAGE};\n    }\n\n    // - exception\n    if (!valid && language.size() > 1)\n        throw mnemonicwords_content_exception{UCCLI_EC_MNEMONIC_TO_SEED_INVALID_IN_LANGUAGES};\n\n#ifdef WITH_ICU\n    // Any word set divisible by 3 works regardless of language validation.\n    const auto seed = bw::decode_mnemonic(words, passphrase);\n#else\n    if (!passphrase.empty())\n    {\n        // - exception\n        throw mnemonicwords_content_exception{UCCLI_EC_MNEMONIC_TO_SEED_PASSPHRASE_UNSUPPORTED};\n    }\n\n    // The passphrase requires ICU normalization.\n    const auto seed = bw::decode_mnemonic(words);\n#endif\n\n    return bc::config::base16(seed);\n}\n\n//hd-new\nbw::hd_private get_hd_new(const data_chunk &seed, uint32_t version)\n{\n    if (seed.size() < minimum_seed_size)\n    {\n        // - exception\n        throw hd_length_exception{UCCLI_HD_NEW_SHORT_SEED};\n    }\n\n    // We require the private version, but public is unused here.\n    const auto prefixes = bc::wallet::hd_private::to_prefixes(version, 0);\n    const bc::wallet::hd_private private_key(seed, prefixes);\n\n    if (!private_key)\n    {\n        // - exception\n        throw hd_key_exception{UCCLI_HD_NEW_INVALID_KEY};\n    }\n\n    return private_key;\n}\n\n} //namespace commands\n} //namespace explorer\n} //namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/commands/send-tx.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/commands/send-tx.hpp>\n\n#include <iostream>\n#include <boost/format.hpp>\n#include <UChain/client.hpp>\n#include <UChain/explorer/callback_state.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/display.hpp>\n#include <UChain/explorer/utility.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::client;\n\nconsole_result send_tx::invoke(std::ostream &output, std::ostream &error)\n{\n    // Bound parameters.\n    const auto &transaction = get_transaction_argument();\n    const auto connection = get_connection(*this);\n\n    obelisk_client client(connection);\n\n    if (!client.connect(connection))\n    {\n        display_connection_failure(error, connection.server);\n        return console_result::failure;\n    }\n\n    callback_state state(error, output);\n\n    auto on_done = [&state]() {\n        state.output(std::string(BX_SEND_TX_OUTPUT));\n    };\n\n    auto on_error = [&state](const code &error) {\n        state.succeeded(error);\n    };\n\n    client.protocol_broadcast_transaction(on_error, on_done, transaction);\n    client.wait();\n\n    return state.get_result();\n}\n\n} //namespace commands\n} //namespace explorer\n} //namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/commands/settings.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/commands/help.hpp>\n\n#include <iostream>\n#include <map>\n#include <UChain/network.hpp>\n#include <UChain/explorer/commands/settings.hpp>\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/utility.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\nconsole_result commands::settings::invoke(std::ostream &output,\n                                          std::ostream &error)\n{\n    // bound parameters\n    const auto &encoding = get_format_option();\n\n    // TODO: look into serializer object quoting.\n    // TODO: load from metadata into settings list.\n\n    // This must be updated for any settings metadata change.\n    settings_list list;\n\n    // [wallet]\n    list[\"wallet.wif_version\"] =\n        serialize(get_wallet_wif_version_setting());\n    list[\"wallet.hd_public_version\"] =\n        serialize(get_wallet_hd_public_version_setting());\n    list[\"wallet.hd_secret_version\"] =\n        serialize(get_wallet_hd_secret_version_setting());\n    list[\"wallet.pay_to_public_key_hash_version\"] =\n        serialize(get_wallet_pay_to_public_key_hash_version_setting());\n    list[\"wallet.pay_to_script_hash_version\"] =\n        serialize(get_wallet_pay_to_script_hash_version_setting());\n    list[\"wallet.transaction_version\"] =\n        serialize(get_wallet_transaction_version_setting());\n\n    // [network]\n    list[\"network.identifier\"] =\n        serialize(get_network_identifier_setting());\n    list[\"network.connect_retries\"] =\n        serialize(get_network_connect_retries_setting());\n    list[\"network.connect_timeout_seconds\"] =\n        serialize(get_network_connect_timeout_seconds_setting());\n    list[\"network.channel_handshake_seconds\"] =\n        serialize(get_network_channel_handshake_seconds_setting());\n    list[\"network.hosts_file\"] =\n        get_network_hosts_file_setting().string();\n    list[\"network.debug_file\"] =\n        get_network_debug_file_setting().string();\n    list[\"network.error_file\"] =\n        get_network_error_file_setting().string();\n\n    network::settings settings(bc::settings::mainnet);\n    const auto &nodes = get_network_seeds_setting();\n    const auto &seeds = nodes.empty() ? settings.seeds : nodes;\n\n    std::vector<std::string> buffer;\n    for (const auto &node : seeds)\n        buffer.push_back(node.to_string());\n\n    list[\"network.seeds\"] = join(buffer, \",\");\n\n    // [server]\n    list[\"server.url\"] =\n        get_server_url_setting().to_string();\n    list[\"server.connect_retries\"] =\n        serialize(get_server_connect_retries_setting());\n    list[\"server.connect_timeout_seconds\"] =\n        serialize(get_server_connect_timeout_seconds_setting());\n    list[\"server.server_public_key\"] =\n        serialize(get_server_server_public_key_setting());\n    list[\"server.client_private_key\"] =\n        serialize(get_server_client_private_key_setting());\n\n    write_stream(output, json_helper().prop_tree(list), encoding);\n    return console_result::okay;\n}\n\n} //namespace commands\n} //namespace explorer\n} //namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/commands/validate-tx.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/commands/validate-tx.hpp>\n\n#include <iostream>\n#include <UChain/client.hpp>\n#include <UChain/explorer/callback_state.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/display.hpp>\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/utility.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::client;\nusing namespace bc::explorer::config;\n\nconsole_result validate_tx::invoke(std::ostream &output,\n                                   std::ostream &error)\n{\n    // Bound parameters.\n    const auto &transaction = get_transaction_argument();\n    const auto connection = get_connection(*this);\n\n    obelisk_client client(connection);\n\n    if (!client.connect(connection))\n    {\n        display_connection_failure(error, connection.server);\n        return console_result::failure;\n    }\n\n    callback_state state(error, output);\n\n    auto on_done = [&state](const chain::point::indexes &indexes) {\n        if (indexes.empty())\n        {\n            state.output(std::string(BX_VALIDATE_TX_VALID));\n            return;\n        }\n\n        const auto unconfirmed = join(numbers_to_strings(indexes), \", \");\n        state.output(format(BX_VALIDATE_TX_UNCONFIRMED_INPUTS) % unconfirmed);\n    };\n\n    auto on_error = [&state](const code &error) {\n        // BX_VALIDATE_TX_INVALID_INPUT is not currently utilized.\n        // The client suppresses an index list which may have 0 or one element.\n        // The list contains the index of the input which caused the failure.\n        state.succeeded(error);\n    };\n\n    client.tx_pool_validate(on_error, on_done, transaction);\n    client.wait();\n\n    return state.get_result();\n}\n\n} //namespace commands\n} //namespace explorer\n} //namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/config/address.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/config/address.hpp>\n\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\naddress::address(const std::string &base58)\n{\n    std::stringstream(base58) >> *this;\n}\n\naddress::operator const std::string &() const\n{\n    return value_;\n}\n\nstd::istream &operator>>(std::istream &input, address &argument)\n{\n    std::string base58;\n    input >> base58;\n\n    bc::wallet::payment_address payment(base58);\n    if (payment)\n    {\n        argument.value_ = base58;\n        return input;\n    }\n\n    bc::wallet::stealth_address stealth(base58);\n    if (stealth)\n    {\n        argument.value_ = base58;\n        return input;\n    }\n\n    using namespace boost::program_options;\n    BOOST_THROW_EXCEPTION(invalid_option_value(base58));\n}\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/config/algorithm.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/config/algorithm.hpp>\n\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\nusing namespace po;\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\nstatic auto algorithm_greedy = \"greedy\";\n\nalgorithm::algorithm()\n    : value_(bc::wallet::select_outputs::algorithm::greedy)\n{\n}\n\nalgorithm::algorithm(const std::string &token)\n{\n    std::stringstream(token) >> *this;\n}\n\nalgorithm::algorithm(bc::wallet::select_outputs::algorithm &algorithm)\n    : value_(algorithm)\n{\n}\n\nalgorithm::algorithm(const algorithm &other)\n    : value_(other.value_)\n{\n}\n\nalgorithm::operator const bc::wallet::select_outputs::algorithm() const\n{\n    return value_;\n}\n\nstd::istream &operator>>(std::istream &input, algorithm &argument)\n{\n    std::string text;\n    input >> text;\n\n    if (text == algorithm_greedy)\n        argument.value_ = bc::wallet::select_outputs::algorithm::greedy;\n    else\n        BOOST_THROW_EXCEPTION(invalid_option_value(text));\n\n    return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const algorithm &argument)\n{\n    std::string text;\n\n    if (argument.value_ == bc::wallet::select_outputs::algorithm::greedy)\n    {\n        text = algorithm_greedy;\n    }\n    else\n    {\n        BITCOIN_ASSERT_MSG(false, \"Unexpected encoding value.\");\n    }\n\n    output << text;\n    return output;\n}\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/config/btc.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/config/btc.hpp>\n\n#include <cstdint>\n#include <iostream>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\nusing namespace po;\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\nbtc::btc()\n    : value_(0)\n{\n}\n\nbtc::btc(const std::string &btc)\n{\n  std::stringstream(btc) >> *this;\n}\n\nbtc::btc(uint64_t satoshi)\n    : value_(satoshi)\n{\n}\n\nbtc::btc(const btc &other)\n    : value_(other.value_)\n{\n}\n\nbtc::operator uint64_t() const\n{\n  return value_;\n}\n\nstd::istream &operator>>(std::istream &input, btc &argument)\n{\n  std::string bitcoins;\n  input >> bitcoins;\n\n  if (!decode_base10(argument.value_, bitcoins, btc_decimal_places))\n  {\n    BOOST_THROW_EXCEPTION(invalid_option_value(bitcoins));\n  }\n\n  return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const btc &argument)\n{\n  std::string bitcoins;\n  bitcoins = encode_base10(argument.value_, btc_decimal_places);\n  output << bitcoins;\n  return output;\n}\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/config/byte.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/config/byte.hpp>\n\n#include <iostream>\n#include <string>\n#include <cstdint>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/utility.hpp>\n\nusing namespace po;\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\nbyte::byte()\n    : value_(0)\n{\n}\n\nbyte::byte(const std::string &decimal)\n{\n  std::stringstream(decimal) >> *this;\n}\n\nbyte::byte(uint8_t byte)\n    : value_(byte)\n{\n}\n\nbyte::byte(const byte &other)\n    : byte(other.value_)\n{\n}\n\nbyte::operator uint8_t() const\n{\n  return value_;\n}\n\nstd::istream &operator>>(std::istream &input, byte &argument)\n{\n  std::string decimal;\n  input >> decimal;\n\n  // We have this byte class only because deserialization doesn't\n  // treat 8 bit values as decimal numbers (unlike 16+ bit numbers).\n\n  uint16_t number;\n  deserialize(number, decimal, true);\n\n  if (number > max_uint8)\n  {\n    BOOST_THROW_EXCEPTION(invalid_option_value(decimal));\n  }\n\n  argument.value_ = static_cast<uint8_t>(number);\n  return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const byte &argument)\n{\n  uint16_t number(argument.value_);\n  output << number;\n  return output;\n}\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/config/cert_key.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/config/cert_key.hpp>\n\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <boost/program_options.hpp>\n#include <UChain/client.hpp>\n#include <UChain/explorer/define.hpp>\n\nusing namespace po;\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n//constexpr uint8_t cert_key_byte_size = 32;\nconstexpr uint8_t cert_key_string_length = 40;\n\ncert_key::cert_key()\n    : value_()\n{\n}\n\ncert_key::cert_key(const std::string &base85)\n{\n    std::stringstream(base85) >> *this;\n}\n\ncert_key::cert_key(const cert_key &other)\n    : value_(other.value_)\n{\n}\n\n// Returns empty string if not initialized.\nstd::string cert_key::get_base85() const\n{\n    std::stringstream base85;\n    base85 << *this;\n    return base85.str();\n}\n\ncert_key::operator const data_chunk &() const\n{\n    return value_;\n}\n\ncert_key::operator data_slice() const\n{\n    return value_;\n}\n\nstd::istream &operator>>(std::istream &input, cert_key &argument)\n{\n    std::string base85;\n    input >> base85;\n\n    if (base85.size() != cert_key_string_length ||\n        !decode_base85(argument.value_, base85))\n    {\n        BOOST_THROW_EXCEPTION(invalid_option_value(base85));\n    }\n\n    return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const cert_key &argument)\n{\n    std::string decoded;\n\n    // Z85 is unusual in that it requires four byte alignment.\n    // We have already guarded construction against this, so we can ignore here.\n    /* bool */ encode_base85(decoded, argument.value_);\n\n    output << decoded;\n    return output;\n}\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/config/ec_private.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/config/ec_private.hpp>\n\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\nusing namespace po;\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n// ec_secret base16 format is private to bx.\nstatic bool decode_secret(ec_secret &secret, const std::string &encoded)\n{\n    return decode_base16(secret, encoded) && verify(secret);\n}\n\nec_private::ec_private(const std::string &hexcode)\n{\n    std::stringstream(hexcode) >> *this;\n}\n\nec_private::ec_private(const ec_secret &secret)\n    : value_(secret)\n{\n}\n\nec_private::operator const ec_secret &() const\n{\n    return value_;\n}\n\nstd::istream &operator>>(std::istream &input, ec_private &argument)\n{\n    std::string hexcode;\n    input >> hexcode;\n\n    if (!decode_secret(argument.value_, hexcode))\n    {\n        BOOST_THROW_EXCEPTION(invalid_option_value(hexcode));\n    }\n\n    return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const ec_private &argument)\n{\n    output << encode_base16(argument.value_);\n    return output;\n}\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/config/encoding.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/config/encoding.hpp>\n\n#include <exception>\n#include <iostream>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\nusing namespace po;\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n// DRY\nstatic auto encoding_info = \"info\";\nstatic auto encoding_json = \"json\";\nstatic auto encoding_xml = \"xml\";\n\nencoding::encoding()\n    : encoding(encoding_engine::json)\n{\n}\n\nencoding::encoding(const std::string &token)\n{\n    std::stringstream(token) >> *this;\n}\n\nencoding::encoding(encoding_engine engine)\n    : value_(engine)\n{\n}\n\nencoding::encoding(const encoding &other)\n    : value_(other.value_)\n{\n}\n\nencoding::operator encoding_engine() const\n{\n    return value_;\n}\n\nstd::istream &operator>>(std::istream &input, encoding &argument)\n{\n    std::string text;\n    input >> text;\n\n    if (text == encoding_info)\n        argument.value_ = encoding_engine::info;\n    else if (text == encoding_json)\n        argument.value_ = encoding_engine::json;\n    else if (text == encoding_xml)\n        argument.value_ = encoding_engine::xml;\n    else\n    {\n        BOOST_THROW_EXCEPTION(invalid_option_value(text));\n    }\n\n    return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const encoding &argument)\n{\n    std::string value;\n\n    switch (argument.value_)\n    {\n    case encoding_engine::info:\n        value = encoding_info;\n        break;\n    case encoding_engine::json:\n        value = encoding_json;\n        break;\n    case encoding_engine::xml:\n        value = encoding_xml;\n        break;\n    default:\n        BITCOIN_ASSERT_MSG(false, \"Unexpected encoding value.\");\n    }\n\n    return output;\n}\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/config/endorsement.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/config/endorsement.hpp>\n\n#include <array>\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <cstdint>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\nusing namespace po;\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n// endorsement format is currently private to bx.\nstatic bool decode_endorsement(bc::endorsement &endorsement,\n                               const std::string &encoded)\n{\n    bc::endorsement decoded;\n    if (!decode_base16(decoded, encoded) ||\n        (decoded.size() > max_endorsement_size))\n        return false;\n\n    endorsement = decoded;\n    return true;\n}\n\nstatic std::string encode_endorsement(data_slice signature)\n{\n    return encode_base16(signature);\n}\n\nendorsement::endorsement()\n    : value_()\n{\n}\n\nendorsement::endorsement(const std::string &hexcode)\n{\n    std::stringstream(hexcode) >> *this;\n}\n\nendorsement::endorsement(const data_chunk &value)\n    : value_(value)\n{\n}\n\nendorsement::endorsement(const endorsement &other)\n    : endorsement(other.value_)\n{\n}\n\nendorsement::operator const data_chunk &() const\n{\n    return value_;\n}\n\nendorsement::operator data_slice() const\n{\n    return value_;\n}\n\nstd::istream &operator>>(std::istream &input, endorsement &argument)\n{\n    std::string hexcode;\n    input >> hexcode;\n\n    if (!decode_endorsement(argument.value_, hexcode))\n    {\n        BOOST_THROW_EXCEPTION(invalid_option_value(hexcode));\n    }\n\n    return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const endorsement &argument)\n{\n    output << encode_endorsement(argument.value_);\n    return output;\n}\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/config/hashtype.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/config/hashtype.hpp>\n\n#include <exception>\n#include <iostream>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\nusing namespace po;\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n// DRY\nstatic auto hashtype_all = \"all\";\nstatic auto hashtype_none = \"none\";\nstatic auto hashtype_single = \"single\";\n\nhashtype::hashtype()\n    : hashtype(chain::signature_hash_algorithm::all)\n{\n}\n\nhashtype::hashtype(const std::string &token)\n{\n    std::stringstream(token) >> *this;\n}\n\nhashtype::hashtype(const chain::signature_hash_algorithm &value)\n    : value_(value)\n{\n}\n\nhashtype::hashtype(const hashtype &other)\n    : value_(other.value_)\n{\n}\n\nhashtype::operator chain::signature_hash_algorithm() const\n{\n    return value_;\n}\n\nstd::istream &operator>>(std::istream &input, hashtype &argument)\n{\n    std::string text;\n    input >> text;\n\n    if (text == hashtype_all)\n        argument.value_ = chain::signature_hash_algorithm::all;\n    else if (text == hashtype_none)\n        argument.value_ = chain::signature_hash_algorithm::none;\n    else if (text == hashtype_single)\n        argument.value_ = chain::signature_hash_algorithm::single;\n    else\n    {\n        BOOST_THROW_EXCEPTION(invalid_option_value(text));\n    }\n\n    return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const hashtype &argument)\n{\n    std::string value;\n\n    switch (argument.value_)\n    {\n    case chain::signature_hash_algorithm::all:\n        value = hashtype_all;\n        break;\n    case chain::signature_hash_algorithm::none:\n        value = hashtype_none;\n        break;\n    case chain::signature_hash_algorithm::single:\n        value = hashtype_single;\n        break;\n    default:\n        BITCOIN_ASSERT_MSG(false, \"Unexpected signature hash type value.\");\n    }\n\n    return output;\n}\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/config/hd_key.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/config/hd_key.hpp>\n\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\nusing namespace po;\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\nhd_key::hd_key(const std::string &base58)\n{\n    std::stringstream(base58) >> *this;\n}\n\nuint32_t hd_key::version() const\n{\n    return from_big_endian_unsafe<uint32_t>(value_.begin());\n}\n\nhd_key::operator const bc::wallet::hd_key &() const\n{\n    return value_;\n}\n\nstd::istream &operator>>(std::istream &input, hd_key &argument)\n{\n    std::string base58;\n    input >> base58;\n\n    data_chunk value;\n    if (!decode_base58(value, base58) || value.size() != bc::wallet::hd_key_size)\n    {\n        BOOST_THROW_EXCEPTION(invalid_option_value(base58));\n    }\n\n    std::copy(value.begin(), value.end(), argument.value_.begin());\n    return input;\n}\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/config/header.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/config/header.hpp>\n\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/utility.hpp>\n\nusing namespace po;\nusing namespace bc::config;\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\nheader::header()\n    : value_()\n{\n}\n\nheader::header(const std::string &hexcode)\n{\n  std::stringstream(hexcode) >> *this;\n}\n\nheader::header(const chain::header &value)\n    : value_(value)\n{\n}\n\nheader::header(const header &other)\n    : header(other.value_)\n{\n}\n\nheader::operator const chain::header &() const\n{\n  return value_;\n}\n\nstd::istream &operator>>(std::istream &input, header &argument)\n{\n  std::string hexcode;\n  input >> hexcode;\n\n  // header base16 is a private encoding in bx, used to pass between commands.\n  if (!argument.value_.from_data(base16(hexcode), false))\n  {\n    BOOST_THROW_EXCEPTION(invalid_option_value(hexcode));\n  }\n\n  return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const header &argument)\n{\n  const auto bytes = argument.value_.to_data(false);\n\n  // header base16 is a private encoding in bx, used to pass between commands.\n  output << base16(bytes);\n  return output;\n}\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/config/input.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/config/input.hpp>\n\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <vector>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/config/point.hpp>\n#include <UChain/explorer/utility.hpp>\n\nusing namespace po;\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n// input is currently a private encoding in bx.\nstatic bool decode_input(tx_input_type &input, const std::string &tuple)\n{\n    const auto tokens = split(tuple, BX_TX_POINT_DELIMITER);\n    if (tokens.size() != 2 && tokens.size() != 3)\n        return false;\n\n    input.sequence = max_input_sequence;\n    input.previous_output = point(tokens[0] + \":\" + tokens[1]);\n\n    if (tokens.size() == 3)\n        deserialize(input.sequence, tokens[2], true);\n\n    return true;\n}\n\n// input is currently a private encoding in bx.\nstatic std::string encode_input(const tx_input_type &input)\n{\n    std::stringstream result;\n    result << point(input.previous_output) << BX_TX_POINT_DELIMITER << input.sequence;\n    return result.str();\n}\n\ninput::input()\n    : value_()\n{\n}\n\ninput::input(const std::string &tuple)\n{\n    std::stringstream(tuple) >> *this;\n}\n\ninput::input(const tx_input_type &value)\n    : value_(value)\n{\n}\n\ninput::input(const input &other)\n    : input(other.value_)\n{\n}\n\ninput::input(const chain::input_point &value)\n    : value_({value, {}, max_input_sequence})\n{\n}\n\ninput::operator const tx_input_type &() const\n{\n    return value_;\n}\n\nstd::istream &operator>>(std::istream &stream, input &argument)\n{\n    std::string tuple;\n    stream >> tuple;\n\n    if (!decode_input(argument.value_, tuple))\n    {\n        BOOST_THROW_EXCEPTION(invalid_option_value(tuple));\n    }\n\n    return stream;\n}\n\nstd::ostream &operator<<(std::ostream &output, const input &argument)\n{\n    output << encode_input(argument.value_);\n    return output;\n}\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/config/language.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/config/language.hpp>\n\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\nusing namespace po;\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n// DRY\nstatic auto language_en = \"en\";\nstatic auto language_es = \"es\";\nstatic auto language_ja = \"ja\";\nstatic auto language_zh_Hans = \"zh_Hans\";\nstatic auto language_zh_Hant = \"zh_Hant\";\nstatic auto language_any = \"any\";\n\nlanguage::language()\n    : value_(bc::wallet::language::all)\n{\n}\n\nlanguage::language(const std::string &token)\n{\n    std::stringstream(token) >> *this;\n}\n\nlanguage::language(bc::wallet::dictionary_list &languages)\n    : value_(languages)\n{\n}\n\nlanguage::language(const language &other)\n    : value_(other.value_)\n{\n}\n\nlanguage::operator const bc::wallet::dictionary_list() const\n{\n    return value_;\n}\n\nstd::istream &operator>>(std::istream &input, language &argument)\n{\n    std::string text;\n    input >> text;\n\n    argument.value_.clear();\n\n    if (text == language_any)\n        argument.value_.assign(bc::wallet::language::all.begin(),\n                               bc::wallet::language::all.end());\n    else if (text == language_en)\n        argument.value_.push_back(&bc::wallet::language::en);\n    else if (text == language_es)\n        argument.value_.push_back(&bc::wallet::language::es);\n    else if (text == language_ja)\n        argument.value_.push_back(&bc::wallet::language::ja);\n    else if (text == language_zh_Hans)\n        argument.value_.push_back(&bc::wallet::language::zh_Hans);\n    else if (text == language_zh_Hant)\n        argument.value_.push_back(&bc::wallet::language::zh_Hant);\n    else\n    {\n        BOOST_THROW_EXCEPTION(invalid_option_value(text));\n    }\n\n    return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const language &argument)\n{\n    std::string text;\n\n    if (argument.value_.size() > 1)\n        text = language_any;\n    else if (argument.value_.front() == &bc::wallet::language::en)\n        text = language_en;\n    else if (argument.value_.front() == &bc::wallet::language::es)\n        text = language_es;\n    else if (argument.value_.front() == &bc::wallet::language::ja)\n        text = language_ja;\n    else if (argument.value_.front() == &bc::wallet::language::zh_Hans)\n        text = language_zh_Hans;\n    else if (argument.value_.front() == &bc::wallet::language::zh_Hant)\n        text = language_zh_Hant;\n    else\n    {\n        BITCOIN_ASSERT_MSG(false, \"Unexpected encoding value.\");\n    }\n\n    output << text;\n    return output;\n}\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/config/output.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/config/output.hpp>\n\n#include <cstdint>\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <vector>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/config/script.hpp>\n#include <UChain/explorer/utility.hpp>\n\nusing namespace po;\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\noutput::output()\n    : amount_(0), version_(0), script_(), pay_to_hash_(null_short_hash),\n      ephemeral_data_({})\n{\n}\n\noutput::output(const std::string &tuple)\n    : output()\n{\n    std::stringstream(tuple) >> *this;\n}\n\nuint64_t output::amount() const\n{\n    return amount_;\n}\n\nuint8_t output::version() const\n{\n    return version_;\n}\n\nconst chain::script &output::script() const\n{\n    return script_;\n}\n\nconst short_hash &output::pay_to_hash() const\n{\n    return pay_to_hash_;\n}\n\nconst data_chunk &output::ephemeral_data() const\n{\n    return ephemeral_data_;\n}\n\nstd::istream &operator>>(std::istream &input, output &argument)\n{\n    std::string tuple;\n    input >> tuple;\n\n    const auto tokens = split(tuple, BX_TX_POINT_DELIMITER);\n    if (tokens.size() < 2 || tokens.size() > 3)\n    {\n        BOOST_THROW_EXCEPTION(invalid_option_value(tuple));\n    }\n\n    uint64_t amount;\n    deserialize(amount, tokens[1], true);\n    if (amount > max_money())\n    {\n        BOOST_THROW_EXCEPTION(invalid_option_value(tuple));\n    }\n\n    argument.amount_ = amount;\n    const auto &target = tokens.front();\n\n    // Is the target a payment address?\n    const bc::wallet::payment_address payment(target);\n    if (payment)\n    {\n        argument.version_ = payment.version();\n        argument.pay_to_hash_ = payment.hash();\n        return input;\n    }\n\n    // Is the target a stealth address?\n    const bc::wallet::stealth_address stealth(target);\n    if (stealth)\n    {\n        // TODO: finish stealth multisig implemetation (p2sh and !p2sh).\n\n        if (stealth.spend_keys().size() != 1 || tokens.size() != 3)\n        {\n            BOOST_THROW_EXCEPTION(invalid_option_value(target));\n        }\n\n        data_chunk seed;\n        if (!decode_base16(seed, tokens[2]) || seed.size() < minimum_seed_size)\n        {\n            BOOST_THROW_EXCEPTION(invalid_option_value(target));\n        }\n\n        ec_secret ephemeral_secret;\n        if (!create_stealth_data(argument.ephemeral_data_, ephemeral_secret,\n                                 stealth.filter(), seed))\n        {\n            BOOST_THROW_EXCEPTION(invalid_option_value(target));\n        }\n\n        ec_compressed stealth_key;\n        if (!uncover_stealth(stealth_key, stealth.scan_key(), ephemeral_secret,\n                             stealth.spend_keys().front()))\n        {\n            BOOST_THROW_EXCEPTION(invalid_option_value(target));\n        }\n\n        argument.pay_to_hash_ = bitcoin_short_hash(stealth_key);\n        argument.version_ = stealth.version();\n        return input;\n    }\n\n    // The target must be a serialized script.\n    data_chunk decoded;\n    if (!decode_base16(decoded, target))\n    {\n        BOOST_THROW_EXCEPTION(invalid_option_value(target));\n    }\n\n    argument.script_ = script(decoded);\n    return input;\n}\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/config/point.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/config/point.hpp>\n\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <vector>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/utility.hpp>\n\nusing namespace po;\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\nusing namespace bc::config;\n\n// point format is currently private to bx.\nstatic bool decode_point(chain::output_point &point, const std::string &tuple)\n{\n    const auto tokens = split(tuple, BX_TX_POINT_DELIMITER);\n    if (tokens.size() != 2)\n        return false;\n\n    // validate and deserialize the transaction hash\n    const hash256 digest(tokens[0]);\n    const hash_digest &txhash = digest;\n\n    // copy the input point values\n    std::copy(txhash.begin(), txhash.end(), point.hash.begin());\n    deserialize(point.index, tokens[1], true);\n\n    return true;\n}\n\n// point format is currently private to bx.\nstatic std::string encode_point(const chain::output_point &point)\n{\n    std::stringstream result;\n    result << hash256(point.hash) << BX_TX_POINT_DELIMITER << point.index;\n    return result.str();\n}\n\npoint::point()\n    : value_()\n{\n}\n\npoint::point(const std::string &tuple)\n{\n    std::stringstream(tuple) >> *this;\n}\n\npoint::point(const chain::output_point &value)\n    : value_(value)\n{\n}\n\npoint::point(const point &other)\n    : point(other.value_)\n{\n}\n\npoint::operator const chain::output_point &() const\n{\n    return value_;\n}\n\nstd::istream &operator>>(std::istream &input, point &argument)\n{\n    std::string tuple;\n    input >> tuple;\n\n    if (!decode_point(argument.value_, tuple))\n    {\n        BOOST_THROW_EXCEPTION(invalid_option_value(tuple));\n    }\n\n    return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const point &argument)\n{\n    output << encode_point(argument.value_);\n    return output;\n}\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/config/raw.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/config/raw.hpp>\n\n#include <iostream>\n#include <sstream>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\nraw::raw()\n    : value_()\n{\n}\n\nraw::raw(const std::string &hexcode)\n{\n  std::stringstream(hexcode) >> *this;\n}\n\nraw::raw(const data_chunk &value)\n    : value_(value)\n{\n}\n\nraw::raw(const raw &other)\n    : raw(other.value_)\n{\n}\n\nraw::operator const data_chunk &() const\n{\n  return value_;\n}\n\nraw::operator data_slice() const\n{\n  return value_;\n}\n\nstd::istream &operator>>(std::istream &input, raw &argument)\n{\n  std::istreambuf_iterator<char> first(input), last;\n  argument.value_.assign(first, last);\n  return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const raw &argument)\n{\n  std::ostreambuf_iterator<char> iterator(output);\n  std::copy(argument.value_.begin(), argument.value_.end(), iterator);\n  return output;\n}\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/config/script.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/config/script.hpp>\n\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <vector>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/utility.hpp>\n\nusing namespace po;\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\nscript::script()\n    : value_()\n{\n}\n\nscript::script(const std::string &mnemonic)\n{\n    std::stringstream(mnemonic) >> *this;\n}\n\nscript::script(const chain::script &value)\n    : value_(value)\n{\n}\n\nscript::script(const data_chunk &value)\n{\n    value_.from_data(value, false,\n                     chain::script::parse_mode::raw_data_fallback);\n}\n\nscript::script(const std::vector<std::string> &tokens)\n{\n    const auto mnemonic = join(tokens);\n    std::stringstream(mnemonic) >> *this;\n}\n\nscript::script(const script &other)\n    : script(other.value_)\n{\n}\n\nconst data_chunk script::to_data() const\n{\n    return value_.to_data(false);\n}\n\nconst std::string script::to_string() const\n{\n    static constexpr auto flags = chain::script_context::all_enabled;\n    return value_.to_string(flags);\n}\n\nscript::operator const chain::script &() const\n{\n    return value_;\n}\n\nstd::istream &operator>>(std::istream &input, script &argument)\n{\n    std::istreambuf_iterator<char> end;\n    std::string mnemonic(std::istreambuf_iterator<char>(input), end);\n    boost::trim(mnemonic);\n\n    // Test for invalid result sentinel.\n    if (!argument.value_.from_string(mnemonic) && mnemonic.length() > 0)\n    {\n        BOOST_THROW_EXCEPTION(invalid_option_value(mnemonic));\n    }\n\n    return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const script &argument)\n{\n    static constexpr auto flags = chain::script_context::all_enabled;\n    output << argument.value_.to_string(flags);\n    return output;\n}\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/config/signature.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/config/signature.hpp>\n\n#include <array>\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <cstdint>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n\nusing namespace po;\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\n// message_signature format is currently private to bx.\nstatic bool decode_signature(bc::wallet::message_signature &signature,\n                             const std::string &encoded)\n{\n    // There is no bc::decode_base64 array-based override.\n    data_chunk decoded;\n    if (!decode_base64(decoded, encoded) ||\n        (decoded.size() != bc::wallet::message_signature_size))\n        return false;\n\n    std::copy(decoded.begin(), decoded.end(), signature.begin());\n    return true;\n}\n\nstatic std::string encode_signature(const bc::wallet::message_signature &signature)\n{\n    return encode_base64(signature);\n}\n\nsignature::signature()\n    : value_()\n{\n}\n\nsignature::signature(const std::string &hexcode)\n{\n    std::stringstream(hexcode) >> *this;\n}\n\nsignature::signature(const bc::wallet::message_signature &value)\n    : value_(value)\n{\n}\n\nsignature::signature(const signature &other)\n    : signature(other.value_)\n{\n}\n\nsignature::operator const bc::wallet::message_signature &() const\n{\n    return value_;\n}\n\nstd::istream &operator>>(std::istream &input, signature &argument)\n{\n    std::string hexcode;\n    input >> hexcode;\n\n    if (!decode_signature(argument.value_, hexcode))\n    {\n        BOOST_THROW_EXCEPTION(invalid_option_value(hexcode));\n    }\n\n    return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const signature &argument)\n{\n    output << encode_signature(argument.value_);\n    return output;\n}\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/config/transaction.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/config/transaction.hpp>\n\n#include <iostream>\n#include <sstream>\n#include <string>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/utility.hpp>\n\nusing namespace po;\nusing namespace bc::config;\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\ntransaction::transaction()\n    : value_()\n{\n}\n\ntransaction::transaction(const std::string &hexcode)\n{\n  std::stringstream(hexcode) >> *this;\n}\n\ntransaction::transaction(const tx_type &value)\n    : value_(value)\n{\n}\n\ntransaction::transaction(const transaction &other)\n    : transaction(other.value_)\n{\n}\n\ntx_type &transaction::data()\n{\n  return value_;\n}\n\ntransaction::operator const tx_type &() const\n{\n  return value_;\n}\n\nstd::istream &operator>>(std::istream &input, transaction &argument)\n{\n  std::string hexcode;\n  input >> hexcode;\n\n  // tx base16 is a private encoding in bx, used to pass between commands.\n  if (!deserialize_satoshi_item(argument.value_, base16(hexcode)))\n  {\n    BOOST_THROW_EXCEPTION(invalid_option_value(hexcode));\n  }\n\n  return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const transaction &argument)\n{\n  // tx base16 is a private encoding in bx, used to pass between commands.\n  const auto bytes = serialize_satoshi_item(argument.value_);\n  output << base16(bytes);\n  return output;\n}\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/config/wrapper.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/config/wrapper.hpp>\n\n#include <iostream>\n#include <boost/program_options.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/utility.hpp>\n\nusing namespace po;\nusing namespace bc::config;\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\nwrapper::wrapper()\n    : value_()\n{\n}\n\nwrapper::wrapper(const std::string &wrapped)\n{\n  std::stringstream(wrapped) >> *this;\n}\n\nwrapper::wrapper(const data_chunk &wrapped)\n    : wrapper(encode_base16(wrapped))\n{\n}\n\nwrapper::wrapper(const bc::wallet::wrapped_data &wrapped)\n    : value_(wrapped)\n{\n}\n\nwrapper::wrapper(const bc::wallet::payment_address &address)\n    : wrapper(encode_base16(address.to_payment()))\n{\n}\n\nwrapper::wrapper(uint8_t version, const data_chunk &payload)\n    : wrapper(bc::wallet::wrapped_data{version, payload, 0})\n{\n}\n\nwrapper::wrapper(const wrapper &other)\n    : value_(other.value_)\n{\n}\n\nconst data_chunk wrapper::to_data() const\n{\n  return wrap(value_);\n}\n\nwrapper::operator const bc::wallet::wrapped_data &() const\n{\n  return value_;\n}\n\nstd::istream &operator>>(std::istream &input, wrapper &argument)\n{\n  std::string hexcode;\n  input >> hexcode;\n\n  // The checksum is validated here.\n  if (!unwrap(argument.value_, base16(hexcode)))\n  {\n    BOOST_THROW_EXCEPTION(invalid_option_value(hexcode));\n  }\n\n  return input;\n}\n\nstd::ostream &operator<<(std::ostream &output, const wrapper &argument)\n{\n  // The checksum is calculated here (value_ checksum is ignored).\n  const auto bytes = wrap(argument.value_);\n  output << base16(bytes);\n  return output;\n}\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/dispatch.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/dispatch.hpp>\n\n#include <iostream>\n#include <string>\n#include <boost/filesystem.hpp>\n#include <boost/program_options.hpp>\n#include <UChain/explorer/command.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/display.hpp>\n#include <UChain/explorer/generated.hpp>\n#include <UChain/explorer/parser.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChain/coin.hpp>\n\nusing namespace boost::filesystem;\nusing namespace boost::program_options;\nusing namespace boost::system;\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\n\n// Swap Unicode input stream for binary stream in Windows builds.\nstatic std::istream &get_command_input(command &command, std::istream &input)\n{\n#ifdef _MSC_VER\n    if (command.requires_raw_input())\n    {\n        bc::set_binary_stdin();\n        return std::cin;\n    }\n\n    bc::set_utf8_stdin();\n#endif\n\n    return input;\n}\n\n// Swap Unicode output stream for binary stream in Windows builds.\nstatic std::ostream &get_command_output(command &command, std::ostream &output)\n{\n#ifdef _MSC_VER\n    if (command.requires_raw_output())\n    {\n        bc::set_binary_stdout();\n        return std::cout;\n    }\n\n    bc::set_utf8_stdout();\n#endif\n\n    return output;\n}\n\n// Set Unicode error stream in Windows builds.\nstatic std::ostream &get_command_error(command &command, std::ostream &error)\n{\n    bc::set_utf8_stderr();\n    return error;\n}\n\nconsole_result dispatch(int argc, const char *argv[],\n                        std::istream &input, std::ostream &output, std::ostream &error)\n{\n    if (argc == 1)\n    {\n        display_usage(output);\n        return console_result::okay;\n    }\n\n    auto ret = dispatch_command(argc - 1, &argv[1], input, output, error);\n    output << std::endl;\n    //error<<std::endl; // once \\n is okay\n    return ret;\n}\n\nconsole_result dispatch_command(int argc, const char *argv[],\n                                std::istream &input, std::ostream &output, std::ostream &error)\n{\n    const std::string target(argv[0]);\n    const auto command = find(target);\n\n    if (!command)\n    {\n        const std::string superseding(formerly(target));\n        display_invalid_command(error, target, superseding);\n        return console_result::failure;\n    }\n\n    auto &in = get_command_input(*command, input);\n    auto &err = get_command_error(*command, error);\n    auto &out = get_command_output(*command, output);\n\n    parser metadata(*command);\n    std::string error_message;\n\n    if (!metadata.parse(error_message, in, argc, argv))\n    {\n        display_invalid_parameter(error, error_message);\n        return console_result::failure;\n    }\n\n    if (metadata.help())\n    {\n        command->write_help(output);\n        return console_result::okay;\n    }\n\n    return command->invoke(out, err);\n}\n\nconsole_result dispatch_command(int argc, const char *argv[],\n                                Json::Value &jv_output,\n                                libbitcoin::server::server_node &node, uint8_t api_version)\n{\n    std::istringstream input;\n    std::ostringstream output;\n\n    const std::string target(argv[0]);\n    const auto command = find(target);\n\n    if (!command)\n    {\n        const std::string superseding(formerly(target));\n        display_invalid_command(output, target, superseding);\n        throw invalid_command_exception{output.str()};\n    }\n    if (node.server_settings().read_only)\n        check_read_only(target);\n    auto &in = get_command_input(*command, input);\n\n    parser metadata(*command);\n    std::string error_message;\n\n    if (!metadata.parse(error_message, in, argc, argv))\n    {\n        display_invalid_parameter(output, error_message);\n        throw command_params_exception{output.str()};\n    }\n\n    if (metadata.help())\n    {\n        command->write_help(output);\n        jv_output = output.str();\n        return console_result::okay;\n    }\n\n    command->set_api_version(api_version);\n\n    if (command->category(ctgy_extension))\n    {\n        // fixme. is_blockchain_sync has some problem.\n        // if (command->category(ctgy_online) && node.is_blockchain_sync()) {\n        if (command->category(ctgy_online) &&\n            !node.chain_impl().chain_settings().use_testnet_rules)\n        {\n            uint64_t height{0};\n            /*node.chain_impl().get_last_height(height);\n            if (!command->is_block_height_fullfilled(height)) {\n                throw block_sync_required_exception{\"This command is unavailable because of the height < 610000.\"};\n            }*/\n        }\n\n        return static_cast<commands::command_extension *>(command.get())->invoke(jv_output, node);\n    }\n    else\n    {\n        command->set_api_version(1); // only compatible for v1\n        auto retcode = command->invoke(output, output);\n        jv_output = output.str();\n        return retcode;\n    }\n}\n\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/display.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/display.hpp>\n\n#include <iostream>\n#include <memory>\n#include <boost/format.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChain/explorer/generated.hpp>\n#include <UChain/explorer/utility.hpp>\n#include <UChain/explorer/version.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\n\nusing namespace bc::config;\n\nvoid display_command_names(std::ostream &stream)\n{\n    const auto func = [&stream](std::shared_ptr<command> explorer_command) {\n        BITCOIN_ASSERT(explorer_command != nullptr);\n        if (!explorer_command->obsolete())\n            stream << \"  \" << explorer_command->name() << \"\\r\\n\";\n    };\n\n    broadcast(func, stream);\n}\n\nvoid display_connection_failure(std::ostream &stream, const endpoint &url)\n{\n    stream << format(BX_CONNECTION_FAILURE) % url;\n}\n\nvoid display_invalid_command(std::ostream &stream, const std::string &command,\n                             const std::string &superseding)\n{\n    if (superseding.empty())\n        stream << format(BX_INVALID_COMMAND) % command;\n    else\n        stream << format(BX_DEPRECATED_COMMAND) % command % superseding;\n}\n\n// English only hack to patch missing arg name in boost exception message.\nstatic std::string fixup_boost_po_what_en(const std::string &what)\n{\n    std::string message(what);\n    boost::replace_all(message, \"for option is invalid\", \"is invalid\");\n    return message;\n}\n\nvoid display_invalid_parameter(std::ostream &stream,\n                               const std::string &message)\n{\n    stream << format(BX_INVALID_PARAMETER) % fixup_boost_po_what_en(message);\n}\n\nvoid display_usage(std::ostream &stream)\n{\n    stream\n        << std::endl\n        << BX_COMMAND_USAGE << std::endl\n        << format(BX_VERSION_MESSAGE) %\n               UC_EXPLORER_VERSION\n        << std::endl\n        << BX_COMMANDS_HEADER << std::endl;\n\n    display_command_names(stream);\n}\n\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/generated.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/generated.hpp>\n\n#include <functional>\n#include <memory>\n#include <string>\n#include <vector>\n#include <UChain/explorer/command.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n\n/********* GENERATED SOURCE CODE, DO NOT EDIT EXCEPT EXPERIMENTALLY **********/\n\nusing namespace po;\nusing namespace std;\nusing namespace boost::filesystem;\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nusing namespace commands;\n\nvoid broadcast(const function<void(shared_ptr<command>)> func, std::ostream &os)\n{\n    /*os <<\"== original commands ==\\r\\n\";\n\n    func(make_shared<help>());\n    func(make_shared<settings>());\n    func(make_shared<fetch_history>());\n    func(make_shared<send_tx>());\n    func(make_shared<tx_decode>());\n    func(make_shared<validate_tx>());\n    func(make_shared<stealth_decode>());\n    func(make_shared<stealth_encode>());\n    func(make_shared<stealth_public>());\n    func(make_shared<stealth_secret>());\n    func(make_shared<stealth_shared>());\n\n    os <<\"\\r\\n== extension commands ==\\r\\n\";*/\n\n    broadcast_extension(func, os);\n}\n\nshared_ptr<command> find(const string &symbol)\n{\n    if (symbol == help::symbol())\n        return make_shared<help>();\n    if (symbol == send_tx::symbol())\n        return make_shared<send_tx>();\n    if (symbol == settings::symbol())\n        return make_shared<settings>();\n    if (symbol == fetch_history::symbol())\n        return make_shared<fetch_history>();\n    if (symbol == stealth_decode::symbol())\n        return make_shared<stealth_decode>();\n    if (symbol == stealth_encode::symbol())\n        return make_shared<stealth_encode>();\n    if (symbol == stealth_public::symbol())\n        return make_shared<stealth_public>();\n    if (symbol == stealth_secret::symbol())\n        return make_shared<stealth_secret>();\n    if (symbol == stealth_shared::symbol())\n        return make_shared<stealth_shared>();\n    if (symbol == tx_decode::symbol())\n        return make_shared<tx_decode>();\n    if (symbol == validate_tx::symbol())\n        return make_shared<validate_tx>();\n\n    return find_extension(symbol);\n}\n\nstd::string formerly(const string &former)\n{\n    if (former == send_tx::formerly())\n        return send_tx::symbol();\n    if (former == stealth_decode::formerly())\n        return stealth_decode::symbol();\n    if (former == stealth_public::formerly())\n        return stealth_public::symbol();\n    if (former == stealth_secret::formerly())\n        return stealth_secret::symbol();\n    if (former == validate_tx::formerly())\n        return validate_tx::symbol();\n\n    return \"\";\n}\n\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/json_helper.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n\n#include <cstdint>\n#include <UChain/client.hpp>\n#include <UChain/explorer/config/script.hpp>\n\nusing namespace bc::client;\nusing namespace bc::config;\nusing namespace bc::wallet;\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace config\n{\n\nstd::ostream &operator<<(std::ostream &out, char c)\n{\n    out << std::to_string(c);\n    return out;\n}\n\nstd::ostream &operator<<(std::ostream &out, unsigned char c)\n{\n    out << std::to_string(c);\n    return out;\n}\n\ntemplate <typename Value>\nJson::Value &operator+=(Json::Value &a, const Value &b)\n{\n    std::ostringstream ss;\n    ss << b;\n    a = ss.str();\n    return a;\n}\n\ntemplate <typename Value>\nstd::string operator+(const Value &value)\n{\n    std::ostringstream ss;\n    ss << value;\n    return ss.str();\n}\n\nJson::Value json_helper::prop_list(const header &header)\n{\n    const chain::header &block_header = header;\n\n    Json::Value tree;\n\n    tree[\"hash\"] += hash256(block_header.hash());\n    tree[\"merkle_tree_hash\"] += hash256(block_header.merkle);\n    tree[\"previous_block_hash\"] += hash256(block_header.previous_block_hash);\n    /*tree[\"bits\"] += block_header.bits;\n    tree[\"mixhash\"] += block_header.mixhash;\n    tree[\"nonce\"] += block_header.nonce;*/\n\n    if (version_ == 1)\n    {\n        tree[\"time_stamp\"] += block_header.timestamp;\n        tree[\"version\"] += block_header.version;\n        tree[\"number\"] += block_header.number;\n        tree[\"transaction_count\"] += block_header.transaction_count;\n    }\n    else\n    {\n        if (version_ <= 2)\n        {\n            tree[\"time_stamp\"] = block_header.timestamp;\n        }\n        else\n        {\n            tree[\"timestamp\"] = block_header.timestamp;\n        }\n        tree[\"version\"] = block_header.version;\n        tree[\"number\"] = block_header.number;\n        tree[\"transaction_count\"] = block_header.transaction_count;\n    }\n\n    return tree;\n}\n\nJson::Value json_helper::prop_tree(const header &header)\n{\n    if (version_ <= 2)\n    {\n        Json::Value tree;\n        tree[\"result\"] = prop_list(header);\n        return tree;\n    }\n    else\n    {\n        return prop_list(header);\n    }\n}\n\nJson::Value json_helper::prop_tree(const std::vector<header> &headers, bool json)\n{\n    if (version_ <= 2)\n    {\n        Json::Value tree;\n        tree[\"headers\"] = prop_tree_list(\"header\", headers, json);\n        return tree;\n    }\n    else\n    {\n        return prop_tree_list(\"header\", headers, json);\n    }\n}\n\n// transfers\n\nJson::Value json_helper::prop_list(const chain::history &row)\n{\n    Json::Value tree;\n\n    tree[\"received\"] = Json::objectValue;\n    // missing output implies output cut off by server's history threshold\n    if (row.output.hash != null_hash)\n    {\n        tree[\"received\"][\"hash\"] += hash256(row.output.hash);\n\n        // zeroized received.height implies output unconfirmed (in mempool)\n        if (row.output_height != 0)\n            tree[\"received\"][\"height\"] += row.output_height;\n\n        if (version_ == 1)\n        {\n            tree[\"received\"][\"index\"] += row.output.index;\n        }\n        else\n        {\n            tree[\"received\"][\"index\"] = row.output.index;\n        }\n    }\n\n    tree[\"spent\"] = Json::objectValue;\n    // missing input implies unspent\n    if (row.spend.hash != null_hash)\n    {\n        tree[\"spent\"][\"hash\"] += hash256(row.spend.hash);\n\n        // zeroized input.height implies spend unconfirmed (in mempool)\n        if (row.spend_height != 0)\n            tree[\"spent\"][\"height\"] += row.spend_height;\n\n        if (version_ == 1)\n        {\n            tree[\"spent\"][\"index\"] += row.spend.index;\n        }\n        else\n        {\n            tree[\"spent\"][\"index\"] = row.spend.index;\n        }\n    }\n\n    if (version_ == 1)\n    {\n        tree[\"value\"] += row.value;\n    }\n    else\n    {\n        tree[\"value\"] = row.value;\n    }\n    return tree;\n}\nJson::Value json_helper::prop_tree(const chain::history &row)\n{\n    Json::Value tree;\n    tree[\"transfer\"] = prop_list(row);\n    return tree;\n}\nJson::Value json_helper::prop_tree(const chain::history::list &rows, bool json)\n{\n    Json::Value tree;\n    tree[\"transfers\"] = prop_tree_list(\"transfer\", rows, json);\n    return tree;\n}\n\n// balance\n\nJson::Value json_helper::prop_list(const chain::history::list &rows,\n                                   const payment_address &balance_address)\n{\n    Json::Value tree;\n    uint64_t total_received = 0;\n    uint64_t confirmed_balance = 0;\n    uint64_t unspent_balance = 0;\n\n    for (const auto &row : rows)\n    {\n        total_received += row.value;\n\n        // spend unconfirmed (or no spend attempted)\n        if (row.spend.hash == null_hash)\n            unspent_balance += row.value;\n\n        if (row.output_height != 0 &&\n            (row.spend.hash == null_hash || row.spend_height == 0))\n            confirmed_balance += row.value;\n    }\n\n    tree[\"address\"] += balance_address;\n    if (version_ == 1)\n    {\n        tree[\"confirmed\"] += confirmed_balance;\n        tree[\"received\"] += total_received;\n        tree[\"unspent\"] += unspent_balance;\n    }\n    else\n    {\n        tree[\"confirmed\"] = confirmed_balance;\n        tree[\"received\"] = total_received;\n        tree[\"unspent\"] = unspent_balance;\n    }\n    return tree;\n}\nJson::Value json_helper::prop_tree(const chain::history::list &rows,\n                                   const payment_address &balance_address)\n{\n    Json::Value tree;\n    if (version_ <= 2)\n    {\n        tree[\"balance\"] = prop_list(rows, balance_address);\n    }\n    else\n    {\n        tree = prop_list(rows, balance_address);\n    }\n    return tree;\n}\n\n// inputs\n\nJson::Value json_helper::prop_list(const tx_input_type &tx_input)\n{\n    Json::Value tree;\n    const auto script_address = payment_address::extract(tx_input.script);\n    if (script_address)\n        tree[\"address\"] += script_address;\n\n    tree[\"previous_output\"] = Json::objectValue;\n    tree[\"previous_output\"][\"hash\"] += hash256(tx_input.previous_output.hash);\n    if (version_ == 1)\n    {\n        tree[\"previous_output\"][\"index\"] += tx_input.previous_output.index;\n        tree[\"sequence\"] += tx_input.sequence;\n    }\n    else\n    {\n        tree[\"previous_output\"][\"index\"] = tx_input.previous_output.index;\n        tree[\"sequence\"] = tx_input.sequence;\n    }\n    tree[\"script\"] += script(tx_input.script).to_string();\n    return tree;\n}\nJson::Value json_helper::prop_tree(const tx_input_type &tx_input)\n{\n    Json::Value tree;\n    tree[\"input\"] = prop_list(tx_input);\n    return tree;\n}\nJson::Value json_helper::prop_tree(const tx_input_type::list &tx_inputs, bool json)\n{\n    Json::Value tree;\n    tree[\"inputs\"] = prop_tree_list(\"input\", tx_inputs, json);\n    return tree;\n}\n\nJson::Value json_helper::prop_list(const input &input)\n{\n    const tx_input_type &tx_input = input;\n    return prop_list(tx_input);\n}\nJson::Value json_helper::prop_tree(const input &input)\n{\n    Json::Value tree;\n    tree[\"input\"] = prop_list(input);\n    return tree;\n}\nJson::Value json_helper::prop_tree(const std::vector<input> &inputs, bool json)\n{\n    const auto tx_inputs = cast<input, tx_input_type>(inputs);\n\n    Json::Value tree;\n    tree[\"inputs\"] = prop_tree_list(\"input\", tx_inputs, json);\n    return tree;\n}\n\n// outputs\n\nJson::Value json_helper::prop_list(const tx_output_type &tx_output)\n{\n    Json::Value tree;\n    const auto address = payment_address::extract(tx_output.script);\n    if (address)\n        tree[\"address\"] += address;\n\n    tree[\"script\"] += script(tx_output.script).to_string();\n    uint64_t lock_height = 0;\n    if (chain::operation::is_pay_key_hash_with_lock_height_pattern(tx_output.script.operations))\n        lock_height = chain::operation::get_lock_height_from_pay_key_hash_with_lock_height(tx_output.script.operations);\n    // TODO: this will eventually change due to privacy problems, see:\n    // lists.dyne.org/lurker/message/20140812.214120.317490ae.en.html\n\n    if (!address)\n    {\n        tree[\"stealth\"] = Json::objectValue;\n        uint32_t stealth_prefix;\n        ec_compressed ephemeral_key;\n        if (to_stealth_prefix(stealth_prefix, tx_output.script) &&\n            extract_ephemeral_key(ephemeral_key, tx_output.script))\n        {\n            tree[\"stealth\"][\"prefix\"] += stealth_prefix;\n            tree[\"stealth\"][\"ephemeral_public_key\"] += ec_public(ephemeral_key);\n        }\n    }\n\n    if (version_ == 1)\n    {\n        tree[\"value\"] += tx_output.value;\n        tree[\"locked_height_range\"] += lock_height;\n    }\n    else\n    {\n        tree[\"value\"] = tx_output.value;\n        tree[\"locked_height_range\"] = lock_height;\n    }\n\n    if (chain::operation::is_pay_key_hash_with_attenuation_model_pattern(tx_output.script.operations))\n    {\n        auto model_param = tx_output.get_attenuation_model_param();\n        tree[\"attenuation_model_param\"] = prop_attenuation_model_param(model_param);\n    }\n\n    tree[\"asset\"] = prop_list(const_cast<bc::chain::asset &>(tx_output.attach_data));\n    return tree;\n}\n\nJson::Value json_helper::prop_attenuation_model_param(const data_chunk &chunk)\n{\n    std::string param_str(chunk.begin(), chunk.end());\n    return prop_attenuation_model_param(param_str);\n}\n\nJson::Value json_helper::prop_attenuation_model_param(const std::string &param_str)\n{\n    Json::Value tree;\n    const auto &kv_vec = bc::split(param_str, \";\", true);\n    std::vector<uint64_t> uc_vec, uq_vec;\n    for (const auto &kv : kv_vec)\n    {\n        auto vec = bc::split(kv, \"=\", true);\n        if (vec.size() == 2)\n        {\n            auto &key = vec[0];\n            auto &value = vec[1];\n            if (attenuation_model::is_multi_value_key(key))\n            {\n                try\n                {\n                    if (key == \"UC\")\n                    {\n                        auto &&str_vec = bc::split(value, \",\", true);\n                        for (auto &str : str_vec)\n                        {\n                            uc_vec.push_back(std::stoull(str));\n                        }\n                    }\n                    else if (key == \"UQ\")\n                    {\n                        auto &&str_vec = bc::split(value, \",\", true);\n                        for (auto &str : str_vec)\n                        {\n                            uq_vec.push_back(std::stoull(str));\n                        }\n                    }\n                }\n                catch (const std::exception &e)\n                {\n                    uc_vec.clear();\n                    uq_vec.clear();\n                }\n            }\n            else\n            {\n                uint64_t num = std::stoull(value);\n                auto display_key = attenuation_model::get_name_of_key(key);\n                tree[display_key] = num;\n            }\n        }\n    }\n\n    if (uc_vec.size() > 0 && uc_vec.size() == uq_vec.size())\n    {\n        Json::Value nodes;\n\n        for (size_t i = 0; i < uc_vec.size(); ++i)\n        {\n            Json::Value node;\n            node[\"number\"] = uc_vec[i];\n            node[\"quantity\"] = uq_vec[i];\n            nodes.append(node);\n        }\n\n        tree[\"locked\"] = nodes;\n    }\n\n    return tree;\n}\n\nJson::Value json_helper::prop_list(const tx_output_type &tx_output, uint32_t index)\n{\n    Json::Value tree;\n\n    tree = prop_list(tx_output);\n\n    if (version_ == 1)\n    {\n        tree[\"index\"] += index;\n    }\n    else\n    {\n        tree[\"index\"] = index;\n    }\n\n    return tree;\n}\n\n// is_secondaryissue has no meaning for token quantity summary.\n// don't add address info if show_address is not true.\nJson::Value json_helper::prop_list(const bc::chain::token_detail &detail_info,\n                                   bool is_maximum_supply, bool show_address)\n{\n    Json::Value tree;\n    tree[\"symbol\"] = detail_info.get_symbol();\n    tree[\"issuer\"] = detail_info.get_issuer();\n    if (show_address)\n    {\n        tree[\"address\"] = detail_info.get_address();\n    }\n    tree[\"description\"] = detail_info.get_description();\n\n    const char *maximum_supply_or_quantity = is_maximum_supply ? \"maximum_supply\" : \"quantity\";\n\n    if (version_ == 1)\n    {\n        tree[maximum_supply_or_quantity] += detail_info.get_maximum_supply();\n        tree[\"decimal_number\"] += detail_info.get_decimal_number();\n        tree[\"secondaryissue_threshold\"] += detail_info.get_secondaryissue_threshold();\n        if (is_maximum_supply)\n        {\n            tree[\"is_secondaryissue\"] = detail_info.is_token_secondaryissue() ? \"true\" : \"false\";\n        }\n    }\n    else\n    {\n        tree[maximum_supply_or_quantity] = detail_info.get_maximum_supply();\n        tree[\"decimal_number\"] = detail_info.get_decimal_number();\n        tree[\"secondaryissue_threshold\"] = detail_info.get_secondaryissue_threshold();\n        if (is_maximum_supply)\n        {\n            tree[\"is_secondaryissue\"] = detail_info.is_token_secondaryissue();\n        }\n    }\n    return tree;\n}\n\n// balance_info only \"symbol\" \"address\" \"quantity\" info included in it.\n// issued_info include the other info.\n// is_secondaryissue has no meaning for token quantity summary.\n// don't add address info if show_address is not true.\nJson::Value json_helper::prop_list(const bc::chain::token_balances &balance_info,\n                                   const bc::chain::token_detail &issued_info, bool show_address)\n{\n    Json::Value tree;\n    tree[\"symbol\"] = balance_info.symbol;\n    if (show_address)\n    {\n        tree[\"address\"] = balance_info.address;\n    }\n\n    tree[\"issuer\"] = issued_info.get_issuer();\n    tree[\"description\"] = issued_info.get_description();\n\n    if (version_ == 1)\n    {\n        tree[\"quantity\"] += balance_info.unspent_token;\n        tree[\"locked_quantity\"] += balance_info.locked_token;\n\n        tree[\"decimal_number\"] += issued_info.get_decimal_number();\n        tree[\"secondaryissue_threshold\"] += issued_info.get_secondaryissue_threshold();\n    }\n    else\n    {\n        tree[\"quantity\"] = balance_info.unspent_token;\n        tree[\"locked_quantity\"] = balance_info.locked_token;\n\n        tree[\"decimal_number\"] = issued_info.get_decimal_number();\n        tree[\"secondaryissue_threshold\"] = issued_info.get_secondaryissue_threshold();\n    }\n    return tree;\n}\n\nJson::Value json_helper::prop_list(const bc::chain::token_balances &balance_info)\n{\n    Json::Value tree;\n    tree[\"address\"] = balance_info.address;\n\n    if (version_ == 1)\n    {\n        tree[\"quantity\"] += balance_info.unspent_token;\n        tree[\"locked_quantity\"] += balance_info.locked_token;\n    }\n    else\n    {\n        tree[\"quantity\"] = balance_info.unspent_token;\n        tree[\"locked_quantity\"] = balance_info.locked_token;\n    }\n    return tree;\n}\n\nJson::Value json_helper::prop_list(const bc::chain::token_deposited_balance &balance_info,\n                                   const bc::chain::token_detail &issued_info, bool show_address)\n{\n    Json::Value tree;\n    tree[\"symbol\"] = balance_info.symbol;\n    if (show_address)\n    {\n        tree[\"address\"] = balance_info.address;\n    }\n\n    tree[\"tx_height\"] = balance_info.tx_height;\n    tree[\"tx_hash\"] = balance_info.tx_hash;\n    tree[\"decimal_number\"] = issued_info.get_decimal_number();\n    // tree[\"issuer\"] = issued_info.get_issuer();\n    // tree[\"description\"] = issued_info.get_description();\n    tree[\"quantity\"] = balance_info.unspent_token;\n    tree[\"locked_quantity\"] = balance_info.locked_token;\n    tree[\"attenuation_model_param\"] = prop_attenuation_model_param(balance_info.model_param);\n    return tree;\n}\n\nJson::Value json_helper::prop_list(const bc::chain::token_transfer &trans_info, uint8_t decimal_number)\n{\n    Json::Value tree;\n    tree[\"symbol\"] = trans_info.get_symbol();\n\n    if (version_ == 1)\n    {\n        tree[\"quantity\"] += trans_info.get_quantity();\n    }\n    else\n    {\n        tree[\"quantity\"] = trans_info.get_quantity();\n    }\n\n    if (decimal_number != max_uint8)\n    {\n        if (version_ == 1)\n        {\n            tree[\"decimal_number\"] += decimal_number;\n        }\n        else\n        {\n            tree[\"decimal_number\"] = decimal_number;\n        }\n    }\n    return tree;\n}\n\nJson::Value json_helper::prop_list(const bc::chain::token_cert &cert_info)\n{\n    Json::Value tree;\n    tree[\"symbol\"] = cert_info.get_symbol();\n    tree[\"owner\"] = cert_info.get_owner();\n    tree[\"address\"] = cert_info.get_address();\n    tree[\"cert\"] = cert_info.get_type_name();\n    return tree;\n}\n\nJson::Value json_helper::prop_list(const bc::chain::candidate &candidate_info, bool always_show_content)\n{\n    Json::Value tree;\n    tree[\"symbol\"] = candidate_info.get_symbol();\n    tree[\"address\"] = candidate_info.get_address();\n    tree[\"status\"] = candidate_info.get_status_name();\n\n    if (always_show_content || candidate_info.is_register_status())\n    {\n        tree[\"content\"] = candidate_info.get_content();\n    }\n\n    return tree;\n}\n\nJson::Value json_helper::prop_list(const bc::chain::candidate_info &candidate_info, bool always_show_content, bool show_vote)\n{\n    Json::Value tree;\n\n    tree[\"height\"] = candidate_info.output_height;\n    if (version_ <= 2)\n    {\n        tree[\"time_stamp\"] = candidate_info.timestamp;\n    }\n    else\n    {\n        tree[\"timestamp\"] = candidate_info.timestamp;\n    }\n\n    tree[\"to_uid\"] = candidate_info.to_uid;\n    tree[\"symbol\"] = candidate_info.candidate.get_symbol();\n    tree[\"address\"] = candidate_info.candidate.get_address();\n    tree[\"status\"] = candidate_info.candidate.get_status_name();\n\n    if (always_show_content || candidate_info.candidate.is_register_status())\n    {\n        tree[\"content\"] = candidate_info.candidate.get_content();\n    }\n\n    if (show_vote)\n    {\n        tree[\"vote\"] = candidate_info.vote;\n    }\n\n    return tree;\n}\n\nJson::Value json_helper::prop_list(const bc::chain::wallet_multisig &acc_multisig)\n{\n    Json::Value tree, pubkeys;\n    for (const auto &each : acc_multisig.get_cosigner_pubkeys())\n    {\n        pubkeys.append(each);\n    }\n\n    if (version_ == 1)\n    {\n        tree[\"index\"] += acc_multisig.get_index();\n        tree[\"m\"] += acc_multisig.get_m();\n        tree[\"n\"] += acc_multisig.get_n();\n    }\n    else\n    {\n        tree[\"index\"] = acc_multisig.get_index();\n        tree[\"m\"] = acc_multisig.get_m();\n        tree[\"n\"] = acc_multisig.get_n();\n    }\n\n    if (version_ == 1 && pubkeys.isNull())\n    { //compatible for v1\n        tree[\"public-keys\"] = \"\";\n    }\n    else if (version_ <= 2)\n    {\n        tree[\"public-keys\"] = pubkeys;\n    }\n    else\n    {\n        tree[\"public_keys\"] = pubkeys;\n    }\n\n    tree[\"address\"] = acc_multisig.get_address();\n    tree[\"description\"] = acc_multisig.get_description();\n\n    if (version_ <= 2)\n    {\n        tree[\"self-publickey\"] = acc_multisig.get_pub_key();\n        tree[\"multisig-script\"] = acc_multisig.get_multisig_script();\n    }\n    else\n    {\n        tree[\"self_publickey\"] = acc_multisig.get_pub_key();\n        tree[\"multisig_script\"] = acc_multisig.get_multisig_script();\n    }\n\n    return tree;\n}\n\nJson::Value json_helper::prop_list(bc::chain::asset &attach_data)\n{\n    Json::Value tree;\n\n    if (attach_data.get_type() == UCN_TYPE)\n    {\n        tree[\"type\"] = \"ucn\";\n    }\n    else if (attach_data.get_type() == UC_TOKEN_TYPE)\n    {\n        auto token_info = boost::get<bc::chain::token>(attach_data.get_attach());\n        if (token_info.get_status() == TOKEN_DETAIL_TYPE)\n        {\n            auto detail_info = boost::get<bc::chain::token_detail>(token_info.get_data());\n            tree = prop_list(detail_info, false);\n            // add is_secondaryissue for token-issue\n            if (version_ == 1)\n            {\n                tree[\"is_secondaryissue\"] = detail_info.is_token_secondaryissue() ? \"true\" : \"false\";\n            }\n            else\n            {\n                tree[\"is_secondaryissue\"] = detail_info.is_token_secondaryissue();\n            }\n            tree[\"type\"] = \"token-issue\";\n        }\n        if (token_info.get_status() == TOKEN_TRANSFERABLE_TYPE)\n        {\n            auto trans_info = boost::get<bc::chain::token_transfer>(token_info.get_data());\n            tree = prop_list(trans_info);\n            tree[\"type\"] = \"token-transfer\";\n        }\n    }\n    else if (attach_data.get_type() == TOKEN_CANDIDATE_TYPE)\n    {\n        auto token_info = boost::get<bc::chain::candidate>(attach_data.get_attach());\n        tree = prop_list(token_info);\n        tree[\"type\"] = \"candidate\";\n    }\n    else if (attach_data.get_type() == TOKEN_CERT_TYPE)\n    {\n        auto cert_info = boost::get<bc::chain::token_cert>(attach_data.get_attach());\n        tree = prop_list(cert_info);\n        tree[\"type\"] = \"token-cert\";\n    }\n    else if (attach_data.get_type() == UID_TYPE)\n    {\n        auto uid_info = boost::get<bc::chain::uid>(attach_data.get_attach());\n        if (uid_info.get_status() == UID_DETAIL_TYPE)\n        {\n            tree[\"type\"] = \"uid-register\";\n            auto detail_info = boost::get<bc::chain::uid_detail>(uid_info.get_data());\n            tree[\"symbol\"] = detail_info.get_symbol();\n            tree[\"address\"] = detail_info.get_address();\n        }\n        if (uid_info.get_status() == UID_TRANSFERABLE_TYPE)\n        {\n            tree[\"type\"] = \"uid-transfer\";\n            auto detail_info = boost::get<bc::chain::uid_detail>(uid_info.get_data());\n            tree[\"symbol\"] = detail_info.get_symbol();\n            tree[\"address\"] = detail_info.get_address();\n        }\n    }\n    else if (attach_data.get_type() == MESSAGE_TYPE)\n    {\n        tree[\"type\"] = \"message\";\n        auto msg_info = boost::get<bc::chain::blockchain_message>(attach_data.get_attach());\n        tree[\"content\"] = msg_info.get_content();\n    }\n    else\n    {\n        tree[\"type\"] = \"unknown business\";\n        BITCOIN_ASSERT(false);\n    }\n\n    if (attach_data.get_version() == UID_ASSET_VERIFY_VERSION)\n    {\n        if (!attach_data.get_from_uid().empty())\n            tree[\"from_uid\"] = attach_data.get_from_uid();\n        if (!attach_data.get_to_uid().empty())\n            tree[\"to_uid\"] = attach_data.get_to_uid();\n    }\n    return tree;\n}\nJson::Value json_helper::prop_tree(const tx_output_type &tx_output)\n{\n    Json::Value tree;\n    tree[\"output\"] = prop_list(tx_output);\n    return tree;\n}\nJson::Value json_helper::prop_tree(const tx_output_type::list &tx_outputs, bool json)\n{\n\n    Json::Value list;\n    uint32_t index = 0;\n    for (const auto &value : tx_outputs)\n    {\n        list.append(prop_list(value, index));\n        index++;\n    }\n\n    if (version_ == 1 && list.isNull())\n    { //compatible for v1\n        list = \"\";\n    }\n\n    return list;\n}\n// points\n\nJson::Value json_helper::prop_list(const chain::point &point)\n{\n    Json::Value tree;\n    tree[\"hash\"] += hash256(point.hash);\n    if (version_ == 1)\n    {\n        tree[\"index\"] += point.index;\n    }\n    else\n    {\n        tree[\"index\"] = point.index;\n    }\n    return tree;\n}\n\nJson::Value json_helper::prop_tree(const chain::point::list &points, bool json)\n{\n    Json::Value tree;\n    for (const auto &point : points)\n        tree[\"points\"] = prop_list(point);\n    return tree;\n}\n\nJson::Value json_helper::prop_tree(const chain::points_info &points_info, bool json)\n{\n    Json::Value tree;\n    tree[\"points\"] = prop_tree_list(\"points\", points_info.points, json);\n    tree[\"change\"] += points_info.change;\n    return tree;\n}\n\n// transactions\n\nJson::Value json_helper::prop_list_of_rawtx(const transaction &transaction, bool with_hash, bool ignore_compatibility)\n{\n    const tx_type &tx = transaction;\n    std::ostringstream sout;\n    sout << base16(tx.to_data());\n\n    Json::Value tree;\n    if (!ignore_compatibility && version_ <= 2)\n    {\n        if (with_hash)\n        {\n            tree[\"hash\"] += hash256(tx.hash());\n        }\n        tree[\"hex\"] = sout.str();\n    }\n    else\n    {\n        if (with_hash)\n        {\n            tree[\"hash\"] += hash256(tx.hash());\n            tree[\"rawtx\"] = sout.str();\n        }\n        else\n        {\n            tree = sout.str();\n        }\n    }\n    return tree;\n}\n\nJson::Value json_helper::prop_list(const transaction &transaction, bool json)\n{\n    const tx_type &tx = transaction;\n\n    Json::Value tree;\n    if (json)\n    {\n        tree[\"hash\"] += hash256(tx.hash());\n        tree[\"inputs\"] = prop_tree_list(\"input\", tx.inputs, json);\n        tree[\"lock_time\"] += tx.locktime;\n        tree[\"outputs\"] = prop_tree(tx.outputs, json); // only used for output to add new field \"index\"\n        tree[\"version\"] += tx.version;\n        return tree;\n    }\n    else\n    {\n        std::ostringstream sout;\n        sout << base16(tx.to_data());\n        if (version_ <= 2)\n        {\n            tree[\"raw\"] = sout.str();\n        }\n        else\n        {\n            tree = sout.str();\n        }\n    }\n    return tree;\n}\n\nJson::Value json_helper::prop_list(const transaction &transaction, uint64_t tx_height, bool json)\n{\n    const tx_type &tx = transaction;\n\n    Json::Value tree;\n    tree[\"hash\"] += hash256(tx.hash());\n    if (version_ == 1)\n    {\n        tree[\"height\"] += tx_height;\n    }\n    else\n    {\n        tree[\"height\"] = tx_height;\n    }\n    tree[\"inputs\"] = prop_tree_list(\"input\", tx.inputs, json);\n    tree[\"lock_time\"] += tx.locktime;\n    tree[\"outputs\"] = prop_tree(tx.outputs, json); // only used for output to add new field \"index\"\n    tree[\"version\"] += tx.version;\n    return tree;\n}\n\nJson::Value json_helper::prop_tree(const transaction &transaction, bool json)\n{\n    if (version_ <= 2)\n    {\n        Json::Value tree;\n        tree[\"transaction\"] = prop_list(transaction, json);\n        return tree;\n    }\n    else\n    {\n        return prop_list(transaction, json);\n    }\n}\n\nJson::Value json_helper::prop_tree(const std::vector<transaction> &transactions, bool json)\n{\n    if (version_ <= 2)\n    {\n        Json::Value tree;\n        tree[\"transactions\"] = prop_tree_list_of_lists(\"transaction\", transactions, json);\n        return tree;\n    }\n    else\n    {\n        return prop_tree_list_of_lists(\"transaction\", transactions, json);\n    }\n}\n\n// wrapper\n\nJson::Value json_helper::prop_list(const bc::wallet::wrapped_data &wrapper)\n{\n    Json::Value tree;\n    tree[\"checksum\"] += wrapper.checksum;\n    tree[\"payload\"] += base16(wrapper.payload);\n    tree[\"version\"] += wrapper.version;\n    return tree;\n}\nJson::Value json_helper::prop_tree(const bc::wallet::wrapped_data &wrapper)\n{\n    Json::Value tree;\n    tree[\"wrapper\"] = prop_list(wrapper);\n    return tree;\n}\n\nJson::Value json_helper::prop_list(const tx_type &tx, const hash_digest &block_hash,\n                                   const payment_address &address, bool json)\n{\n    Json::Value tree;\n    tree[\"block\"] += hash256(block_hash);\n    tree[\"address\"] += address;\n    tree[\"transaction\"] = prop_list(tx, json);\n    return tree;\n}\nJson::Value json_helper::prop_tree(const tx_type &tx, const hash_digest &block_hash,\n                                   const payment_address &address, bool json)\n{\n    Json::Value tree;\n    tree[\"watch_address\"] = prop_list(tx, block_hash, address, json);\n    return tree;\n}\n\n// stealth_address\n\nJson::Value json_helper::prop_list(const stealth_address &stealth, bool json)\n{\n    // We don't serialize a \"reuse key\" value as this is strictly an\n    // optimization for the purpose of serialization and otherwise complicates\n    // understanding of what is actually otherwise very simple behavior.\n    // So instead we emit the reused key as one of the spend keys.\n    // This means that it is typical to see the same key in scan and spend.\n\n    const auto spends = cast<ec_compressed, ec_public>(stealth.spend_keys());\n    const auto spends_values = prop_value_list(\"public_key\", spends, json);\n\n    Json::Value tree;\n    tree[\"encoded\"] += stealth;\n    tree[\"filter\"] += stealth.filter();\n    tree[\"scan_public_key\"] += ec_public(stealth.scan_key());\n    tree[\"signatures\"] += stealth.signatures();\n    tree[\"spends\"] = spends_values;\n    tree[\"version\"] += stealth.version();\n    return tree;\n}\nJson::Value json_helper::prop_tree(const stealth_address &stealth, bool json)\n{\n    Json::Value tree;\n    tree[\"stealth_address\"] = prop_list(stealth, json);\n    return tree;\n}\n\n// stealth\n\nJson::Value json_helper::prop_list(const chain::stealth &row)\n{\n    Json::Value tree;\n    tree[\"ephemeral_public_key\"] += ec_public(row.ephemeral_public_key);\n    tree[\"public_key_hash\"] += hash160(row.public_key_hash);\n    tree[\"transaction_hash\"] += hash256(row.transaction_hash);\n    return tree;\n}\nJson::Value json_helper::prop_tree(const chain::stealth &row)\n{\n    Json::Value tree;\n    tree[\"match\"] = prop_list(row);\n    return tree;\n}\n\nJson::Value json_helper::prop_tree(const chain::stealth::list &rows, bool json)\n{\n    Json::Value tree;\n    tree[\"stealth\"] = prop_tree_list(\"match\", rows, json);\n    return tree;\n}\n\n// metadata\n\nJson::Value json_helper::prop_list(const hash_digest &hash, size_t height, size_t index)\n{\n    Json::Value tree;\n    tree[\"hash\"] += hash256(hash);\n    if (version_ == 1)\n    {\n        tree[\"height\"] += height;\n        tree[\"index\"] += index;\n    }\n    else\n    {\n        tree[\"height\"] = static_cast<uint64_t>(height);\n        tree[\"index\"] = static_cast<uint32_t>(index);\n    }\n    return tree;\n}\nJson::Value json_helper::prop_tree(const hash_digest &hash, size_t height, size_t index)\n{\n    Json::Value tree;\n    tree[\"metadata\"] = prop_list(hash, height, index);\n    return tree;\n}\n\n// settings\n\nJson::Value json_helper::prop_tree(const settings_list &settings)\n{\n    Json::Value list;\n    for (const auto &setting : settings)\n        list[setting.first] = setting.second;\n\n    Json::Value tree;\n    tree[\"settings\"] = list;\n    return tree;\n}\n\n// uri\n\nJson::Value json_helper::prop_tree(const bitcoin_uri &uri)\n{\n    Json::Value uri_props;\n\n    if (!uri.address().empty())\n        uri_props[\"address\"] = uri.address();\n\n    if (uri.amount() != 0)\n        uri_props[\"amount\"] += uri.amount();\n\n    if (!uri.label().empty())\n        uri_props[\"label\"] = uri.label();\n\n    if (!uri.message().empty())\n        uri_props[\"message\"] = uri.message();\n\n    if (!uri.r().empty())\n        uri_props[\"r\"] = uri.r();\n\n    uri_props[\"scheme\"] = \"bitcoin\";\n\n    Json::Value tree;\n    tree[\"uri\"] = uri_props;\n    return tree;\n}\n\n//block\n\nJson::Value json_helper::prop_tree(const block &block, bool json, bool tx_json)\n{\n    Json::Value tree;\n\n    if (json)\n    {\n        std::vector<transaction> txs;\n        txs.resize(block.transactions.size());\n        std::copy(block.transactions.begin(), block.transactions.end(), txs.begin());\n        if (version_ <= 2)\n        {\n            tree[\"header\"] = prop_tree(block.header);\n            tree[\"txs\"] = prop_tree(txs, tx_json);\n        }\n        else\n        {\n            tree = prop_tree(block.header);\n            tree[\"transactions\"] = prop_tree(txs, tx_json);\n        }\n    }\n    else\n    {\n        std::ostringstream sout;\n        sout << encode_base16(block.to_data());\n        if (version_ <= 2)\n        {\n            tree[\"raw\"] = sout.str();\n        }\n        else\n        {\n            tree = sout.str();\n        }\n    }\n\n    return tree;\n}\n\nJson::Value json_helper::prop_list(const wallet_info &acc)\n{\n    Json::Value tree;\n    tree[\"name\"] = std::get<0>(acc);\n    if (std::get<1>(acc).size() > 0)\n        tree[\"mnemonic\"] = std::get<1>(acc);\n    tree[\"addresses\"] = std::get<2>(acc);\n\n    return tree;\n}\n\n} // namespace config\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/parser.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/parser.hpp>\n\n#include <iostream>\n#include <string>\n#include <boost/program_options.hpp>\n#include <UChain/explorer/command.hpp>\n#include <UChain/explorer/define.hpp>\n#include <UChain/coin.hpp>\n\nusing namespace boost::filesystem;\nusing namespace boost::program_options;\nusing namespace boost::system;\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\n\nparser::parser(command &instance)\n    : help_(false), instance_(instance)\n{\n}\n\nbool parser::help() const\n{\n    return help_;\n}\n\noptions_metadata parser::load_options()\n{\n    return instance_.load_options();\n}\n\narguments_metadata parser::load_arguments()\n{\n    return instance_.load_arguments();\n}\n\noptions_metadata parser::load_settings()\n{\n    options_metadata settings(\"settings\");\n    instance_.load_settings(settings);\n    return settings;\n}\n\noptions_metadata parser::load_environment()\n{\n    options_metadata environment(\"environment\");\n    instance_.load_environment(environment);\n    return environment;\n}\n\nvoid parser::load_command_variables(variables_map &variables,\n                                    std::istream &input, int argc, const char *argv[])\n{\n    bc::config::parser::load_command_variables(variables, argc, argv);\n\n    // Don't load rest if help is specified.\n    // For variable with stdin or file fallback load the input stream.\n    if (!get_option(variables, BX_HELP_VARIABLE))\n        instance_.load_fallbacks(input, variables);\n}\n\nbool parser::is_negative(const char *c)\n{\n    return (c[0] == '-') && c[1] != '\\0' && std::isdigit(c[1]);\n}\n\nbool parser::parse(std::string &out_error, std::istream &input,\n                   int argc, const char *argv[])\n{\n    try\n    {\n        variables_map variables;\n        size_t pos;\n        //no negative parameters\n        for (size_t i = 2; i < argc; i++)\n        {\n            std::string parameter(argv[i]);\n            if ((pos = parameter.find(':')) != std::string::npos)\n            {\n                if (is_negative(parameter.substr(0, pos).c_str()) || is_negative(parameter.erase(0, pos + 1).c_str()))\n                {\n                    out_error = \"Parameter cannot be negative.\";\n                    return false;\n                }\n            }\n            else\n            {\n                if (is_negative(argv[i]))\n                {\n                    out_error = \"Parameter cannot be negative.\";\n                    return false;\n                }\n            }\n        }\n        // Must store before environment in order for commands to supercede.\n        load_command_variables(variables, input, argc, argv);\n\n        // Don't load rest if help is specified.\n        if (!get_option(variables, BX_HELP_VARIABLE))\n        {\n            // Must store before configuration in order to specify the path.\n            load_environment_variables(variables,\n                                       BX_ENVIRONMENT_VARIABLE_PREFIX);\n\n            // Is lowest priority, which will cause confusion if there is\n            // composition between them, which therefore should be avoided.\n            /* auto file = */ load_configuration_variables(variables,\n                                                           BX_CONFIG_VARIABLE);\n\n            // Set variable defaults, send notifications and update bound vars.\n            notify(variables);\n\n            // Set the instance defaults from config values.\n            instance_.set_defaults_from_config(variables);\n        }\n        else\n        {\n            help_ = true;\n        }\n    }\n    catch (const po::invalid_option_value &e)\n    {\n        // prevent boost from throwing 'std::out_of_range' when calling e.what()\n        // see /usr/include/boost/program_options/errors.hpp\n        // line 29 : return text.substr(text.find_first_not_of(\"-/\"));\n        // which will throw 'std::out_of_range' when text.find_first_not_of return string::npos\n        po::invalid_option_value ex{e};\n        ex.set_original_token(\"OPTION\");\n        out_error = ex.what();\n        return false;\n    }\n    catch (const po::error &e)\n    {\n        // This is obtained from boost, which circumvents our localization.\n        out_error = e.what();\n        return false;\n    }\n\n    return true;\n}\n\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/explorer/utility.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/explorer/utility.hpp>\n\n#include <algorithm>\n#include <iomanip>\n#include <iostream>\n#include <random>\n#include <cstdint>\n#include <mutex>\n#include <string>\n#include <thread>\n#include <tuple>\n#include <vector>\n#include <boost/date_time.hpp>\n#include <boost/filesystem.hpp>\n#include <boost/format.hpp>\n#include <boost/lexical_cast.hpp>\n#include <boost/algorithm/string.hpp>\n#include <boost/algorithm/string/predicate.hpp>\n#include <UChain/client.hpp>\n#include <UChain/explorer/command.hpp>\n#include <UChain/explorer/define.hpp>\n\nusing namespace bc::client;\nusing boost::filesystem::path;\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\n\nconnection_type get_connection(const command &cmd)\n{\n    connection_type connection;\n    connection.retries = cmd.get_server_connect_retries_setting();\n    connection.timeout_seconds = cmd.get_server_connect_timeout_seconds_setting();\n    connection.server = cmd.get_server_url_setting();\n    connection.server_public_key = cmd.get_server_server_public_key_setting();\n    connection.client_private_key = cmd.get_server_client_private_key_setting();\n    return connection;\n}\n\n// The key may be invalid, caller may test for null secret.\nec_secret new_key(const data_chunk &seed)\n{\n    const bc::wallet::hd_private key(seed);\n    return key.secret();\n}\n\n// Not testable due to lack of random engine injection.\ndata_chunk new_seed(size_t bitlength)\n{\n    size_t fill_seed_size = bitlength / byte_bits;\n    data_chunk seed(fill_seed_size);\n    random_fill(seed);\n    return seed;\n}\n\nstd::vector<std::string> numbers_to_strings(\n    const chain::point::indexes &indexes)\n{\n    std::vector<std::string> stringlist;\n    for (const auto index : indexes)\n        stringlist.push_back(std::to_string(index));\n\n    return stringlist;\n}\n\n// Not testable due to lack of random engine injection.\n// DEPRECATED in favor of libbitcoin::pseudo_random_fill.\nvoid random_fill(data_chunk &chunk)\n{\n    pseudo_random_fill(chunk);\n}\n\n// TODO: switch to binary for raw (primitive) reads in windows.\nstd::string read_stream(std::istream &stream)\n{\n    std::istreambuf_iterator<char> first(stream), last;\n    std::string result(first, last);\n    return result;\n}\n\nname_value_pairs split_pairs(const std::vector<std::string> tokens,\n                             const std::string delimiter)\n{\n    name_value_pairs list;\n\n    for (const auto &token : tokens)\n    {\n        const auto words = split(token, delimiter);\n        const auto &left = words[0];\n\n        std::string right;\n        if (words.size() > 1)\n            right = words[1];\n\n        list.push_back(std::make_pair(left, right));\n    }\n\n    return list;\n}\n\nbool starts_with(const std::string &value, const std::string &prefix)\n{\n    try\n    {\n        return boost::istarts_with(value, prefix);\n    }\n    catch (boost::bad_lexical_cast)\n    {\n        return false;\n    }\n}\n\n// This verifies the checksum.\nbool unwrap(bc::wallet::wrapped_data &data, data_slice wrapped)\n{\n    if (!verify_checksum(wrapped))\n        return false;\n\n    data.version = wrapped.data()[0];\n    const auto payload_begin = std::begin(wrapped) + 1;\n    const auto checksum_begin = std::end(wrapped) - checksum_size;\n    data.payload.resize(checksum_begin - payload_begin);\n    std::copy(payload_begin, checksum_begin, data.payload.begin());\n    data.checksum = from_little_endian_unsafe<uint32_t>(checksum_begin);\n    return true;\n}\n\n// This recalculates the checksum, ignoring what is in data.checksum.\ndata_chunk wrap(const bc::wallet::wrapped_data &data)\n{\n    auto bytes = to_chunk(data.version);\n    extend_data(bytes, data.payload);\n    append_checksum(bytes);\n    return bytes;\n}\n\nstd::ostream &write_stream(std::ostream &output, const Json::Value &tree,\n                           encoding_engine engine)\n{\n    switch (engine)\n    {\n    case encoding_engine::json:\n        output << tree.toStyledString();\n        break;\n    default:\n        output << tree.toStyledString();\n        break;\n    }\n\n    return output;\n}\n\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/CMakeLists.txt",
    "content": "FILE(GLOB_RECURSE network_SOURCES \"*.cpp\")\n\nADD_DEFINITIONS(-DBCT_STATIC=1)\n# gcc-6 boost/multiprecision/cpp_int.hpp:181\nSET(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fpermissive\")\n\nIF(USE_UPNP)\n    IF(ENABLE_SHARED_LIBS)\n        ADD_LIBRARY(miniupnpc_shared SHARED IMPORTED)\n        SET_TARGET_PROPERTIES(miniupnpc_shared PROPERTIES IMPORTED_LOCATION ${miniupnpc_ROOT_DIR}/lib/libminiupnpc.so)\n    ELSE()\n        ADD_LIBRARY(miniupnpc_static STATIC IMPORTED)\n        SET_TARGET_PROPERTIES(miniupnpc_static PROPERTIES IMPORTED_LOCATION ${miniupnpc_ROOT_DIR}/lib/libminiupnpc.a)\n    ENDIF()\nENDIF()\n\nADD_LIBRARY(network_static STATIC ${network_SOURCES})\nSET_TARGET_PROPERTIES(network_static PROPERTIES OUTPUT_NAME uc_network)\nTARGET_LINK_LIBRARIES(network_static ${Boost_LIBRARIES} ${miniupnpc_LIBRARY})\nINSTALL(TARGETS network_static DESTINATION lib)\n\nIF(ENABLE_SHARED_LIBS)\n    ADD_DEFINITIONS(-DBCT_DLL=1)\n  ADD_LIBRARY(network_shared SHARED ${network_SOURCES})\n  SET_TARGET_PROPERTIES(network_shared PROPERTIES OUTPUT_NAME uc_network)\n  TARGET_LINK_LIBRARIES(network_shared ${Boost_LIBRARIES} ${miniupnpc_LIBRARY})\n  INSTALL(TARGETS network_shared DESTINATION lib)\nENDIF()\n"
  },
  {
    "path": "src/UChain/network/acceptor.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/acceptor.hpp>\n\n#include <cstdint>\n#include <functional>\n#include <iostream>\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/proxy.hpp>\n#include <UChain/network/settings.hpp>\n#include <UChain/network/socket.hpp>\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\n#define NAME \"acceptor\"\n\nusing namespace std::placeholders;\n\nstatic const auto reuse_address = asio::acceptor::reuse_address(true);\n\nacceptor::acceptor(threadpool &pool, const settings &settings)\n    : pool_(pool),\n      settings_(settings),\n      dispatch_(pool, NAME),\n      acceptor_(std::make_shared<asio::acceptor>(pool_.service())),\n      CONSTRUCT_TRACK(acceptor)\n{\n}\n\nacceptor::~acceptor()\n{\n    BITCOIN_ASSERT_MSG(!acceptor_->is_open(), \"The acceptor was not stopped.\");\n}\n\n// Stop sequence.\n// ----------------------------------------------------------------------------\n\n// public:\nvoid acceptor::stop()\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    unique_lock lock(mutex_);\n\n    // This will asynchronously invoke the handler of each pending accept.\n    acceptor_->close();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n// Listen sequence.\n// ----------------------------------------------------------------------------\n\n// public:\n// This is hardwired to listen on IPv6.\nvoid acceptor::listen(uint16_t port, result_handler handler)\n{\n    // This is the end of the listen sequence.\n    handler(safe_listen(port));\n}\n\ncode acceptor::safe_listen(uint16_t port)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    unique_lock lock(mutex_);\n\n    if (acceptor_->is_open())\n        return error::operation_failed;\n\n    boost_code error;\n    asio::endpoint endpoint(asio::tcp::v6(), settings_.inbound_port);\n\n    acceptor_->open(endpoint.protocol(), error);\n\n    if (!error)\n        acceptor_->set_option(reuse_address, error);\n\n    if (!error)\n        acceptor_->bind(endpoint, error);\n\n    if (!error)\n        acceptor_->listen(asio::max_connections, error);\n\n    return error::boost_to_error_code(error);\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n// Accept sequence.\n// ----------------------------------------------------------------------------\n\n// public:\nvoid acceptor::accept(accept_handler handler)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    mutex_.lock();\n\n    if (!acceptor_->is_open())\n    {\n        dispatch_.concurrent(handler, error::service_stopped, nullptr);\n        mutex_.unlock();\n        //---------------------------------------------------------------------\n        return;\n    }\n\n    const auto socket = std::make_shared<network::socket>(pool_);\n    safe_accept(socket, handler);\n\n    mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid acceptor::safe_accept(socket::ptr socket, accept_handler handler)\n{\n    // Critical Section (external)\n    ///////////////////////////////////////////////////////////////////////////\n    const auto locked = socket->get_socket();\n\n    // async_accept will not invoke the handler within this function.\n    acceptor_->async_accept(locked->get(),\n                            std::bind(&acceptor::handle_accept,\n                                      shared_from_this(), _1, socket, handler));\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid acceptor::handle_accept(const boost_code &ec, socket::ptr socket,\n                             accept_handler handler)\n{\n    // This is the end of the accept sequence.\n    if (ec)\n        handler(error::boost_to_error_code(ec), nullptr);\n    else\n        handler(error::success, new_channel(socket));\n}\n\nstd::shared_ptr<channel> acceptor::new_channel(socket::ptr socket)\n{\n    return std::make_shared<channel>(pool_, socket, settings_);\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/channel.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/channel.hpp>\n\n#include <atomic>\n#include <cstddef>\n#include <cstdint>\n#include <functional>\n#include <memory>\n#include <utility>\n#include <UChain/coin.hpp>\n#include <UChain/network/proxy.hpp>\n#include <UChain/network/settings.hpp>\n#include <UChain/network/socket.hpp>\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\nusing namespace bc::message;\nusing namespace std::placeholders;\n\n// Factory for deadline timer pointer construction.\nstatic deadline::ptr alarm(threadpool &pool, const asio::duration &duration)\n{\n    return std::make_shared<deadline>(pool, pseudo_randomize(duration));\n}\n\n// TODO: configure settings.protocol_maximum and settings.protocol_minimum.\n// Limit to version::limit::maximum and version::limit::minimum respectively\n// and if protocol_maximum is then below protocol_minimum return a failure.\n// On handshake send peer version.maxiumum and on receipt of protocol_peer\n// if it is below protocol_minimum drop the channel, otherwise set\n// protocol_version to the lesser of protocol_maximum and protocol_peer.\nchannel::channel(threadpool &pool, socket::ptr socket,\n                 const settings &settings)\n    : proxy(pool, socket, settings.identifier, settings.protocol),\n      notify_(false),\n      nonce_(0),\n      expiration_(alarm(pool, settings.channel_expiration())),\n      inactivity_(alarm(pool, settings.channel_inactivity())),\n      CONSTRUCT_TRACK(channel)\n{\n}\n\n// Talk sequence.\n// ----------------------------------------------------------------------------\n\n// public:\nvoid channel::start(result_handler handler)\n{\n    proxy::start(\n        std::bind(&channel::do_start,\n                  shared_from_base<channel>(), _1, handler));\n}\n\n// Don't start the timers until the socket is enabled.\nvoid channel::do_start(const code &ec, result_handler handler)\n{\n    start_expiration();\n    start_inactivity();\n    handler(error::success);\n}\n\n// Properties (version write is thread unsafe, isolate from read).\n// ----------------------------------------------------------------------------\n\nbool channel::notify() const\n{\n    return notify_;\n}\n\nvoid channel::set_notify(bool value)\n{\n    notify_ = value;\n}\n\nuint64_t channel::nonce() const\n{\n    return nonce_;\n}\n\nvoid channel::set_nonce(uint64_t value)\n{\n    nonce_ = value;\n}\n\nvoid channel::set_protocol_start_handler(std::function<void()> handler)\n{\n    protocol_start_handler_ = std::move(handler);\n}\n\nvoid channel::invoke_protocol_start_handler(const code &ec)\n{\n    std::function<void()> func;\n    {\n        unique_lock lock{mutex_};\n        if (!protocol_start_handler_)\n            return;\n        if (ec)\n        {\n            protocol_start_handler_ = nullptr;\n            return;\n        }\n\n        func = std::move(protocol_start_handler_);\n        protocol_start_handler_ = nullptr;\n    }\n    func();\n}\n\n// Proxy pure virtual protected and ordered handlers.\n// ----------------------------------------------------------------------------\n\n// It is possible that this may be called multiple times.\nvoid channel::handle_stopping()\n{\n    invoke_protocol_start_handler(error::channel_stopped);\n    expiration_->stop();\n    inactivity_->stop();\n}\n\nvoid channel::handle_activity()\n{\n    start_inactivity();\n}\n\n// Timers (these are inherent races, requiring stranding by stop only).\n// ----------------------------------------------------------------------------\n\nvoid channel::start_expiration()\n{\n    if (stopped())\n        return;\n\n    expiration_->start(\n        std::bind(&channel::handle_expiration,\n                  shared_from_base<channel>(), _1));\n    if (stopped())\n        expiration_->stop();\n}\n\nvoid channel::handle_expiration(const code &ec)\n{\n    if (stopped())\n    {\n        return;\n    }\n\n    log::debug(LOG_NETWORK)\n        << \"Channel lifetime expired [\" << authority() << \"]\";\n\n    stop(error::channel_timeout);\n}\n\nvoid channel::start_inactivity()\n{\n    if (stopped())\n        return;\n\n    inactivity_->start(\n        std::bind(&channel::handle_inactivity,\n                  shared_from_base<channel>(), _1));\n    if (stopped())\n        inactivity_->stop();\n}\n\nvoid channel::handle_inactivity(const code &ec)\n{\n    if (stopped())\n    {\n        return;\n    }\n\n    log::debug(LOG_NETWORK)\n        << \"Channel inactivity timeout [\" << authority() << \"]\";\n\n    stop(error::channel_timeout);\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/connections.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/connections.hpp>\n\n#include <algorithm>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\nusing namespace bc::config;\n\n#define NAME \"connections\"\n\nconnections::connections()\n    : stopped_(false)\n{\n}\n\nconnections::~connections()\n{\n    BITCOIN_ASSERT_MSG(channels_.empty(), \"Connections was not cleared.\");\n}\n\n// This is idempotent.\nvoid connections::stop(const code &ec)\n{\n    connections::list channels;\n\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    mutex_.lock_upgrade();\n\n    if (!stopped_)\n    {\n        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n        mutex_.unlock_upgrade_and_lock();\n        stopped_ = true;\n        mutex_.unlock_and_lock_upgrade();\n        //---------------------------------------------------------------------\n\n        // Once stopped this list cannot change, but must copy to escape lock.\n        channels = channels_;\n    }\n\n    mutex_.unlock_upgrade();\n    ///////////////////////////////////////////////////////////////////////////\n\n    // Channel stop handlers should remove channels from list.\n    for (const auto channel : channels)\n        channel->stop(ec);\n}\n\nconnections::list connections::safe_copy() const\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    shared_lock lock(mutex_);\n\n    return channels_;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nbool connections::safe_exists(const authority &address) const\n{\n    const auto match = [&address](channel::ptr entry) {\n        return entry->authority() == address;\n    };\n\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    shared_lock lock(mutex_);\n\n    const auto it = std::find_if(channels_.begin(), channels_.end(), match);\n    return it != channels_.end();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid connections::exists(const authority &address, truth_handler handler) const\n{\n    handler(safe_exists(address));\n}\n\nconfig::authority::list connections::authority_list()\n{\n    config::authority::list address_list;\n    address_list.reserve(channels_.size());\n    mutex_.lock_upgrade();\n    std::find_if(channels_.begin(), channels_.end(), [&address_list](channel::ptr channel) {\n        address_list.push_back(channel->authority());\n        return false;\n    });\n    mutex_.unlock_upgrade();\n    return address_list;\n}\n\nbool connections::safe_remove(channel::ptr channel)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    mutex_.lock_upgrade();\n\n    const auto it = std::find(channels_.begin(), channels_.end(), channel);\n    const auto found = it != channels_.end();\n\n    if (found)\n    {\n        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n        mutex_.unlock_upgrade_and_lock();\n        channels_.erase(it);\n        mutex_.unlock();\n        //---------------------------------------------------------------------\n        return true;\n    }\n\n    mutex_.unlock_upgrade();\n    ///////////////////////////////////////////////////////////////////////////\n\n    return false;\n}\n\nvoid connections::remove(channel::ptr channel, result_handler handler)\n{\n    handler(safe_remove(channel) ? error::success : error::not_found);\n}\n\nvoid connections::stop(const config::authority &address)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    shared_lock lock(mutex_);\n\n    for (auto it = channels_.begin(); it != channels_.end(); ++it)\n    {\n        if ((*it)->authority().ip() == address.ip())\n        {\n            (*it)->stop(error::address_blocked);\n        }\n    }\n}\n\ncode connections::safe_store(channel::ptr channel)\n{\n    const auto nonce = channel->nonce();\n    const auto &authority = channel->authority();\n    const auto match = [&authority, nonce](channel::ptr entry) {\n        return entry->authority() == authority || entry->nonce() == nonce;\n    };\n\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    mutex_.lock_upgrade();\n\n    const auto stopped = stopped_.load();\n\n    if (!stopped)\n    {\n        auto it = std::find_if(channels_.begin(), channels_.end(), match);\n        const auto found = it != channels_.end();\n\n        if (!found)\n        {\n            //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n            mutex_.unlock_upgrade_and_lock();\n            channels_.push_back(channel);\n            mutex_.unlock();\n            //-----------------------------------------------------------------\n            return error::success;\n        }\n    }\n\n    mutex_.unlock_upgrade();\n    ///////////////////////////////////////////////////////////////////////////\n\n    // Stopped and found are the only ways to get here.\n    return stopped ? error::service_stopped : error::address_in_use;\n}\n\nvoid connections::store(channel::ptr channel, result_handler handler)\n{\n    handler(safe_store(channel));\n}\n\nsize_t connections::safe_count() const\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    shared_lock lock(mutex_);\n\n    return channels_.size();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid connections::count(count_handler handler) const\n{\n    handler(safe_count());\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/connector.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/connector.hpp>\n\n#include <cstdint>\n#include <functional>\n#include <memory>\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/proxy.hpp>\n#include <UChain/network/settings.hpp>\n#include <UChain/network/socket.hpp>\n#include <boost/format.hpp>\n#include <boost/regex.hpp>\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\n#define NAME \"connector\"\n\nusing namespace bc::config;\nusing namespace std::placeholders;\n\n// The resolver_, pending_, and stopped_ members are protected.\n\nconnector::connector(threadpool &pool, const settings &settings)\n    : stopped_(false),\n      pool_(pool),\n      settings_(settings),\n      dispatch_(pool, NAME),\n      resolver_(std::make_shared<asio::resolver>(pool.service())),\n      CONSTRUCT_TRACK(connector)\n{\n}\n\n// Stop sequence.\n// ----------------------------------------------------------------------------\n\n// public:\nvoid connector::stop()\n{\n    safe_stop();\n    pending_.clear();\n}\n\nvoid connector::safe_stop()\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    mutex_.lock_upgrade();\n\n    if (!stopped_)\n    {\n        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n        mutex_.unlock_upgrade_and_lock();\n\n        // This will asynchronously invoke the handler of each pending resolve.\n        resolver_->cancel();\n        stopped_ = true;\n\n        mutex_.unlock();\n        //---------------------------------------------------------------------\n        return;\n    }\n\n    mutex_.unlock_upgrade();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nbool connector::stopped()\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    shared_lock lock(mutex_);\n\n    return stopped_;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n// Connect sequence.\n// ----------------------------------------------------------------------------\n\n// public:\nvoid connector::connect(const endpoint &endpoint, connect_handler handler, resolve_handler h)\n{\n    connect(endpoint.host(), endpoint.port(), handler, h);\n}\n\nstatic std::string to_ipv4_hostname(const asio::address &ip_address)\n{\n    // std::regex requires gcc 4.9, so we are using boost::regex for now.\n    static const boost::regex regular(\"^::ffff:([0-9\\\\.]+)$\");\n\n    const auto address = ip_address.to_string();\n    boost::sregex_iterator it(address.begin(), address.end(), regular), end;\n    if (it == end)\n        return \"\";\n\n    const auto &match = *it;\n    return match[1];\n}\n\nstatic std::string to_ipv6(const std::string &ipv4_address)\n{\n    return std::string(\"::ffff:\") + ipv4_address;\n}\n\nstatic asio::ipv6 to_ipv6(const asio::ipv4 &ipv4_address)\n{\n    // Create an IPv6 mapped IPv4 address via serialization.\n    const auto ipv6 = to_ipv6(ipv4_address.to_string());\n    return asio::ipv6::from_string(ipv6);\n}\n\nstatic asio::ipv6 to_ipv6(const asio::address &ip_address)\n{\n    if (ip_address.is_v6())\n        return ip_address.to_v6();\n\n    BITCOIN_ASSERT_MSG(ip_address.is_v4(),\n                       \"The address must be either IPv4 or IPv6.\");\n\n    return to_ipv6(ip_address.to_v4());\n}\n\nstatic std::string to_ipv6_hostname(const asio::address &ip_address)\n{\n    // IPv6 URLs use a bracketed IPv6 address, see rfc2732.\n    const auto hostname = boost::format(\"%1%\") % to_ipv6(ip_address);\n    return hostname.str();\n}\n\nstatic asio::ipv6 to_boost_address(const message::ip_address &in)\n{\n    asio::ipv6::bytes_type bytes;\n    BITCOIN_ASSERT(bytes.size() == in.size());\n    std::copy(in.begin(), in.end(), bytes.begin());\n    const asio::ipv6 out(bytes);\n    return out;\n}\n\n// public:\nvoid connector::connect(const authority &authority, connect_handler handler, resolve_handler h)\n{\n    //    connect(authority.to_hostname(), authority.port(), handler, h);\n    auto ip = to_boost_address(authority.ip());\n    auto ipv4_hostname = to_ipv4_hostname(ip);\n    connect(ipv4_hostname.empty() ? to_ipv6_hostname(ip) : ipv4_hostname, authority.port(), handler, h);\n}\n\n// public:\nvoid connector::connect(const std::string &hostname, uint16_t port,\n                        connect_handler handler, resolve_handler h)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    mutex_.lock_upgrade();\n\n    if (stopped_)\n    {\n        // We preserve the asynchronous contract of the async_resolve.\n        // Dispatch ensures job does not execute in the current thread.\n        dispatch_.concurrent(handler, error::service_stopped, nullptr);\n        mutex_.unlock_upgrade();\n        //---------------------------------------------------------------------\n        return;\n    }\n    auto query = std::make_shared<asio::query>(hostname, std::to_string(port));\n\n    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n    mutex_.unlock_upgrade_and_lock();\n\n    // async_resolve will not invoke the handler within this function.\n    resolver_->async_resolve(*query,\n                             std::bind(&connector::handle_resolve,\n                                       shared_from_this(), _1, _2, handler, h));\n\n    mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid connector::handle_resolve(const boost_code &ec, asio::iterator iterator,\n                               connect_handler handler, resolve_handler h)\n{\n    auto it = iterator;\n    asio::iterator end;\n    if (h)\n    {\n        while (it != end)\n        {\n            h(*it);\n            ++it;\n        }\n    }\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    mutex_.lock_shared();\n\n    if (stopped_)\n    {\n        dispatch_.concurrent(handler, error::service_stopped, nullptr);\n        mutex_.unlock_shared();\n        //---------------------------------------------------------------------\n        return;\n    }\n\n    if (ec)\n    {\n        dispatch_.concurrent(handler, error::resolve_failed, nullptr);\n        mutex_.unlock_shared();\n        //---------------------------------------------------------------------\n        return;\n    }\n\n    auto do_connecting = [this, &handler](asio::iterator resolver_iterator) {\n        const auto timeout = settings_.connect_timeout();\n        const auto timer = std::make_shared<deadline>(pool_, timeout);\n        const auto socket = std::make_shared<network::socket>(pool_);\n\n        // Retain a socket reference until connected, allowing connect cancelation.\n        pending_.store(socket);\n\n        // Manage the socket-timer race, terminating if either fails.\n        const auto handle_connect = synchronize(handler, 1, NAME, false);\n\n        // This is branch #1 of the connnect sequence.\n        timer->start(\n            std::bind(&connector::handle_timer,\n                      shared_from_this(), _1, socket, handle_connect));\n        safe_connect(resolver_iterator, socket, timer, handle_connect);\n    };\n\n    // Get all hosts under one DNS record.\n    for (asio::iterator end; iterator != end; ++iterator)\n    {\n        do_connecting(iterator);\n        break; // FIXME. -, can not query all hosts, caused by loop fastly\n    }\n\n    mutex_.unlock_shared();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid connector::safe_connect(asio::iterator iterator, socket::ptr socket,\n                             deadline::ptr timer, connect_handler handler)\n{\n    // Critical Section (external)\n    ///////////////////////////////////////////////////////////////////////////\n    const auto locked = socket->get_socket();\n\n    // This is branch #2 of the connnect sequence.\n    using namespace boost::asio;\n    ip::tcp::endpoint endpoint = *iterator;\n\n    locked->get().async_connect(endpoint,\n                                std::bind(&connector::handle_connect,\n                                          shared_from_this(), _1, socket, timer, handler));\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n// Timer sequence.\n// ----------------------------------------------------------------------------\n\n// private:\nvoid connector::handle_timer(const code &ec, socket::ptr socket,\n                             connect_handler handler)\n{\n    // This is the end of the timer sequence.\n    if (ec)\n        handler(ec, nullptr);\n    else\n        handler(error::channel_timeout, nullptr);\n\n    socket->close();\n}\n\n// Connect sequence.\n// ----------------------------------------------------------------------------\n\n// private:\nvoid connector::handle_connect(const boost_code &ec,\n                               socket::ptr socket, deadline::ptr timer, connect_handler handler)\n{\n    pending_.remove(socket);\n    // This is the end of the connect sequence.\n    if (ec)\n        handler(error::boost_to_error_code(ec), nullptr);\n    else\n        handler(error::success, new_channel(socket));\n\n    timer->stop();\n}\n\nstd::shared_ptr<channel> connector::new_channel(socket::ptr socket)\n{\n    return std::make_shared<channel>(pool_, socket, settings_);\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/const_buffer.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/const_buffer.hpp>\n\n#include <memory>\n#include <utility>\n#include <UChain/coin.hpp>\n#include <UChain/network/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\nconst_buffer::const_buffer()\n    : data_(std::make_shared<data_chunk>()),\n      buffer_(boost::asio::buffer(*data_))\n{\n}\n\nconst_buffer::const_buffer(data_chunk &&data)\n    : data_(std::make_shared<data_chunk>(std::forward<data_chunk>(data))),\n      buffer_(boost::asio::buffer(*data_))\n{\n}\n\nconst_buffer::const_buffer(const data_chunk &data)\n    : data_(std::make_shared<data_chunk>(data)),\n      buffer_(boost::asio::buffer(*data_))\n{\n}\n\nsize_t const_buffer::size() const\n{\n  return data_->size();\n}\n\nconst_buffer::const_iterator const_buffer::begin() const\n{\n  return &buffer_;\n}\n\nconst_buffer::const_iterator const_buffer::end() const\n{\n  return &buffer_ + 1;\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/hosts.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/hosts.hpp>\n\n#include <algorithm>\n#include <cstddef>\n#include <string>\n#include <vector>\n#include <UChainService/txs/utility/path.hpp>\n#include <UChain/network/settings.hpp>\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\n#define NAME \"hosts\"\n\nhosts::hosts(threadpool &pool, const settings &settings)\n    : stopped_(true),\n      dispatch_(pool, NAME),\n      file_path_(settings.hosts_file == \"hosts.cache\" ? (default_data_path() / settings.hosts_file) : settings.hosts_file),\n      disabled_(settings.host_pool_capacity == 0),\n      pool_(pool),\n      seed_count(settings.seeds.size())\n{\n    //    buffer_.reserve(std::max(settings.host_pool_capacity, 1u));\n}\n\n// private\nhosts::iterator hosts::find(const address &host)\n{\n    const auto found = [&host](const address &entry) {\n        return entry.port == host.port && entry.ip == host.ip;\n    };\n    return buffer_.find(host);\n    //    return std::find_if(buffer_.begin(), buffer_.end(), found);\n}\n\nsize_t hosts::count() const\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    shared_lock lock(mutex_);\n\n    return buffer_.size();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nstatic std::atomic<uint64_t> fetch_times{0};\n\nstatic std::vector<config::authority> hosts_{config::authority(\"198.199.84.199:5252\")};\n\ncode hosts::fetch(address &out, const config::authority::list &excluded_list)\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    shared_lock lock(mutex_);\n    fetch_times++;\n    config::authority::list addresses;\n    list *buffer = nullptr;\n    {\n\n        if (stopped_)\n        {\n            return error::service_stopped;\n        }\n\n        if (fetch_times % 5 == 4 && !buffer_.empty())\n            buffer = &buffer_;\n        else\n            buffer = &inactive_;\n    }\n\n    for (auto entry : *buffer)\n    {\n        auto iter = std::find(excluded_list.begin(), excluded_list.end(), config::authority(entry));\n        if (iter == excluded_list.end())\n        {\n            addresses.push_back(config::authority(entry));\n        }\n    }\n\n    if (addresses.empty())\n    {\n        if (inactive_.empty())\n        {\n            return error::not_found;\n        }\n        const auto index = static_cast<size_t>(pseudo_random() % inactive_.size());\n\n        size_t i = 0;\n        for (const auto &entry : inactive_)\n        {\n            if (i == index)\n            {\n                out = entry;\n                break;\n            }\n            i++;\n        }\n\n        return error::success;\n    }\n\n    const auto index = static_cast<size_t>(pseudo_random() % addresses.size());\n    out = addresses[index].to_network_address();\n\n    //    const auto index = static_cast<size_t>(pseudo_random() % hosts_.size());\n    //    out = hosts_[index].to_network_address();\n    return error::success;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nhosts::address::list hosts::copy()\n{\n    address::list copy;\n\n    shared_lock lock{mutex_};\n    copy.reserve(buffer_.size());\n    for (auto &h : buffer_)\n    {\n        copy.push_back(h);\n    }\n    return copy;\n}\n\nvoid hosts::handle_timer(const code &ec)\n{\n    if (ec.value() != error::success)\n    {\n        return;\n    }\n\n    mutex_.lock_upgrade();\n\n    if (stopped_)\n    {\n        mutex_.unlock_upgrade();\n        return;\n    }\n\n    mutex_.unlock_upgrade_and_lock();\n    bc::ofstream file(file_path_.string());\n    const auto file_error = file.bad();\n\n    if (!file_error)\n    {\n        log::debug(LOG_NETWORK) << \"sync hosts to file(\" << file_path_.string() << \"), active hosts size is \"\n                                << buffer_.size() << \" hosts found, inactive hosts size is \" << inactive_.size();\n        for (const auto &entry : buffer_)\n            file << config::authority(entry) << std::endl;\n        for (const auto &entry : inactive_)\n            file << config::authority(entry) << std::endl;\n    }\n    else\n    {\n        log::error(LOG_NETWORK) << \"hosts file (\" << file_path_.string() << \") open failed\";\n        mutex_.unlock();\n        return;\n    }\n\n    mutex_.unlock();\n    snap_timer_->start(std::bind(&hosts::handle_timer, shared_from_this(), std::placeholders::_1));\n}\n\n// load\ncode hosts::start()\n{\n    if (disabled_)\n        return error::success;\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    mutex_.lock_upgrade();\n\n    if (!stopped_)\n    {\n        mutex_.unlock_upgrade();\n        //---------------------------------------------------------------------\n        return error::operation_failed;\n    }\n\n    mutex_.unlock_upgrade_and_lock();\n    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n    snap_timer_ = std::make_shared<deadline>(pool_, asio::seconds(60));\n    snap_timer_->start(std::bind(&hosts::handle_timer, shared_from_this(), std::placeholders::_1));\n    stopped_ = false;\n    bc::ifstream file(file_path_.string());\n    const auto file_error = file.bad();\n\n    if (!file_error)\n    {\n        std::string line;\n\n        while (std::getline(file, line))\n        {\n            config::authority host(line);\n\n            if (host.port() != 0)\n            {\n                auto network_address = host.to_network_address();\n                if (network_address.is_routable())\n                {\n                    inactive_.insert(network_address);\n                }\n                else\n                {\n                    log::debug(LOG_NETWORK) << \"host start is not routable,\" << config::authority{network_address};\n                }\n            }\n        }\n    }\n\n    mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n\n    if (file_error)\n    {\n        log::debug(LOG_NETWORK)\n            << \"Failed to save hosts file.\";\n        return error::file_system;\n    }\n\n    return error::success;\n}\n\n// load\ncode hosts::stop()\n{\n    if (disabled_)\n        return error::success;\n\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    mutex_.lock_upgrade();\n\n    if (stopped_)\n    {\n        mutex_.unlock_upgrade();\n        //---------------------------------------------------------------------\n        return error::success;\n    }\n\n    mutex_.unlock_upgrade_and_lock();\n    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n    snap_timer_->stop();\n    stopped_ = true;\n    bc::ofstream file(file_path_.string());\n    const auto file_error = file.bad();\n\n    if (!file_error)\n    {\n        for (const auto &entry : buffer_)\n            file << config::authority(entry) << std::endl;\n\n        buffer_.clear();\n    }\n\n    mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n\n    if (file_error)\n    {\n        log::debug(LOG_NETWORK)\n            << \"Failed to load hosts file.\";\n        return error::file_system;\n    }\n\n    return error::success;\n}\n\ncode hosts::clear()\n{\n    // Critical Section\n    mutex_.lock_upgrade();\n\n    if (stopped_)\n    {\n        mutex_.unlock_upgrade();\n        //---------------------------------------------------------------------\n        return error::service_stopped;\n    }\n\n    mutex_.unlock_upgrade_and_lock();\n\n    // if the buffer is already moved to backup, call this function again will lead to the loss of backup.\n    // backup_ = std::move( buffer_ );\n    for (auto &host : buffer_)\n    {\n        backup_.insert(host);\n    }\n    buffer_.clear();\n\n    mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n\n    return error::success;\n}\n\ncode hosts::after_reseeding()\n{\n    mutex_.lock_upgrade();\n\n    if (stopped_)\n    {\n        mutex_.unlock_upgrade();\n        //---------------------------------------------------------------------\n        return error::service_stopped;\n    }\n\n    mutex_.unlock_upgrade_and_lock();\n    //re-seeding failed and recover the buffer with backup one\n    if (buffer_.size() <= seed_count)\n    {\n        log::warning(LOG_NETWORK) << \"Reseeding finished, but got address list: \" << buffer_.size() << \", less than seed count: \"\n                                  << seed_count << \", roll back the hosts cache.\";\n        buffer_ = std::move(backup_);\n    }\n    else\n    {\n        // filter inactive hosts\n        for (auto &host : inactive_)\n        {\n            auto iter = buffer_.find(host);\n            if (iter != buffer_.end())\n            {\n                buffer_.erase(iter);\n            }\n        }\n\n        // clear the backup\n        backup_.clear();\n    }\n\n    log::debug(LOG_NETWORK) << \"Reseeding finished, and got addresses of count: \" << buffer_.size();\n\n    mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n\n    return error::success;\n}\n\ncode hosts::remove(const address &host)\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    mutex_.lock_upgrade();\n\n    if (stopped_)\n    {\n        mutex_.unlock_upgrade();\n        //---------------------------------------------------------------------\n        return error::service_stopped;\n    }\n\n    auto it = find(host);\n\n    if (it != buffer_.end())\n    {\n        mutex_.unlock_upgrade_and_lock();\n        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n        buffer_.erase(it);\n\n        mutex_.unlock();\n        //---------------------------------------------------------------------\n        return error::success;\n    }\n\n    mutex_.unlock_upgrade_and_lock();\n    auto iter = inactive_.find(host);\n    if (iter == inactive_.end())\n    {\n        inactive_.insert(host);\n    }\n    mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n\n    return error::success;\n}\n\ncode hosts::store(const address &host)\n{\n    if (!host.is_routable())\n    {\n        // We don't treat invalid address as an error, just log it.\n        return error::success;\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    mutex_.lock_upgrade();\n\n    if (stopped_)\n    {\n        mutex_.unlock_upgrade();\n        //---------------------------------------------------------------------\n        return error::service_stopped;\n    }\n\n    if (find(host) == buffer_.end())\n    {\n        mutex_.unlock_upgrade_and_lock();\n        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n        buffer_.insert(host);\n        auto iter = inactive_.find(host);\n        if (iter != inactive_.end())\n        {\n            inactive_.erase(iter);\n        }\n\n        mutex_.unlock();\n        //---------------------------------------------------------------------\n        return error::success;\n    }\n\n    mutex_.unlock_upgrade();\n    ///////////////////////////////////////////////////////////////////////////\n\n    //    log::trace(LOG_NETWORK)\n    //        << \"Redundant host address from peer\";\n\n    // We don't treat redundant address as an error, just log it.\n    return error::success;\n}\n\n// private\nvoid hosts::do_store(const address &host, result_handler handler)\n{\n    handler(store(host));\n}\n\n// The handler is invoked once all calls to do_store are completed.\n// We disperse here to allow other addresses messages to interleave hosts.\nvoid hosts::store(const address::list &hosts, result_handler handler)\n{\n    if (stopped_)\n        return;\n\n    dispatch_.parallel(hosts, \"hosts\", handler,\n                       &hosts::do_store, shared_from_this());\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/locked_socket.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/locked_socket.hpp>\n\n#include <UChain/coin.hpp>\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\nlocked_socket::locked_socket(asio::socket &socket, upgrade_mutex &mutex)\n    : socket_(socket),\n      mutex_(mutex),\n      CONSTRUCT_TRACK(locked_socket)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    mutex_.lock();\n}\n\nasio::socket &locked_socket::get()\n{\n    return socket_;\n}\n\nlocked_socket::~locked_socket()\n{\n    mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/message_subscriber.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/message_subscriber.hpp>\n\n#include <istream>\n#include <memory>\n#include <string>\n#include <UChain/coin.hpp>\n\n#define INITIALIZE_SUBSCRIBER(pool, value)                         \\\n    value##_subscriber_(std::make_shared<value##_subscriber_type>( \\\n        pool, #value \"_sub\"))\n\n#define RELAY_CODE(code, value) \\\n    value##_subscriber_->relay(code, nullptr)\n\n#define CASE_HANDLE_MESSAGE(stream, version, value) \\\n    case message_type::value:                       \\\n        return handle<message::value>(stream, version, value##_subscriber_)\n\n#define CASE_RELAY_MESSAGE(stream, version, value) \\\n    case message_type::value:                      \\\n        return relay<message::value>(stream, version, value##_subscriber_)\n\n#define START_SUBSCRIBER(value) \\\n    value##_subscriber_->start()\n\n#define STOP_SUBSCRIBER(value) \\\n    value##_subscriber_->stop()\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\nusing namespace message;\n\nmessage_subscriber::message_subscriber(threadpool &pool)\n    : INITIALIZE_SUBSCRIBER(pool, address),\n      INITIALIZE_SUBSCRIBER(pool, block_msg),\n      INITIALIZE_SUBSCRIBER(pool, block_txs),\n      INITIALIZE_SUBSCRIBER(pool, compact_block),\n      INITIALIZE_SUBSCRIBER(pool, fee_filter),\n      INITIALIZE_SUBSCRIBER(pool, filter_add),\n      INITIALIZE_SUBSCRIBER(pool, filter_clear),\n      INITIALIZE_SUBSCRIBER(pool, filter_load),\n      INITIALIZE_SUBSCRIBER(pool, get_address),\n      INITIALIZE_SUBSCRIBER(pool, get_blocks),\n      INITIALIZE_SUBSCRIBER(pool, get_block_txs),\n      INITIALIZE_SUBSCRIBER(pool, get_data),\n      INITIALIZE_SUBSCRIBER(pool, get_headers),\n      INITIALIZE_SUBSCRIBER(pool, headers),\n      INITIALIZE_SUBSCRIBER(pool, inventory),\n      INITIALIZE_SUBSCRIBER(pool, memory_pool),\n      INITIALIZE_SUBSCRIBER(pool, merkle_block),\n      INITIALIZE_SUBSCRIBER(pool, not_found),\n      INITIALIZE_SUBSCRIBER(pool, ping),\n      INITIALIZE_SUBSCRIBER(pool, pong),\n      INITIALIZE_SUBSCRIBER(pool, reject),\n      INITIALIZE_SUBSCRIBER(pool, send_headers),\n      INITIALIZE_SUBSCRIBER(pool, send_compact_blocks),\n      INITIALIZE_SUBSCRIBER(pool, tx_message),\n      INITIALIZE_SUBSCRIBER(pool, verack),\n      INITIALIZE_SUBSCRIBER(pool, version)\n{\n}\n\nvoid message_subscriber::broadcast(const code &ec)\n{\n    RELAY_CODE(ec, address);\n    RELAY_CODE(ec, block_msg);\n    RELAY_CODE(ec, block_txs);\n    RELAY_CODE(ec, compact_block);\n    RELAY_CODE(ec, fee_filter);\n    RELAY_CODE(ec, filter_add);\n    RELAY_CODE(ec, filter_clear);\n    RELAY_CODE(ec, filter_load);\n    RELAY_CODE(ec, get_address);\n    RELAY_CODE(ec, get_blocks);\n    RELAY_CODE(ec, get_block_txs);\n    RELAY_CODE(ec, get_data);\n    RELAY_CODE(ec, get_headers);\n    RELAY_CODE(ec, headers);\n    RELAY_CODE(ec, inventory);\n    RELAY_CODE(ec, memory_pool);\n    RELAY_CODE(ec, merkle_block);\n    RELAY_CODE(ec, not_found);\n    RELAY_CODE(ec, ping);\n    RELAY_CODE(ec, pong);\n    RELAY_CODE(ec, reject);\n    RELAY_CODE(ec, send_headers);\n    RELAY_CODE(ec, send_compact_blocks);\n    RELAY_CODE(ec, tx_message);\n    RELAY_CODE(ec, verack);\n    RELAY_CODE(ec, version);\n}\n\ncode message_subscriber::load(message_type type, uint32_t version,\n                              std::istream &stream) const\n{\n    switch (type)\n    {\n        CASE_RELAY_MESSAGE(stream, version, address);\n        CASE_HANDLE_MESSAGE(stream, version, block_msg);\n        CASE_RELAY_MESSAGE(stream, version, block_txs);\n        CASE_RELAY_MESSAGE(stream, version, compact_block);\n        CASE_RELAY_MESSAGE(stream, version, fee_filter);\n        CASE_RELAY_MESSAGE(stream, version, filter_add);\n        CASE_RELAY_MESSAGE(stream, version, filter_clear);\n        CASE_RELAY_MESSAGE(stream, version, filter_load);\n        CASE_RELAY_MESSAGE(stream, version, get_address);\n        CASE_RELAY_MESSAGE(stream, version, get_blocks);\n        CASE_RELAY_MESSAGE(stream, version, get_block_txs);\n        CASE_RELAY_MESSAGE(stream, version, get_data);\n        CASE_RELAY_MESSAGE(stream, version, get_headers);\n        CASE_RELAY_MESSAGE(stream, version, headers);\n        CASE_RELAY_MESSAGE(stream, version, inventory);\n        CASE_RELAY_MESSAGE(stream, version, memory_pool);\n        CASE_RELAY_MESSAGE(stream, version, merkle_block);\n        CASE_RELAY_MESSAGE(stream, version, not_found);\n        CASE_RELAY_MESSAGE(stream, version, ping);\n        CASE_RELAY_MESSAGE(stream, version, pong);\n        CASE_RELAY_MESSAGE(stream, version, reject);\n        CASE_RELAY_MESSAGE(stream, version, send_headers);\n        CASE_RELAY_MESSAGE(stream, version, send_compact_blocks);\n        CASE_RELAY_MESSAGE(stream, version, tx_message);\n        CASE_RELAY_MESSAGE(stream, version, verack);\n        CASE_HANDLE_MESSAGE(stream, version, version);\n    case message_type::unknown:\n    default:\n        return error::not_found;\n    }\n}\n\nvoid message_subscriber::start()\n{\n    START_SUBSCRIBER(address);\n    START_SUBSCRIBER(block_msg);\n    START_SUBSCRIBER(block_txs);\n    START_SUBSCRIBER(compact_block);\n    START_SUBSCRIBER(fee_filter);\n    START_SUBSCRIBER(filter_add);\n    START_SUBSCRIBER(filter_clear);\n    START_SUBSCRIBER(filter_load);\n    START_SUBSCRIBER(get_address);\n    START_SUBSCRIBER(get_blocks);\n    START_SUBSCRIBER(get_block_txs);\n    START_SUBSCRIBER(get_data);\n    START_SUBSCRIBER(get_headers);\n    START_SUBSCRIBER(headers);\n    START_SUBSCRIBER(inventory);\n    START_SUBSCRIBER(memory_pool);\n    START_SUBSCRIBER(merkle_block);\n    START_SUBSCRIBER(not_found);\n    START_SUBSCRIBER(ping);\n    START_SUBSCRIBER(pong);\n    START_SUBSCRIBER(reject);\n    START_SUBSCRIBER(send_headers);\n    START_SUBSCRIBER(send_compact_blocks);\n    START_SUBSCRIBER(tx_message);\n    START_SUBSCRIBER(verack);\n    START_SUBSCRIBER(version);\n}\n\nvoid message_subscriber::stop()\n{\n    STOP_SUBSCRIBER(address);\n    STOP_SUBSCRIBER(block_msg);\n    STOP_SUBSCRIBER(block_txs);\n    STOP_SUBSCRIBER(compact_block);\n    STOP_SUBSCRIBER(fee_filter);\n    STOP_SUBSCRIBER(filter_add);\n    STOP_SUBSCRIBER(filter_clear);\n    STOP_SUBSCRIBER(filter_load);\n    STOP_SUBSCRIBER(get_address);\n    STOP_SUBSCRIBER(get_blocks);\n    STOP_SUBSCRIBER(get_block_txs);\n    STOP_SUBSCRIBER(get_data);\n    STOP_SUBSCRIBER(get_headers);\n    STOP_SUBSCRIBER(headers);\n    STOP_SUBSCRIBER(inventory);\n    STOP_SUBSCRIBER(memory_pool);\n    STOP_SUBSCRIBER(merkle_block);\n    STOP_SUBSCRIBER(not_found);\n    STOP_SUBSCRIBER(ping);\n    STOP_SUBSCRIBER(pong);\n    STOP_SUBSCRIBER(reject);\n    STOP_SUBSCRIBER(send_headers);\n    STOP_SUBSCRIBER(send_compact_blocks);\n    STOP_SUBSCRIBER(tx_message);\n    STOP_SUBSCRIBER(verack);\n    STOP_SUBSCRIBER(version);\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/p2p.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/p2p.hpp>\n\n#include <cstddef>\n#include <cstdint>\n#include <functional>\n#include <memory>\n#include <string>\n#include <vector>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/connections.hpp>\n#include <UChain/network/define.hpp>\n#include <UChain/network/hosts.hpp>\n#include <UChain/network/protocols/protocol_address.hpp>\n#include <UChain/network/protocols/protocol_ping.hpp>\n#include <UChain/network/protocols/protocol_seed.hpp>\n#include <UChain/network/protocols/protocol_version.hpp>\n#include <UChain/network/sessions/session_inbound.hpp>\n#include <UChain/network/sessions/session_manual.hpp>\n#include <UChain/network/sessions/session_outbound.hpp>\n#include <UChain/network/sessions/session_seed.hpp>\n#include <UChain/network/settings.hpp>\n#ifdef USE_UPNP\n#include <miniupnpc/miniupnpc.h>\n#include <miniupnpc/miniwget.h>\n#include <miniupnpc/upnpcommands.h>\n#include <miniupnpc/upnperrors.h>\n#endif\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\n#define NAME \"p2p\"\n\nusing namespace std::placeholders;\n\n#ifdef USE_UPNP\nstatic std::atomic<size_t> out_address_use_count_ = {0};\nbc::atomic<config::authority::ptr> upnp_out;\n#endif\n\np2p::p2p(const settings &settings)\n    : settings_(settings),\n      stopped_(true),\n      height_(0),\n      hosts_(std::make_shared<hosts>(threadpool_, settings_)),\n      connections_(std::make_shared<connections>()),\n      stop_subscriber_(std::make_shared<stop_subscriber>(threadpool_, NAME \"_stop_sub\")),\n      channel_subscriber_(std::make_shared<channel_subscriber>(threadpool_, NAME \"_sub\")),\n      seed(nullptr)\n{\n}\n\n// This allows for shutdown based on destruct without need to call stop.\np2p::~p2p()\n{\n    p2p::close();\n}\n\n// Start sequence.\n// ----------------------------------------------------------------------------\n\nvoid p2p::start(result_handler handler)\n{\n    if (!stopped())\n    {\n        handler(error::operation_failed);\n        return;\n    }\n\n    threadpool_.join();\n    threadpool_.spawn(settings_.threads, thread_priority::low);\n\n    stopped_ = false;\n    stop_subscriber_->start();\n    channel_subscriber_->start();\n\n    // This instance is retained by stop handler and member references.\n    const auto manual = attach_manual_session();\n    manual_.store(manual);\n\n    // This is invoked on a new thread.\n    manual->start(\n        std::bind(&p2p::handle_manual_started,\n                  this, _1, handler));\n\n    //start upnp map port\n    map_port(settings_.upnp_map_port);\n}\n\nvoid p2p::handle_manual_started(const code &ec, result_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped);\n        return;\n    }\n\n    if (ec)\n    {\n        log::error(LOG_NETWORK)\n            << \"Error starting manual session: \" << ec.message();\n        handler(ec);\n        return;\n    }\n\n    handle_hosts_loaded(hosts_->start(), handler);\n}\n\nvoid p2p::handle_hosts_loaded(const code &ec, result_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped);\n        return;\n    }\n\n    if (ec)\n    {\n        log::error(LOG_NETWORK)\n            << \"Error loading host addresses: \" << ec.message();\n        handler(ec);\n        return;\n    }\n\n    // The instance is retained by the stop handler (until shutdown).\n    seed = attach_seed_session();\n\n    // This is invoked on a new thread.\n    seed->start(\n        std::bind(&p2p::handle_started,\n                  this, _1, handler));\n}\n\nvoid p2p::handle_started(const code &ec, result_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped);\n        return;\n    }\n\n    if (ec)\n    {\n        log::error(LOG_NETWORK)\n            << \"Error seeding host addresses: \" << ec.message();\n        handler(ec);\n        return;\n    }\n\n    // There is no way to guarantee subscription before handler execution.\n    // So currently subscription for seed node connections is not supported.\n    // Subscription after this return will capture connections established via\n    // subsequent \"run\" and \"connect\" calls, and will clear on close/destruct.\n\n    // This is the end of the start sequence.\n    handler(error::success);\n}\n\n// Run sequence.\n// ----------------------------------------------------------------------------\n\nvoid p2p::run(result_handler handler)\n{\n    // Start node.peer persistent connections.\n    for (const auto &peer : settings_.peers)\n        connect(peer);\n\n    // The instance is retained by the stop handler (until shutdown).\n    const auto inbound = attach_inbound_session();\n\n    // This is invoked on a new thread.\n    inbound->start(\n        std::bind(&p2p::handle_inbound_started,\n                  this, _1, handler));\n}\n\nvoid p2p::handle_inbound_started(const code &ec, result_handler handler)\n{\n    if (ec)\n    {\n        log::error(LOG_NETWORK)\n            << \"Error starting inbound session: \" << ec.message();\n        handler(ec);\n        return;\n    }\n\n    // The instance is retained by the stop handler (until shutdown).\n    const auto outbound = attach_outbound_session();\n\n    // This is invoked on a new thread.\n    outbound->start(\n        std::bind(&p2p::handle_running,\n                  this, _1, handler));\n}\n\nvoid p2p::handle_running(const code &ec, result_handler handler)\n{\n    if (ec)\n    {\n        log::error(LOG_NETWORK)\n            << \"Error starting outbound session: \" << ec.message();\n        handler(ec);\n        return;\n    }\n\n    // This is the end of the run sequence.\n    handler(error::success);\n}\n\n// Specializations.\n// ----------------------------------------------------------------------------\n// Create derived sessions and override these to inject from derived p2p class.\n\nsession_seed::ptr p2p::attach_seed_session()\n{\n    return attach<session_seed>();\n}\n\nsession_manual::ptr p2p::attach_manual_session()\n{\n    return attach<session_manual>();\n}\n\nsession_inbound::ptr p2p::attach_inbound_session()\n{\n    return attach<session_inbound>();\n}\n\nsession_outbound::ptr p2p::attach_outbound_session()\n{\n    return attach<session_outbound>();\n}\n\n// Shutdown.\n// ----------------------------------------------------------------------------\n// All shutdown actions must be queued by the end of the stop call.\n// IOW queued shutdown operations must not enqueue additional work.\n\n// This is not short-circuited by a stopped test because we need to ensure it\n// completes at least once before returning. This requires a unique lock be\n// taken around the entire section, which poses a deadlock risk. Instead this\n// is thread safe and idempotent, allowing it to be unguarded.\nbool p2p::stop()\n{\n    // This is the only stop operation that can fail.\n    const auto result = (hosts_->stop() == (code)error::success);\n\n    // Signal all current work to stop and free manual session.\n    stopped_ = true;\n    manual_.store(nullptr);\n\n    // Prevent subscription after stop.\n    stop_subscriber_->stop();\n    stop_subscriber_->invoke(error::service_stopped);\n\n    // Prevent subscription after stop.\n    channel_subscriber_->stop();\n    channel_subscriber_->invoke(error::service_stopped, nullptr);\n\n    // Stop accepting channels and stop those that exist (self-clearing).\n    connections_->stop(error::service_stopped);\n\n    //shutdown upnp\n    map_port(false);\n\n    // Signal threadpool to stop accepting work now that subscribers are clear.\n    threadpool_.shutdown();\n    return result;\n}\n\n// This must be called from the thread that constructed this class (see join).\nbool p2p::close()\n{\n    // Signal current work to stop and threadpool to stop accepting new work.\n    const auto result = p2p::stop();\n\n    // Block on join of all threads in the threadpool.\n    threadpool_.join();\n    return result;\n}\n\n// Properties.\n// ----------------------------------------------------------------------------\n\nconst settings &p2p::network_settings() const\n{\n    return settings_;\n}\n\n// The blockchain height is set in our version message for handshake.\nsize_t p2p::height() const\n{\n    return height_;\n}\n\n// The height is set externally and is safe as an atomic.\nvoid p2p::set_height(size_t value)\n{\n    height_ = value;\n}\n\nbool p2p::stopped() const\n{\n    return stopped_;\n}\n\nthreadpool &p2p::thread_pool()\n{\n    return threadpool_;\n}\n\n// Subscriptions.\n// ----------------------------------------------------------------------------\n\nvoid p2p::subscribe_connection(connect_handler handler)\n{\n    channel_subscriber_->subscribe(handler, error::service_stopped, nullptr);\n}\n\nvoid p2p::subscribe_stop(result_handler handler)\n{\n    stop_subscriber_->subscribe(handler, error::service_stopped);\n}\n\n// Manual connections.\n// ----------------------------------------------------------------------------\n\nvoid p2p::connect(const config::endpoint &peer)\n{\n    connect(peer.host(), peer.port());\n}\n\nvoid p2p::connect(const std::string &hostname, uint16_t port)\n{\n    if (stopped())\n        return;\n\n    auto manual = manual_.load();\n    if (manual)\n        manual->connect(hostname, port);\n}\n\nvoid p2p::connect(const std::string &hostname, uint16_t port,\n                  channel_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped, nullptr);\n        return;\n    }\n\n    auto manual = manual_.load();\n    if (manual)\n    {\n        // Connect is invoked on a new thread.\n        manual->connect(hostname, port, handler);\n    }\n}\n\n// Connections collection.\n// ----------------------------------------------------------------------------\n\nvoid p2p::connected(const address &address, truth_handler handler)\n{\n    connections_->exists(address, handler);\n}\n\nvoid p2p::store(channel::ptr channel, result_handler handler)\n{\n    const auto new_connection_handler =\n        std::bind(&p2p::handle_new_connection,\n                  this, _1, channel, handler);\n\n    connections_->store(channel, new_connection_handler);\n}\n\nvoid p2p::handle_new_connection(const code &ec, channel::ptr channel,\n                                result_handler handler)\n{\n    // Connection-in-use indicated here by error::address_in_use.\n    handler(ec);\n\n    if (!ec && channel->notify())\n        channel_subscriber_->relay(error::success, channel);\n}\n\nvoid p2p::remove(channel::ptr channel, result_handler handler)\n{\n    connections_->remove(channel, handler);\n}\n\nvoid p2p::connected_count(count_handler handler)\n{\n    connections_->count(handler);\n}\n\n// Hosts collection.\n// ----------------------------------------------------------------------------\n\nvoid p2p::fetch_address(const config::authority::list &excluded_list, address_handler handler)\n{\n    address out;\n    handler(hosts_->fetch(out, excluded_list), out);\n}\n\nconfig::authority::list p2p::authority_list()\n{\n    return connections_->authority_list();\n}\n\nvoid p2p::store(const address &address, result_handler handler)\n{\n    handler(hosts_->store(address));\n}\n\nvoid p2p::store(const address::list &addresses, result_handler handler)\n{\n    // Store is invoked on a new thread.\n    hosts_->store(addresses, handler);\n}\n\nvoid p2p::remove(const address &address, result_handler handler)\n{\n    handler(hosts_->remove(address));\n}\n\nvoid p2p::address_count(count_handler handler)\n{\n    handler(hosts_->count());\n}\n\np2p::address::list p2p::address_list()\n{\n    return hosts_->copy();\n}\n\nconnections::ptr p2p::connections_ptr()\n{\n    return connections_;\n}\n\n#ifdef USE_UPNP\n\nvoid p2p::thread_map_port(uint16_t map_port)\n{\n    std::string port = std::to_string(map_port);\n    const char *multicastif = nullptr;\n    const char *minissdpdpath = nullptr;\n    struct UPNPDev *devlist = nullptr;\n    char lanaddr[64];\n\n#ifndef UPNPDISCOVER_SUCCESS\n    /* miniupnpc 1.5 */\n    devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);\n#elif MINIUPNPC_API_VERSION < 14\n    /* miniupnpc 1.6 */\n    int error = 0;\n    devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);\n#else\n    /* miniupnpc 1.9.20150730 */\n    int error = 0;\n    devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error);\n\n#endif\n\n    struct UPNPUrls urls;\n    struct IGDdatas data;\n    int r;\n    try\n    {\n        r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));\n    }\n    catch (...)\n    {\n        r = 0;\n        log::info(\"upnp\") << \"Get UPnP IGDs exception\";\n    }\n    if (r == 1)\n    {\n        std::string strDesc = std::string(\"UCN v\") + UC_VERSION;\n\n        try\n        {\n            while (true)\n            {\n#ifndef UPNPDISCOVER_SUCCESS\n                /* miniupnpc 1.5 */\n                r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,\n                                        port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), \"TCP\", 0);\n#else\n                /* miniupnpc 1.6 */\n                r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,\n                                        port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), \"TCP\", 0, \"0\");\n#endif\n\n                if (r != UPNPCOMMAND_SUCCESS)\n                    log::info(\"upnp\") << \"AddPortMapping(\" << port << \", \" << port << \", \" << lanaddr << \") failed with code \" << r << \" (\" << strupnperror(r) << \")\";\n                else\n                    log::info(\"upnp\") << \"Port Mapping successful.\";\n\n                std::this_thread::sleep_for(asio::milliseconds(20 * 60 * 1000));\n            }\n        }\n        catch (const boost::thread_interrupted &)\n        {\n            r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), \"TCP\", 0);\n            log::info(\"upnp\") << \"UPNP_DeletePortMapping() returned: \" << r;\n            freeUPNPDevlist(devlist);\n            devlist = nullptr;\n            FreeUPNPUrls(&urls);\n            throw;\n        }\n    }\n    else\n    {\n        log::info(\"upnp\") << \"No valid UPnP IGDs found\";\n        freeUPNPDevlist(devlist);\n        devlist = nullptr;\n        if (r != 0)\n            FreeUPNPUrls(&urls);\n    }\n}\n\nconfig::authority::ptr p2p::get_out_address()\n{\n\n    //every 8 times,get a new one\n    if (out_address_use_count_ != 0 && out_address_use_count_ <= 8)\n    {\n        out_address_use_count_++;\n        return upnp_out.load();\n    }\n\n    const char *multicastif = nullptr;\n    const char *minissdpdpath = nullptr;\n    struct UPNPDev *devlist = nullptr;\n    char lanaddr[64];\n\n#ifndef UPNPDISCOVER_SUCCESS\n    /* miniupnpc 1.5 */\n    devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0);\n#elif MINIUPNPC_API_VERSION < 14\n    /* miniupnpc 1.6 */\n    int error = 0;\n    devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error);\n#else\n    /* miniupnpc 1.9.20150730 */\n    int error = 0;\n    devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error);\n\n#endif\n\n    struct UPNPUrls urls;\n    struct IGDdatas data;\n    int r;\n\n    try\n    {\n        r = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr));\n    }\n    catch (...)\n    {\n        r = 0;\n        log::info(\"upnp\") << \"Get UPnP IGDs exception\";\n    }\n    if (r == 1)\n    {\n        char externalIPAddress[40];\n        r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress);\n        if (r != UPNPCOMMAND_SUCCESS)\n            log::info(\"upnp\") << \"GetExternalIPAddress() returned \" << r;\n        else\n        {\n            std::string outaddressstr = std::string(externalIPAddress) + \":\" + std::to_string(settings_.inbound_port);\n            upnp_out.store(std::make_shared<config::authority>(outaddressstr));\n            out_address_use_count_ = 1;\n            freeUPNPDevlist(devlist);\n            devlist = nullptr;\n            if (r != 0)\n                FreeUPNPUrls(&urls);\n            return upnp_out.load();\n        }\n    }\n\n    //log::info(\"upnp\") << \"No valid UPnP IGDs found\";\n    freeUPNPDevlist(devlist);\n    devlist = nullptr;\n    if (r != 0)\n        FreeUPNPUrls(&urls);\n\n    return std::make_shared<config::authority>(settings_.self);\n}\n\nvoid p2p::map_port(bool use_upnp)\n{\n    static std::unique_ptr<boost::thread> upnp_thread;\n\n    if (use_upnp)\n    {\n        if (upnp_thread)\n        {\n            upnp_thread->interrupt();\n            upnp_thread->join();\n        }\n        upnp_thread.reset(new boost::thread(boost::bind(p2p::thread_map_port, settings_.inbound_port)));\n    }\n    else if (upnp_thread)\n    {\n        upnp_thread->interrupt();\n        upnp_thread->join();\n        upnp_thread.reset();\n    }\n}\n\n#else  // #ifdef USE_UPNP\nvoid p2p::map_port(bool)\n{\n    // Intentionally left blank.\n}\n#endif // #ifdef USE_UPNP\n\nvoid p2p::restart_seeding()\n{\n    //1. clear the host::buffer_ cache\n    const auto result = hosts_->clear();\n    log::debug(LOG_NETWORK) << \"restart_seeding clear hosts cache: \" << result.message();\n\n    //2. start the session_seed\n    result_handler handler = [this](const code &ec) {\n        log::debug(LOG_NETWORK) << \"restart_seeding result: \" << ec.message();\n        hosts_->after_reseeding();\n    };\n\n    seed->restart(handler);\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/pending_channels.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/pending_channels.hpp>\n\n#include <algorithm>\n#include <cstdint>\n#include <functional>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\npending_channels::pending_channels()\n{\n}\n\npending_channels::~pending_channels()\n{\n    BITCOIN_ASSERT_MSG(channels_.empty(), \"Pending channels not cleared.\");\n}\n\nbool pending_channels::safe_store(channel::ptr channel)\n{\n    const auto version_nonce = channel->nonce();\n    const auto match = [version_nonce](const channel::ptr &entry) {\n        return entry->nonce() == version_nonce;\n    };\n\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    mutex_.lock_upgrade();\n\n    const auto it = std::find_if(channels_.begin(), channels_.end(), match);\n    const auto found = it != channels_.end();\n\n    if (!found)\n    {\n        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n        mutex_.unlock_upgrade_and_lock();\n        channels_.push_back(channel);\n        mutex_.unlock();\n        //---------------------------------------------------------------------\n        return true;\n    }\n\n    mutex_.unlock_upgrade();\n    ///////////////////////////////////////////////////////////////////////////\n\n    return false;\n}\n\nvoid pending_channels::store(channel::ptr channel, result_handler handler)\n{\n    handler(safe_store(channel) ? error::success : error::address_in_use);\n}\n\nbool pending_channels::safe_remove(channel::ptr channel)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    mutex_.lock_upgrade();\n\n    const auto it = std::find(channels_.begin(), channels_.end(), channel);\n    const auto found = it != channels_.end();\n\n    if (found)\n    {\n        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n        mutex_.unlock_upgrade_and_lock();\n        channels_.erase(it);\n        mutex_.unlock();\n        //---------------------------------------------------------------------\n        return true;\n    }\n\n    mutex_.unlock_upgrade();\n    ///////////////////////////////////////////////////////////////////////////\n\n    return false;\n}\n\nvoid pending_channels::remove(channel::ptr channel, result_handler handler)\n{\n    handler(safe_remove(channel) ? error::success : error::not_found);\n}\n\nbool pending_channels::safe_exists(uint64_t version_nonce) const\n{\n    const auto match = [version_nonce](channel::ptr entry) {\n        return entry->nonce() == version_nonce;\n    };\n\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    shared_lock lock(mutex_);\n\n    const auto it = std::find_if(channels_.begin(), channels_.end(), match);\n    return it != channels_.end();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid pending_channels::exists(uint64_t version_nonce,\n                              truth_handler handler) const\n{\n    // This is an optimization that requires we always set a non-zero nonce.\n    handler(version_nonce == 0 ? false : safe_exists(version_nonce));\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/pending_sockets.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/pending_sockets.hpp>\n\n#include <algorithm>\n#include <UChain/coin.hpp>\n#include <UChain/network/proxy.hpp>\n#include <UChain/network/socket.hpp>\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\npending_sockets::pending_sockets()\n{\n}\n\npending_sockets::~pending_sockets()\n{\n    BITCOIN_ASSERT_MSG(sockets_.empty(), \"Pending sockets not cleared.\");\n}\n\nvoid pending_sockets::clear()\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    unique_lock lock(mutex_);\n\n    // This will asynchronously invoke the handler of each pending connect.\n    for (auto socket : sockets_)\n        socket->close();\n\n    sockets_.clear();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid pending_sockets::store(socket::ptr socket)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    unique_lock lock(mutex_);\n\n    // We could test the list for the socket, which should not exist.\n    sockets_.push_back(socket);\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid pending_sockets::remove(socket::ptr socket)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    mutex_.lock_upgrade();\n\n    auto it = std::find(sockets_.begin(), sockets_.end(), socket);\n    const auto found = it != sockets_.end();\n\n    // Clear can be called at any time, so the entry may not be found.\n    if (found)\n    {\n        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n        mutex_.unlock_upgrade_and_lock();\n        sockets_.erase(it);\n        mutex_.unlock();\n        //---------------------------------------------------------------------\n        return;\n    }\n\n    mutex_.unlock_upgrade();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/protocols/protocol.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/protocols/protocol.hpp>\n\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/p2p.hpp>\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\nprotocol::protocol(p2p &network, channel::ptr channel,\n                   const std::string &name)\n    : pool_(network.thread_pool()),\n      channel_(channel),\n      name_(name)\n{\n}\n\nconfig::authority protocol::authority() const\n{\n    return channel_->authority();\n}\n\nconst std::string &protocol::name() const\n{\n    return name_;\n}\n\nuint64_t protocol::nonce() const\n{\n    return channel_->nonce();\n}\n\nmessage::version protocol::peer_version() const\n{\n    return channel_->version();\n}\n\nvoid protocol::set_peer_version(message::version::ptr value)\n{\n    channel_->set_version(value);\n}\n\nuint32_t protocol::peer_start_height()\n{\n    return channel_->peer_start_height();\n}\n\nthreadpool &protocol::pool()\n{\n    return pool_;\n}\n\n// Stop the channel.\nvoid protocol::stop(const code &ec)\n{\n    channel_->stop(ec);\n}\n\nbool protocol::misbehaving(int32_t howmuch)\n{\n    return channel_->misbehaving(howmuch);\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/protocols/protocol_address.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/protocols/protocol_address.hpp>\n\n#include <functional>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/p2p.hpp>\n#include <UChain/network/protocols/protocol.hpp>\n#include <UChain/network/protocols/protocol_events.hpp>\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\n#define NAME \"address\"\n#define CLASS protocol_address\n\nusing namespace bc::message;\nusing namespace std::placeholders;\n\nprotocol_address::protocol_address(p2p &network, channel::ptr channel)\n    : protocol_events(network, channel, NAME),\n      network_(network),\n      CONSTRUCT_TRACK(protocol_address)\n{\n}\n\nprotocol_address::ptr protocol_address::do_subscribe()\n{\n    SUBSCRIBE2(address, handle_receive_address, _1, _2);\n    SUBSCRIBE2(get_address, handle_receive_get_address, _1, _2);\n    // Must have a handler to capture a shared self pointer in stop subscriber.\n    protocol_events::start(BIND1(handle_stop, _1));\n    return std::dynamic_pointer_cast<protocol_address>(protocol::shared_from_this());\n}\n\n// Start sequence.\n// ----------------------------------------------------------------------------\n\nvoid protocol_address::start()\n{\n    const auto &settings = network_.network_settings();\n\n    if (settings.self.port() != 0)\n    {\n        network_address nt_address = settings.self.to_network_address();\n\n        //for testnet don't filter local ip\n        if (settings.hosts_file == \"hosts-test.cache\")\n        {\n            self_ = address({{nt_address}});\n            SEND2(self_, handle_send, _1, self_.command);\n        }\n        //only outer address can be broadcast\n        else if (!nt_address.is_private_network())\n        {\n            self_ = address({{nt_address}});\n            SEND2(self_, handle_send, _1, self_.command);\n        }\n    }\n\n#ifdef USE_UPNP\n    if (settings.upnp_map_port && settings.be_found)\n    {\n        config::authority::ptr sp_out_address = network_.get_out_address();\n\n        if (sp_out_address && (settings.self != *sp_out_address))\n        {\n            const config::authority &out_address = *sp_out_address;\n            network_address nt_address = out_address.to_network_address();\n            if (settings.hosts_file == \"hosts-test.cache\")\n            {\n                address self = address({{nt_address}});\n                log::info(\"upnp\") << \"send addresss \" << out_address.to_string();\n                SEND2(self, handle_send, _1, self.command);\n            }\n            else if (!nt_address.is_private_network())\n            {\n                address self = address({{nt_address}});\n                log::info(\"upnp\") << \"send addresss \" << out_address.to_string();\n                SEND2(self, handle_send, _1, self.command);\n            }\n        }\n    }\n\n#endif\n\n    // If we can't store addresses we don't ask for or handle them.\n    if (settings.host_pool_capacity == 0)\n        return;\n\n    SEND2(get_address(), handle_send, _1, get_address::command);\n}\n\nvoid protocol_address::remove_useless_address(address::ptr &message)\n{\n    auto &addresses = message->addresses;\n    const auto &settings = network_.network_settings();\n    if (settings.self.port() != 0)\n    {\n        auto iter = std::find_if(addresses.begin(), addresses.end(), [&settings](const message::network_address &addr) {\n            if (config::authority{addr} == settings.self)\n            {\n                return true;\n            }\n            return false;\n        });\n\n        if (iter != addresses.end())\n        {\n            addresses.erase(iter);\n        }\n    }\n}\n\n// Protocol.\n// ----------------------------------------------------------------------------\n\nbool protocol_address::handle_receive_address(const code &ec,\n                                              address::ptr message)\n{\n    if (stopped())\n        return false;\n\n    if (ec)\n    {\n        log::trace(LOG_NETWORK)\n            << \"Failure receiving address message from [\"\n            << authority() << \"] \" << ec.message();\n        stop(ec);\n\n        return false;\n    }\n    remove_useless_address(message);\n    log::trace(LOG_NETWORK)\n        << \"Storing addresses from [\" << authority() << \"] (\"\n        << message->addresses.size() << \")\";\n\n    //    if (message->addresses.size() > 1000)\n    //    {\n    //        return ! misbehaving(20);\n    //    }\n    network_address::list addresses;\n    addresses.reserve(message->addresses.size());\n    for (auto &addr : message->addresses)\n    {\n        //if (!channel::blacklisted(addr)) {\n        if (!channel::manualbanned(addr))\n        {\n            addresses.push_back(addr);\n        }\n    }\n\n    // TODO: manage timestamps (active channels are connected < 3 hours ago).\n    network_.store(addresses, BIND2(handle_store_addresses, _1, message));\n\n    // RESUBSCRIBE\n    return true;\n}\n\nbool protocol_address::handle_receive_get_address(const code &ec,\n                                                  get_address::ptr message)\n{\n    if (stopped())\n        return false;\n\n    if (ec)\n    {\n        log::trace(LOG_NETWORK)\n            << \"Failure receiving get_address message from [\"\n            << authority() << \"] \" << ec.message();\n        stop(ec);\n        return false;\n    }\n\n    // TODO: allowing repeated queries can allow a channel to map our history.\n    // TODO: pull active hosts from host cache (currently just resending self).\n    // TODO: need to distort for privacy, don't send currently-connected peers.\n\n    auto &&address_list = network_.address_list();\n    auto channel_authorithy = authority();\n\n    auto iter = std::find_if(address_list.begin(), address_list.end(), [&channel_authorithy](const message::network_address &address) {\n        if (config::authority{address} == channel_authorithy)\n        {\n            return true;\n        }\n        return false;\n    });\n    if (iter != address_list.end())\n    {\n        address_list.erase(iter);\n    }\n\n    if (address_list.empty())\n    {\n        return true;\n    }\n    //    if (self_.addresses.empty())\n    //        return false;\n\n    log::trace(LOG_NETWORK)\n        << \"Sending addresses to [\" << authority() << \"] (\"\n        << address_list.size() << \")\";\n    message::address self_address = {address_list};\n    SEND2(self_address, handle_send, _1, self_address.command);\n\n    // RESUBSCRIBE\n    return true;\n}\n\nvoid protocol_address::handle_store_addresses(const code &ec, address::ptr message)\n{\n    if (stopped())\n        return;\n\n    if (ec)\n    {\n        log::error(LOG_NETWORK)\n            << \"Failure storing addresses from [\" << authority() << \"] \"\n            << ec.message();\n        stop(ec);\n    }\n}\n\nvoid protocol_address::handle_stop(const code &)\n{\n    log::trace(LOG_NETWORK)\n        << \"Stopped addresss protocol\";\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/protocols/protocol_events.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/protocols/protocol_events.hpp>\n\n#include <functional>\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/p2p.hpp>\n#include <UChain/network/protocols/protocol.hpp>\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\n#define CLASS protocol_events\n\nusing namespace std::placeholders;\n\nprotocol_events::protocol_events(p2p &network, channel::ptr channel,\n                                 const std::string &name)\n    : protocol(network, channel, name)\n{\n}\n\n// Properties.\n// ----------------------------------------------------------------------------\n\nbool protocol_events::stopped()\n{\n    return !handler_.load();\n}\n\n// Start.\n// ----------------------------------------------------------------------------\n\nvoid protocol_events::start(event_handler handler)\n{\n    handler_.store(handler);\n    SUBSCRIBE_STOP1(handle_stopped, _1);\n    if (channel_stopped())\n        set_event(error::channel_stopped);\n}\n\n// Stop.\n// ----------------------------------------------------------------------------\n\nvoid protocol_events::handle_stopped(const code &ec)\n{\n    log::trace(LOG_NETWORK)\n        << \"Stop protocol_\" << name() << \" on [\" << authority() << \"] \"\n        << ec.message();\n\n    // Event handlers can depend on this code for channel stop.\n    set_event(error::channel_stopped);\n}\n\n// Set Event.\n// ----------------------------------------------------------------------------\n\nvoid protocol_events::set_event(const code &ec)\n{\n    auto handler = handler_.load();\n    if (!handler)\n        return;\n\n    if (ec == (code)error::channel_stopped)\n        handler_.store(nullptr);\n\n    handler(ec);\n}\n\n// Send Handler.\n// ----------------------------------------------------------------------------\n\nvoid protocol_events::handle_send(const code &ec, const std::string &command)\n{\n    if (stopped())\n        return;\n\n    if (ec)\n    {\n        log::trace(LOG_NETWORK)\n            << \"Failure sending '\" << command << \"' to [\" << authority()\n            << \"] \" << ec.message();\n        stop(ec);\n        return;\n    }\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/protocols/protocol_ping.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of libbitcoin.\n *\n * libbitcoin is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/protocols/protocol_ping.hpp>\n\n#include <cstdint>\n#include <functional>\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/p2p.hpp>\n#include <UChain/network/protocols/protocol_timer.hpp>\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\n#define NAME \"ping\"\n#define CLASS protocol_ping\n\nusing namespace bc::message;\nusing namespace std::placeholders;\n\nprotocol_ping::protocol_ping(p2p &network, channel::ptr channel)\n    : protocol_timer(network, channel, true, NAME),\n      settings_(network.network_settings()),\n      CONSTRUCT_TRACK(protocol_ping)\n{\n}\n\nprotocol_ping::ptr protocol_ping::do_subscribe()\n{\n    SUBSCRIBE2(ping, handle_receive_ping, _1, _2);\n    protocol_timer::start(settings_.channel_heartbeat(), BIND1(send_ping, _1));\n    return std::dynamic_pointer_cast<protocol_ping>(protocol::shared_from_this());\n}\n\nvoid protocol_ping::start()\n{\n\n    //    SUBSCRIBE2(ping, handle_receive_ping, _1, _2);\n\n    // Send initial ping message by simulating first heartbeat.\n    set_event(error::success);\n}\n\n// This is fired by the callback (i.e. base timer and stop handler).\nvoid protocol_ping::send_ping(const code &ec)\n{\n    if (stopped())\n        return;\n\n    if (ec && ec != error::channel_timeout)\n    {\n        log::trace(LOG_NETWORK)\n            << \"Failure in ping timer for [\" << authority() << \"] \"\n            << ec.message();\n        stop(ec);\n        return;\n    }\n\n    const auto nonce = pseudo_random();\n\n    SUBSCRIBE3(pong, handle_receive_pong, _1, _2, nonce);\n    SEND2(ping{nonce}, handle_send, _1, pong::command);\n}\n\nbool protocol_ping::handle_receive_ping(const code &ec,\n                                        message::ping::ptr message)\n{\n    if (stopped())\n        return false;\n\n    if (ec)\n    {\n        log::trace(LOG_NETWORK)\n            << \"Failure getting ping from [\" << authority() << \"] \"\n            << ec.message();\n        stop(ec);\n        return false;\n    }\n\n    SEND2(pong{message->nonce}, handle_send, _1, pong::command);\n\n    // RESUBSCRIBE\n    return true;\n}\n\nbool protocol_ping::handle_receive_pong(const code &ec,\n                                        message::pong::ptr message, uint64_t nonce)\n{\n    if (stopped())\n        return false;\n\n    if (ec)\n    {\n        log::trace(LOG_NETWORK)\n            << \"Failure getting pong from [\" << authority() << \"] \"\n            << ec.message();\n        stop(ec);\n        return false;\n    }\n\n    if (message->nonce != nonce)\n    {\n        log::warning(LOG_NETWORK)\n            << \"Invalid pong nonce from [\" << authority() << \"]\";\n\n        // This could result from message overlap due to a short period,\n        // but we assume the response is not as expected and terminate.\n        stop(error::bad_stream);\n    }\n\n    return false;\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/protocols/protocol_seed.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/protocols/protocol_seed.hpp>\n\n#include <functional>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/p2p.hpp>\n#include <UChain/network/protocols/protocol_timer.hpp>\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\n#define NAME \"seed\"\n#define CLASS protocol_seed\n\nusing namespace bc::message;\nusing namespace std::placeholders;\n\n// Require three callbacks (or any error) before calling complete.\nprotocol_seed::protocol_seed(p2p &network, channel::ptr channel)\n    : protocol_timer(network, channel, false, NAME),\n      network_(network),\n      CONSTRUCT_TRACK(protocol_seed)\n{\n}\n\n// Start sequence.\n// ----------------------------------------------------------------------------\n\nvoid protocol_seed::start(event_handler handler)\n{\n    const auto &settings = network_.network_settings();\n\n    auto complete = BIND2(handle_seeding_complete, _1, handler);\n\n    if (settings.host_pool_capacity == 0)\n    {\n        complete(error::not_found);\n        return;\n    }\n\n    protocol_timer::start(settings.channel_germination(),\n                          synchronize(complete, 3, NAME, false));\n\n    SUBSCRIBE2(address, handle_receive_address, _1, _2);\n    send_own_address(settings);\n    SEND1(get_address(), handle_send_get_address, _1);\n}\n\n// Protocol.\n// ----------------------------------------------------------------------------\n\nvoid protocol_seed::send_own_address(const settings &settings)\n{\n    if (settings.self.port() == 0)\n    {\n        set_event(error::success);\n        return;\n    }\n\n    const address self({{settings.self.to_network_address()}});\n    SEND1(self, handle_send_address, _1);\n}\n\nvoid protocol_seed::handle_seeding_complete(const code &ec,\n                                            event_handler handler)\n{\n    handler(ec);\n    stop(ec);\n}\n\nbool protocol_seed::handle_receive_address(const code &ec,\n                                           address::ptr message)\n{\n    if (stopped())\n        return false;\n\n    if (ec)\n    {\n        log::trace(LOG_NETWORK)\n            << \"Failure receiving addresses from seed [\" << authority() << \"] \"\n            << ec.message();\n        set_event(ec);\n        return false;\n    }\n\n    log::trace(LOG_NETWORK)\n        << \"Storing addresses from seed [\" << authority() << \"] (\"\n        << message->addresses.size() << \")\";\n\n    // TODO: manage timestamps (active channels are connected < 3 hours ago).\n    network_.store(message->addresses, BIND1(handle_store_addresses, _1));\n\n    return false;\n}\n\nvoid protocol_seed::handle_send_address(const code &ec)\n{\n    if (stopped())\n        return;\n\n    if (ec)\n    {\n        log::trace(LOG_NETWORK)\n            << \"Failure sending address to seed [\" << authority() << \"] \"\n            << ec.message();\n        set_event(ec);\n        return;\n    }\n\n    // 1 of 3\n    set_event(error::success);\n}\n\nvoid protocol_seed::handle_send_get_address(const code &ec)\n{\n    if (stopped())\n        return;\n\n    if (ec)\n    {\n        log::trace(LOG_NETWORK)\n            << \"Failure sending get_address to seed [\" << authority() << \"] \"\n            << ec.message();\n        set_event(ec);\n        return;\n    }\n\n    // 2 of 3\n    set_event(error::success);\n}\n\nvoid protocol_seed::handle_store_addresses(const code &ec)\n{\n    if (stopped())\n        return;\n\n    if (ec)\n    {\n        log::error(LOG_NETWORK)\n            << \"Failure storing addresses from seed [\" << authority() << \"] \"\n            << ec.message();\n        set_event(ec);\n        return;\n    }\n\n    log::trace(LOG_NETWORK)\n        << \"Stopping completed seed [\" << authority() << \"] \";\n\n    // 3 of 3\n    set_event(error::channel_stopped);\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/protocols/protocol_timer.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/protocols/protocol_timer.hpp>\n\n#include <functional>\n#include <memory>\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/p2p.hpp>\n#include <UChain/network/protocols/protocol_events.hpp>\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\n#define CLASS protocol_timer\nusing namespace std::placeholders;\n\nprotocol_timer::protocol_timer(p2p &network, channel::ptr channel,\n                               bool perpetual, const std::string &name)\n    : protocol_events(network, channel, name),\n      perpetual_(perpetual)\n{\n}\n\n// Start sequence.\n// ----------------------------------------------------------------------------\n\n// protected:\nvoid protocol_timer::start(const asio::duration &timeout,\n                           event_handler handle_event)\n{\n    // The deadline timer is thread safe.\n    timer_ = std::make_shared<deadline>(pool(), timeout);\n    protocol_events::start(BIND2(handle_notify, _1, handle_event));\n    reset_timer();\n}\n\nvoid protocol_timer::handle_notify(const code &ec, event_handler handler)\n{\n    if (ec == (code)error::channel_stopped)\n        timer_->stop();\n\n    handler(ec);\n}\n\n// Timer.\n// ----------------------------------------------------------------------------\n\n// protected:\nvoid protocol_timer::reset_timer()\n{\n    if (stopped())\n        return;\n\n    timer_->start(BIND1(handle_timer, _1));\n    if (stopped())\n    {\n        timer_->stop();\n        return;\n    }\n}\n\nvoid protocol_timer::handle_timer(const code &ec)\n{\n    if (stopped())\n    {\n        return;\n    }\n\n    // The handler completes before the timer is reset.\n    set_event(error::channel_timeout);\n\n    // A perpetual timer resets itself until the channel is stopped.\n    if (perpetual_)\n        reset_timer();\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/protocols/protocol_version.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/protocols/protocol_version.hpp>\n\n#include <chrono>\n#include <cstdint>\n#include <cstdlib>\n#include <functional>\n#include <UChain/coin.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/p2p.hpp>\n#include <UChain/network/protocols/protocol_timer.hpp>\n#include <UChain/network/settings.hpp>\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\n#define NAME \"version\"\n#define CLASS protocol_version\n\nusing namespace bc::message;\nusing namespace std::placeholders;\n\n// TODO: move to libbitcoin utility with similar blockchain function.\nstatic uint64_t time_stamp()\n{\n    // Use system clock because we require accurate time of day.\n    typedef std::chrono::system_clock wall_clock;\n    const auto now = wall_clock::now();\n    return wall_clock::to_time_t(now);\n}\n\nmessage::version protocol_version::version_factory(\n    const config::authority &authority, const settings &settings,\n    uint64_t nonce, size_t height)\n{\n    BITCOIN_ASSERT_MSG(height < max_uint32, \"Time to upgrade the protocol.\");\n    const auto height32 = static_cast<uint32_t>(height);\n\n    // TODO: move services to authority member in base protocol (passed in).\n    auto self = authority.to_network_address();\n    self.services = services::node_network;\n\n    return {\n        settings.protocol,\n        self.services,\n        time_stamp(),\n        self,\n        settings.self.to_network_address(),\n        nonce,\n        BC_USER_AGENT,\n        height32,\n        settings.relay_transactions};\n}\n\nprotocol_version::protocol_version(p2p &network, channel::ptr channel)\n    : protocol_timer(network, channel, false, NAME),\n      network_(network),\n      CONSTRUCT_TRACK(protocol_version)\n{\n}\n\n// Start sequence.\n// ----------------------------------------------------------------------------\n\nvoid protocol_version::start(event_handler handler)\n{\n    const auto height = network_.height();\n    const auto &settings = network_.network_settings();\n    complete_handler_ = handler;\n\n    // The handler is invoked in the context of the last message receipt.\n    protocol_timer::start(settings.channel_handshake(),\n                          synchronize(BIND1(handle_complete, _1), 2, NAME, false));\n\n    SUBSCRIBE2(version, handle_receive_version, _1, _2);\n    SUBSCRIBE2(verack, handle_receive_verack, _1, _2);\n    send_version(version_factory(authority(), settings, nonce(), height));\n}\n\nvoid protocol_version::handle_complete(const code &ec)\n{\n    if (!complete_handler_)\n        return;\n    complete_handler_(ec);\n    complete_handler_ = nullptr;\n}\n\nvoid protocol_version::send_version(const message::version &self)\n{\n    SEND1(self, handle_version_sent, _1);\n}\n\n// Protocol.\n// ----------------------------------------------------------------------------\n\nbool protocol_version::handle_receive_version(const code &ec,\n                                              version::ptr message)\n{\n    if (stopped())\n        return false;\n\n    if (ec)\n    {\n        log::trace(LOG_NETWORK)\n            << \"Failure receiving version from [\" << authority() << \"] \"\n            << ec.message();\n        set_event(ec);\n        return false;\n    }\n\n    log::trace(LOG_NETWORK)\n        << \"Peer [\" << authority() << \"] version (\" << message->value\n        << \") services (\" << message->services << \") time (\"\n        << message->timestamp << \") \" << message->user_agent;\n\n    set_peer_version(message);\n    SEND1(verack(), handle_verack_sent, _1);\n\n    // 1 of 2\n    set_event(error::success);\n    return false;\n}\n\nbool protocol_version::handle_receive_verack(const code &ec, verack::ptr)\n{\n    if (stopped())\n        return false;\n\n    if (ec)\n    {\n        log::trace(LOG_NETWORK)\n            << \"Failure receiving verack from [\" << authority() << \"] \"\n            << ec.message();\n        set_event(ec);\n        return false;\n    }\n\n    // 2 of 2\n    set_event(error::success);\n    return false;\n}\n\nvoid protocol_version::handle_version_sent(const code &ec)\n{\n    if (stopped())\n        return;\n\n    if (ec)\n    {\n        log::trace(LOG_NETWORK)\n            << \"Failure sending version to [\" << authority() << \"] \"\n            << ec.message();\n        set_event(ec);\n        return;\n    }\n}\n\nvoid protocol_version::handle_verack_sent(const code &ec)\n{\n    if (stopped())\n        return;\n\n    if (ec)\n    {\n        log::trace(LOG_NETWORK)\n            << \"Failure sending verack to [\" << authority() << \"] \"\n            << ec.message();\n        set_event(ec);\n        return;\n    }\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/proxy.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/proxy.hpp>\n\n#define BOOST_BIND_NO_PLACEHOLDERS\n\n#include <cstddef>\n#include <cstdint>\n#include <cstdlib>\n#include <functional>\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/network/const_buffer.hpp>\n#include <UChain/network/define.hpp>\n#include <UChain/network/socket.hpp>\n#include <UChain/coin/utility/time.hpp>\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\n#ifndef NDEBUG\nclass traffic\n{\n  public:\n    static traffic &instance();\n\n    void rx(uint64_t bytes)\n    {\n        rx_.fetch_add(bytes);\n    }\n\n    void tx(uint64_t bytes)\n    {\n        tx_.fetch_add(bytes);\n    }\n\n    ~traffic()\n    {\n        auto now = std::chrono::system_clock::now();\n        std::cout << \"it costs \" << std::chrono::duration_cast<std::chrono::seconds>(now - start_time_).count() << \" seconds, rx,\" << rx_.load() << \", tx,\" << tx_.load() << std::endl;\n    }\n\n  private:\n    static boost::detail::spinlock spinlock_;\n    static std::shared_ptr<traffic> instance_;\n    traffic() : rx_{0}, tx_{0}, start_time_{std::chrono::system_clock::now()}\n    {\n    }\n\n  private:\n    std::atomic<uint64_t> rx_;\n    std::atomic<uint64_t> tx_;\n    std::chrono::system_clock::time_point start_time_;\n};\ntraffic &traffic::instance()\n{\n    if (instance_ == nullptr)\n    {\n        boost::detail::spinlock::scoped_lock guard{spinlock_};\n        if (instance_ == nullptr)\n        {\n            instance_.reset(new traffic{});\n        }\n    }\n    return *instance_;\n}\nboost::detail::spinlock traffic::spinlock_;\nstd::shared_ptr<traffic> traffic::instance_ = nullptr;\n#endif\n\n#define NAME \"proxy\"\n\nusing namespace message;\nusing namespace std::placeholders;\n\nproxy::proxy(threadpool &pool, socket::ptr socket, uint32_t protocol_magic,\n             uint32_t protocol_version)\n    : protocol_magic_(protocol_magic),\n      protocol_version_(protocol_version),\n      authority_(socket->get_authority()),\n      heading_buffer_(heading::maximum_size()),\n      payload_buffer_(heading::maximum_payload_size(protocol_version_)),\n      dispatch_{pool, \"proxy\"},\n      socket_(socket),\n      stopped_(true),\n      peer_protocol_version_(message::version::level::maximum),\n      message_subscriber_(pool),\n      stop_subscriber_(std::make_shared<stop_subscriber>(pool, NAME)),\n      has_sent_{true},\n      misbehaving_{0}\n{\n}\n\nproxy::~proxy()\n{\n    BITCOIN_ASSERT_MSG(stopped(), \"The channel was not stopped.\");\n}\n\n// Properties.\n// ----------------------------------------------------------------------------\n\nconst config::authority &proxy::authority() const\n{\n    return authority_;\n}\n\nmessage::version proxy::version() const\n{\n    const auto version = peer_version_message_.load();\n    BITCOIN_ASSERT_MSG(version, \"Peer version read before set.\");\n    return *version;\n}\n\nvoid proxy::set_version(message::version::ptr value)\n{\n    peer_version_message_.store(value);\n    peer_protocol_version_.store(value->value);\n}\n\n// Start sequence.\n// ----------------------------------------------------------------------------\n\nvoid proxy::start(result_handler handler)\n{\n    if (!stopped())\n    {\n        handler(error::operation_failed);\n        return;\n    }\n\n    stopped_ = false;\n    stop_subscriber_->start();\n    message_subscriber_.start();\n\n    // Allow for subscription before first read, so no messages are missed.\n    handler(error::success);\n\n    // Start the read cycle.\n    read_heading();\n}\n\n// Stop subscription.\n// ----------------------------------------------------------------------------\n\nvoid proxy::subscribe_stop(result_handler handler)\n{\n    stop_subscriber_->subscribe(handler, error::channel_stopped);\n}\n\n// Read cycle (read continues until stop).\n// ----------------------------------------------------------------------------\n\nvoid proxy::read_heading()\n{\n    if (stopped())\n        return;\n\n    // The heading buffer is protected by ordering, not the critial section.\n\n    // Critical Section (external)\n    ///////////////////////////////////////////////////////////////////////////\n    const auto socket = socket_->get_socket();\n    using namespace boost::asio;\n    async_read(socket->get(), buffer(heading_buffer_, heading_buffer_.size()),\n               std::bind(&proxy::handle_read_heading,\n                         shared_from_this(), _1, _2));\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid proxy::handle_read_heading(const boost_code &ec, size_t)\n{\n    if (stopped())\n        return;\n\n    // TODO: verify client quick disconnect.\n    if (ec)\n    {\n        log::trace(LOG_NETWORK)\n            << \"Heading read failure [\" << authority() << \"] \"\n            << code(error::boost_to_error_code(ec)).message();\n        stop(ec);\n        return;\n    }\n#ifndef NDEBUG\n    traffic::instance().rx(heading_buffer_.size());\n#endif\n    const auto head = heading::factory_from_data(heading_buffer_);\n\n    if (!head.is_valid())\n    {\n        log::warning(LOG_NETWORK)\n            << \"Invalid heading from [\" << authority() << \"]\";\n        stop(error::bad_stream);\n        return;\n    }\n\n    if (head.magic != protocol_magic_)\n    {\n        log::trace(LOG_NETWORK)\n            << \"Invalid heading magic (\" << head.magic << \") from [\"\n            << authority() << \"]\";\n        stop(error::bad_magic);\n        return;\n    }\n\n    if (head.payload_size > payload_buffer_.capacity())\n    {\n        log::warning(LOG_NETWORK)\n            << \"Oversized payload indicated by \" << head.command\n            << \" heading from [\" << authority() << \"] (\"\n            << head.payload_size << \" bytes)\";\n        stop(error::bad_stream);\n        return;\n    }\n\n    handle_activity();\n    read_payload(head);\n}\n\nvoid proxy::read_payload(const heading &head)\n{\n    if (stopped())\n        return;\n\n    // This does not cause a reallocation.\n    payload_buffer_.resize(head.payload_size);\n\n    // The payload buffer is protected by ordering, not the critial section.\n\n    // Critical Section (external)\n    ///////////////////////////////////////////////////////////////////////////\n    const auto socket = socket_->get_socket();\n    using namespace boost::asio;\n    async_read(socket->get(), buffer(payload_buffer_, head.payload_size),\n               std::bind(&proxy::handle_read_payload,\n                         shared_from_this(), _1, _2, head));\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid proxy::handle_read_payload(const boost_code &ec, size_t payload_size,\n                                const heading &head)\n{\n    if (stopped())\n        return;\n\n    // TODO: verify client quick disconnect.\n    if (ec)\n    {\n        log::trace(LOG_NETWORK)\n            << \"Payload read failure [\" << authority() << \"] \"\n            << code(error::boost_to_error_code(ec)).message();\n        stop(ec);\n        return;\n    }\n\n#ifndef NDEBUG\n    traffic::instance().rx(payload_buffer_.size());\n#endif\n\n    auto checksum = bitcoin_checksum(payload_buffer_);\n    if (head.checksum != checksum)\n    {\n        log::trace(LOG_NETWORK)\n            << \"Invalid \" << head.command << \" payload from [\" << authority()\n            << \"] bad checksum. size is \" << payload_size;\n        stop(error::bad_stream);\n        return;\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n    // TODO: we aren't getting a stream benefit if we read the full payload\n    // before parsing the message. Should just make this a message parse.\n    ///////////////////////////////////////////////////////////////////////////\n\n    handle_request(payload_buffer_, peer_protocol_version_.load(), head, payload_size);\n\n    handle_activity();\n    read_heading();\n}\n\nvoid proxy::handle_request(data_chunk payload_buffer, uint32_t peer_protocol_version, heading head, size_t payload_size)\n{\n    bool succeed = false;\n\n    // Notify subscribers of the new message.\n    payload_source source(payload_buffer);\n    payload_stream istream(source);\n    const auto version = peer_protocol_version;\n\n    const auto code = message_subscriber_.load(head.type(), version, istream);\n\n    const auto consumed = istream.peek() == std::istream::traits_type::eof();\n\n    if (code)\n    {\n        log::warning(LOG_NETWORK)\n            << \"Invalid \" << head.command << \" payload from [\" << authority()\n            << \"] \" << code.message();\n        stop(code);\n        return;\n    }\n\n    if (!consumed)\n    {\n        log::warning(LOG_NETWORK)\n            << \"Invalid \" << head.command << \" payload from [\" << authority()\n            << \"] trailing bytes.\";\n        stop(error::bad_stream);\n        return;\n    }\n\n    log::trace(LOG_NETWORK)\n        << \"Valid \" << head.command << \" payload from [\" << authority()\n        << \"] (\" << payload_size << \" bytes)\";\n    succeed = true;\n}\n\n// Message send sequence.\n// ----------------------------------------------------------------------------\n\nvoid proxy::do_send(const std::string &command, const_buffer buffer,\n                    result_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::channel_stopped);\n        return;\n    }\n\n    if (command == \"headers\")\n    {\n        log::trace(LOG_NETWORK) << \"\";\n    }\n\n    //thin log network\n    log::trace(LOG_NETWORK)\n        << \"Sending \" << command << \" to [\" << authority() << \"] (\"\n        << buffer.size() << \" bytes)\";\n\n    // Critical Section (protect socket)\n    ///////////////////////////////////////////////////////////////////////////\n    // The socket is locked until async_write returns.\n#define QUEUE_REQUEST\n#ifdef QUEUE_REQUEST\n    bool is_ok_to_send{false};\n    uint32_t outbound_size{0};\n    request_callback h{nullptr};\n    {\n        auto pThis = shared_from_this();\n        auto f = [this, pThis, buffer, handler]() {\n            if (stopped())\n            {\n                handler(error::channel_stopped);\n                return;\n            }\n            const auto socket = socket_->get_socket();\n            auto &native_socket = socket->get();\n            async_write(native_socket, buffer,\n                        std::bind(&proxy::handle_send,\n                                  shared_from_this(), _1, buffer, handler));\n        };\n        const auto socket = socket_->get_socket();\n        outbound_size = outbound_queue_.size();\n        bool is_empty{outbound_queue_.empty()};\n        bool in_sending{!has_sent_.load()};\n        is_ok_to_send = (is_empty && !in_sending);\n        if (is_ok_to_send)\n        {\n            h = std::move(f);\n            has_sent_.store(false);\n        }\n        else\n        {\n            outbound_queue_.push(std::move(f));\n        }\n    }\n\n    if (outbound_size > 500)\n    {\n        stop(error::size_limits);\n        return;\n    }\n\n    if (is_ok_to_send)\n    {\n        h();\n    }\n#else\n    const auto socket = socket_->get_socket();\n\n    // The shared buffer is kept in scope until the handler is invoked.\n    using namespace boost::asio;\n    async_write(socket->get(), buffer,\n                std::bind(&proxy::handle_send,\n                          shared_from_this(), _1, buffer, handler));\n#endif\n    // The shared buffer is kept in scope until the handler is invoked.\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid proxy::handle_send(const boost_code &ec, const_buffer buffer,\n                        result_handler handler)\n{\n    const auto error = code(error::boost_to_error_code(ec));\n\n    if (error)\n        log::trace(LOG_NETWORK)\n            << \"Failure sending \" << buffer.size() << \" byte message to [\"\n            << authority() << \"] \" << error.message();\n    else\n    {\n#ifndef NDEBUG\n        traffic::instance().tx(buffer.size());\n#endif\n    }\n\n    handler(error);\n#ifdef QUEUE_REQUEST\n    if (error)\n    {\n        const auto socket = socket_->get_socket();\n        std::queue<request_callback>{}.swap(outbound_queue_);\n        return;\n    }\n\n    has_sent_.store(true);\n\n    request_callback h{nullptr};\n    {\n        const auto socket = socket_->get_socket();\n        if (outbound_queue_.empty())\n            return;\n        log::trace(LOG_NETWORK) << \"channel:\" << reinterpret_cast<int64_t>(this) << \" outbound size,\" << outbound_queue_.size();\n        h = std::move(outbound_queue_.front());\n        outbound_queue_.pop();\n        has_sent_.store(false);\n    }\n    h();\n#endif\n}\n\n// Stop sequence.\n// ----------------------------------------------------------------------------\n\n// This is not short-circuited by a stop test because we need to ensure it\n// completes at least once before invoking the handler. That would require a\n// lock be taken around the entire section, which poses a deadlock risk.\n// Instead this is thread safe and idempotent, allowing it to be unguarded.\nvoid proxy::stop(const code &ec)\n{\n    BITCOIN_ASSERT_MSG(ec, \"The stop code must be an error code.\");\n\n    stopped_ = true;\n\n    // Prevent subscription after stop.\n    message_subscriber_.stop();\n    message_subscriber_.broadcast(error::channel_stopped);\n\n    // Prevent subscription after stop.\n    stop_subscriber_->stop();\n    stop_subscriber_->relay(ec);\n\n    // Give channel opportunity to terminate timers.\n    handle_stopping();\n    {\n        const auto socket = socket_->get_socket();\n        std::queue<request_callback>{}.swap(outbound_queue_);\n    }\n\n    // The socket_ is internally guarded against concurrent use.\n    socket_->close();\n    {\n        if (error::bad_magic != ec.value())\n            return;\n        boost::detail::spinlock::scoped_lock guard{proxy::spinlock_};\n        auto millissecond = unix_millisecond();\n        banned_.insert({authority(), millissecond + 24 * 3600 * 1000});\n    }\n}\n\nvoid proxy::stop(const boost_code &ec)\n{\n    stop(error::boost_to_error_code(ec));\n}\n\nbool proxy::stopped() const\n{\n    return stopped_;\n}\n\nstd::map<config::authority, int64_t> proxy::banned_;\nstd::list<config::authority> proxy::manual_banned_;\nboost::detail::spinlock proxy::spinlock_;\nboost::detail::spinlock proxy::manual_banned_spinlock_;\n\nbool proxy::blacklisted(const config::authority &authority)\n{\n    int64_t ms{0};\n    {\n        boost::detail::spinlock::scoped_lock guard{proxy::spinlock_};\n        auto it = banned_.find(authority);\n        if (it == banned_.end())\n            return false;\n        ms = it->second;\n    }\n\n    auto millissecond = unix_millisecond();\n    if (ms >= millissecond)\n    {\n        return true;\n    }\n    return false;\n}\n\nbool proxy::manualbanned(const config::authority &authority)\n{\n    boost::detail::spinlock::scoped_lock guard{proxy::manual_banned_spinlock_};\n    auto it = find(manual_banned_.begin(), manual_banned_.end(), config::authority(authority.ip(), 0));\n    return (it != manual_banned_.end());\n}\n\nvoid proxy::manual_ban(const config::authority &authority)\n{\n    const config::authority local_authority{authority.ip(), 0};\n    boost::detail::spinlock::scoped_lock guard{proxy::manual_banned_spinlock_};\n    auto it = find(manual_banned_.begin(), manual_banned_.end(), local_authority);\n    if (it == manual_banned_.end())\n    {\n        manual_banned_.push_back(local_authority);\n        log::info(LOG_NETWORK) << \"add to manual_ban_list: \" << local_authority.to_string();\n    }\n}\n\nvoid proxy::manual_unban(const config::authority &authority)\n{\n    const config::authority local_authority{authority.ip(), 0};\n    boost::detail::spinlock::scoped_lock guard{proxy::manual_banned_spinlock_};\n    auto it = find(manual_banned_.begin(), manual_banned_.end(), local_authority);\n    if (it != manual_banned_.end())\n    {\n        manual_banned_.erase(it);\n        log::info(LOG_NETWORK) << \"remove from manual_ban_list: \" << local_authority.to_string();\n    }\n}\n\nbool proxy::misbehaving(int32_t howmuch)\n{\n    misbehaving_ += howmuch;\n    if (misbehaving_.load() >= 100)\n    {\n        {\n            boost::detail::spinlock::scoped_lock guard{proxy::spinlock_};\n            auto millissecond = unix_millisecond();\n            banned_.insert({authority(), millissecond + 24 * 3600 * 1000});\n        }\n        log::debug(LOG_NETWORK) << \"channel misbehave trigger,\" << authority();\n        stop(error::bad_stream);\n        return true;\n    }\n    return false;\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/sessions/session.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/sessions/session.hpp>\n\n#include <algorithm>\n#include <cstddef>\n#include <cstdint>\n#include <functional>\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/network/acceptor.hpp>\n#include <UChain/network/channel.hpp>\n#include <UChain/network/connector.hpp>\n#include <UChain/network/p2p.hpp>\n#include <UChain/network/proxy.hpp>\n#include <UChain/network/protocols/protocol_address.hpp>\n#include <UChain/network/protocols/protocol_ping.hpp>\n#include <UChain/network/protocols/protocol_version.hpp>\n#include <UChain/network/settings.hpp>\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\n#define NAME \"session\"\n\n// Base class binders.\n#define BIND_0(method) \\\n    base_bind(&session::method)\n#define BIND_1(method, p1) \\\n    base_bind(&session::method, p1)\n#define BIND_2(method, p1, p2) \\\n    base_bind(&session::method, p1, p2)\n#define BIND_3(method, p1, p2, p3) \\\n    base_bind(&session::method, p1, p2, p3)\n#define BIND_4(method, p1, p2, p3, p4) \\\n    base_bind(&session::method, p1, p2, p3, p4)\n\nusing namespace std::placeholders;\n\nsession::session(p2p &network, bool outgoing, bool persistent)\n    : stopped_(true),\n      incoming_(!outgoing),\n      notify_(persistent),\n      network_(network),\n      settings_(network.network_settings()),\n      pool_(network.thread_pool()),\n      dispatch_(pool_, NAME)\n{\n}\n\nsession::~session()\n{\n    BITCOIN_ASSERT_MSG(stopped(), \"The session was not stopped.\");\n}\n\n// Properties.\n// ----------------------------------------------------------------------------\n\n// protected:\nvoid session::address_count(count_handler handler)\n{\n    network_.address_count(handler);\n}\n\n// protected:\nvoid session::fetch_address(host_handler handler)\n{\n    network_.fetch_address(network_.authority_list(), handler);\n}\n\n// protected:\nvoid session::connection_count(count_handler handler)\n{\n    network_.connected_count(handler);\n}\n\n// protected:\nbool session::blacklisted(const authority &authority) const\n{\n    const auto &blocked = settings_.blacklists;\n    // black through IP, does not care port.\n    const auto it = std::find_if(blocked.begin(), blocked.end(),\n                                 [&authority](const config::authority &elem) {\n                                     return (authority.ip() == elem.ip());\n                                 });\n    auto result = it != blocked.end();\n    return result || channel::blacklisted(authority) || channel::manualbanned(authority);\n}\n\nvoid session::remove(const message::network_address &address, result_handler handler)\n{\n    network_.remove(address, handler);\n}\n\nvoid session::store(const message::network_address &address)\n{\n    network_.store(address, [](const code &) {});\n}\n\n// Socket creators.\n// ----------------------------------------------------------------------------\n// Must not change context in the stop handlers (must use bind).\n\n// protected:\nacceptor::ptr session::create_acceptor()\n{\n    const auto accept = std::make_shared<acceptor>(pool_, settings_);\n    subscribe_stop(BIND_2(do_stop_acceptor, _1, accept));\n    return accept;\n}\n\nvoid session::do_stop_acceptor(const code &, acceptor::ptr accept)\n{\n    accept->stop();\n}\n\n// protected:\nconnector::ptr session::create_connector()\n{\n    const auto connect = std::make_shared<connector>(pool_, settings_);\n    subscribe_stop(BIND_2(do_stop_connector, _1, connect));\n    return connect;\n}\n\nvoid session::do_stop_connector(const code &, connector::ptr connect)\n{\n    connect->stop();\n}\n\n// Start sequence.\n// ----------------------------------------------------------------------------\n// Must not change context before subscribing.\n\nvoid session::start(result_handler handler)\n{\n    if (!stopped())\n    {\n        handler(error::operation_failed);\n        return;\n    }\n\n    stopped_ = false;\n    subscribe_stop(BIND_1(do_stop_session, _1));\n\n    // This is the end of the start sequence.\n    handler(error::success);\n}\n\nvoid session::do_stop_session(const code &)\n{\n    // This signals the session to stop creating connections, but does not\n    // close the session. Channels are stopped resulting in session lost scope.\n    stopped_ = true;\n}\n\nbool session::stopped() const\n{\n    return stopped_;\n}\n\n// Subscribe Stop sequence.\n// ----------------------------------------------------------------------------\n\nvoid session::subscribe_stop(result_handler handler)\n{\n    network_.subscribe_stop(handler);\n}\n\n// Registration sequence.\n// ----------------------------------------------------------------------------\n// Must not change context in start or stop sequences (use bind).\n\n// protected:\nvoid session::register_channel(channel::ptr channel,\n                               result_handler handle_started, result_handler handle_stopped)\n{\n    result_handler stop_handler =\n        BIND_3(do_remove, _1, channel, handle_stopped);\n\n    result_handler start_handler =\n        BIND_4(handle_start, _1, channel, handle_started, stop_handler);\n\n    if (stopped())\n    {\n        start_handler(error::service_stopped);\n        return;\n    }\n\n    if (incoming_)\n    {\n        handle_pend(error::success, channel, start_handler);\n        return;\n    }\n\n    channel->set_notify(notify_);\n    channel->set_nonce(nonzero_pseudo_random());\n\n    result_handler unpend_handler =\n        BIND_3(do_unpend, _1, channel, start_handler);\n\n    pending_.store(channel,\n                   BIND_3(handle_pend, _1, channel, unpend_handler));\n}\n\nvoid session::handle_pend(const code &ec, channel::ptr channel,\n                          result_handler handle_started)\n{\n    if (ec)\n    {\n        handle_started(ec);\n        return;\n    }\n\n    // The channel starts, invokes the handler, then starts the read cycle.\n    channel->start(\n        BIND_3(handle_channel_start, _1, channel, handle_started));\n}\n\nvoid session::handle_channel_start(const code &ec, channel::ptr channel,\n                                   result_handler handle_started)\n{\n    if (ec)\n    {\n        log::info(LOG_NETWORK)\n            << \"Channel failed to start [\" << channel->authority() << \"] \"\n            << ec.message();\n        handle_started(ec);\n        return;\n    }\n\n    result_handler handshake_handler =\n        BIND_3(handle_handshake, _1, channel, handle_started);\n\n    attach_handshake_protocols(channel, handshake_handler);\n}\n\n// Sessions that desire to customize the version message must override this.\nvoid session::attach_handshake_protocols(channel::ptr channel,\n                                         result_handler handle_started)\n{\n    attach<protocol_version>(channel)->start(handle_started);\n}\n\nvoid session::handle_handshake(const code &ec, channel::ptr channel,\n                               result_handler handle_started)\n{\n    if (ec)\n    {\n        log::trace(LOG_NETWORK)\n            << \"Failure in handshake with [\" << channel->authority()\n            << \"] \" << ec.message();\n        handle_started(ec);\n        return;\n    }\n\n    truth_handler handler =\n        BIND_3(handle_is_pending, _1, channel, handle_started);\n\n    // The loopback test is for incoming channels only.\n    if (incoming_)\n        pending_.exists(channel->version().nonce, handler);\n    else\n        handler(false);\n}\n\nvoid session::handle_is_pending(bool pending, channel::ptr channel,\n                                result_handler handle_started)\n{\n    if (pending)\n    {\n        log::debug(LOG_NETWORK)\n            << \"Rejected connection from [\" << channel->authority()\n            << \"] as loopback.\";\n        handle_started(error::accept_failed);\n        return;\n    }\n\n    const auto &version = channel->version();\n\n    if (version.value < version.minimum)\n    {\n        log::debug(LOG_NETWORK)\n            << \"Peer version (\" << version.value << \") below minimum (\"\n            << version.minimum << \") [\" << channel->authority() << \"]\";\n        handle_started(error::accept_failed);\n        return;\n    }\n\n    // This will fail if the IP address or nonce is already connected.\n    network_.store(channel, handle_started);\n}\n\nvoid session::handle_start(const code &ec, channel::ptr channel,\n                           result_handler handle_started, result_handler handle_stopped)\n{\n    if (ec)\n    {\n        channel->stop(ec);\n        handle_stopped(ec);\n    }\n    else\n    {\n        channel->subscribe_stop(handle_stopped);\n    }\n\n    // This is the end of the registration sequence.\n    handle_started(ec);\n}\n\nvoid session::do_unpend(const code &ec, channel::ptr channel,\n                        result_handler handle_started)\n{\n    pending_.remove(channel, BIND_1(handle_unpend, _1));\n    handle_started(ec);\n}\n\nvoid session::do_remove(const code &ec, channel::ptr channel,\n                        result_handler handle_stopped)\n{\n    network_.remove(channel, BIND_1(handle_remove, _1));\n    handle_stopped(ec);\n}\n\nvoid session::handle_unpend(const code &ec)\n{\n    if (ec)\n        log::trace(LOG_NETWORK)\n            << \"Failed to unpend a channel: \" << ec.message();\n}\n\nvoid session::handle_remove(const code &ec)\n{\n    if (ec)\n        log::trace(LOG_NETWORK)\n            << \"Failed to remove a channel: \" << ec.message();\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/sessions/session_batch.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/sessions/session_batch.hpp>\n\n#include <atomic>\n#include <cstdint>\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/network/connector.hpp>\n#include <UChain/network/p2p.hpp>\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\n#define CLASS session_batch\n#define NAME \"session_batch\"\n\nusing namespace bc::config;\nusing namespace std::placeholders;\n\nsession_batch::session_batch(p2p &network, bool persistent)\n    : session(network, true, persistent),\n      batch_size_(std::max(settings_.connect_batch_size, 1u))\n{\n}\n\nvoid session_batch::converge(const code &ec, channel::ptr channel,\n                             atomic_counter_ptr counter, upgrade_mutex_ptr mutex,\n                             channel_handler handler)\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    mutex->lock_upgrade();\n\n    const auto initial_count = counter->load();\n    BITCOIN_ASSERT(initial_count <= batch_size_);\n\n    // Already completed, don't call handler.\n    if (initial_count == batch_size_)\n    {\n        mutex->unlock_upgrade();\n        //-----------------------------------------------------------------\n        if (!ec)\n            channel->stop(error::channel_stopped);\n\n        return;\n    }\n\n    const auto count = !ec ? batch_size_ : initial_count + 1;\n    const auto cleared = count == batch_size_;\n\n    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n    mutex->unlock_upgrade_and_lock();\n    counter->store(count);\n    mutex->unlock();\n    ///////////////////////////////////////////////////////////////////////\n\n    if (cleared)\n    {\n        // If the last connection attempt is an error, normalize the code.\n        auto result = ec ? error::operation_failed : error::success;\n        handler(result, channel);\n    }\n}\n\n// Connect sequence.\n// ----------------------------------------------------------------------------\n\n// protected:\nvoid session_batch::connect(connector::ptr connect, channel_handler handler)\n{\n    // synchronizer state.\n    const auto mutex = std::make_shared<upgrade_mutex>();\n    const auto counter = std::make_shared<atomic_counter>(0);\n    const auto singular = BIND5(converge, _1, _2, counter, mutex, handler);\n\n    for (uint32_t host = 0; host < batch_size_; ++host)\n        new_connect(connect, counter, singular);\n}\n\nvoid session_batch::new_connect(connector::ptr connect,\n                                atomic_counter_ptr counter, channel_handler handler)\n{\n    if (stopped())\n    {\n        log::debug(LOG_NETWORK)\n            << \"Suspended batch connection.\";\n        return;\n    }\n\n    if (counter->load() == batch_size_)\n        return;\n    fetch_address(BIND5(start_connect, _1, _2, connect, counter, handler));\n}\n\nvoid session_batch::start_connect(const code &ec, const authority &host,\n                                  connector::ptr connect, atomic_counter_ptr counter, channel_handler handler)\n{\n    if (counter->load() == batch_size_ || ec == (code)error::service_stopped)\n        return;\n\n    // This termination prevents a tight loop in the empty address pool case.\n    if (ec)\n    {\n        log::warning(LOG_NETWORK)\n            << \"Failure fetching new address: \" << ec.message();\n        handler(ec, nullptr);\n        return;\n    }\n\n    // This creates a tight loop in the case of a small address pool.\n    if (blacklisted(host))\n    {\n        handler(error::address_blocked, nullptr);\n        return;\n    }\n\n    log::trace(LOG_NETWORK)\n        << \"Connecting to [\" << host << \"]\";\n\n    // CONNECT\n    connect->connect(host, BIND7(handle_connect, _1, _2, host, connect,\n                                 counter, 3, handler));\n}\n\nvoid session_batch::handle_connect(const code &ec, channel::ptr channel,\n                                   const authority &host, connector::ptr connect, atomic_counter_ptr counter, std::size_t count,\n                                   channel_handler handler)\n{\n    if (counter->load() == batch_size_)\n        return;\n\n    if (ec)\n    {\n        log::trace(LOG_NETWORK)\n            << \"Failure connecting to [\" << host << \"] \" << count << \",\"\n            << ec.message();\n        remove(host.to_network_address(), [](const code &) {});\n        handler(ec, channel);\n        return;\n    }\n\n    store(host.to_network_address());\n\n    log::trace(LOG_NETWORK)\n        << \"Connected to [\" << channel->authority() << \"]\";\n\n    // This is the end of the connect sequence.\n    handler(error::success, channel);\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/sessions/session_inbound.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/sessions/session_inbound.hpp>\n\n#include <cstddef>\n#include <functional>\n#include <UChain/coin.hpp>\n#include <UChain/network/connector.hpp>\n#include <UChain/network/p2p.hpp>\n#include <UChain/network/protocols/protocol_address.hpp>\n#include <UChain/network/protocols/protocol_ping.hpp>\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\n#define CLASS session_inbound\n\nusing namespace std::placeholders;\n\nsession_inbound::session_inbound(p2p &network)\n    : session(network, true, true),\n      network_{network},\n      CONSTRUCT_TRACK(session_inbound)\n{\n}\n\n// Start sequence.\n// ----------------------------------------------------------------------------\n\nvoid session_inbound::start(result_handler handler)\n{\n    if (settings_.inbound_port == 0 || settings_.inbound_connections == 0)\n    {\n        log::info(LOG_NETWORK)\n            << \"Not configured for accepting incoming connections.\";\n        handler(error::success);\n        return;\n    }\n\n    session::start(CONCURRENT2(handle_started, _1, handler));\n}\n\nvoid session_inbound::handle_started(const code &ec, result_handler handler)\n{\n    if (ec)\n    {\n        handler(ec);\n        return;\n    }\n\n    const auto accept = create_acceptor();\n    const auto port = settings_.inbound_port;\n\n    // START LISTENING ON PORT\n    accept->listen(port, BIND2(start_accept, _1, accept));\n\n    // This is the end of the start sequence.\n    handler(error::success);\n}\n\n// Accept sequence.\n// ----------------------------------------------------------------------------\n\nvoid session_inbound::start_accept(const code &ec, acceptor::ptr accept)\n{\n    if (stopped())\n    {\n        log::trace(LOG_NETWORK)\n            << \"Suspended inbound connection.\";\n        return;\n    }\n\n    if (ec)\n    {\n        log::error(LOG_NETWORK)\n            << \"Error starting listener: \" << ec.message();\n        network_.stop();\n        return;\n    }\n\n    // ACCEPT THE NEXT INCOMING CONNECTION\n    accept->accept(BIND3(handle_accept, _1, _2, accept));\n}\n\nvoid session_inbound::handle_accept(const code &ec, channel::ptr channel,\n                                    acceptor::ptr accept)\n{\n    if (stopped())\n    {\n        log::trace(LOG_NETWORK)\n            << \"Suspended inbound connection.\";\n        return;\n    }\n\n    start_accept(error::success, accept);\n\n    if (ec)\n    {\n        log::trace(LOG_NETWORK)\n            << \"Failure accepting connection: \" << ec.message();\n        return;\n    }\n\n    if (blacklisted(channel->authority()))\n    {\n        log::trace(LOG_NETWORK)\n            << \"Rejected inbound connection from [\"\n            << channel->authority() << \"] due to blacklisted address.\";\n        channel->stop(error::accept_failed);\n        return;\n    }\n\n    connection_count(BIND2(handle_connection_count, _1, channel));\n}\n\nvoid session_inbound::handle_connection_count(size_t connections,\n                                              channel::ptr channel)\n{\n    const auto connection_limit = settings_.inbound_connections +\n                                  settings_.outbound_connections;\n\n    if (connections >= connection_limit)\n    {\n        log::trace(LOG_NETWORK)\n            << \"Rejected inbound connection from [\"\n            << channel->authority() << \"] due to connection limit.\";\n        return;\n    }\n\n    log::trace(LOG_NETWORK)\n        << \"Connected inbound channel [\" << channel->authority() << \"]\";\n\n    register_channel(channel,\n                     BIND2(handle_channel_start, _1, channel),\n                     BIND1(handle_channel_stop, _1));\n}\n\nvoid session_inbound::handle_channel_start(const code &ec,\n                                           channel::ptr channel)\n{\n    if (ec)\n    {\n        log::trace(LOG_NETWORK)\n            << \"Inbound channel failed to start [\" << channel->authority()\n            << \"] \" << ec.message();\n        channel->stop(ec);\n        return;\n    }\n\n    attach_protocols(channel);\n};\n\nvoid session_inbound::attach_protocols(channel::ptr channel)\n{\n    attach<protocol_ping>(channel)->do_subscribe()->start();\n    attach<protocol_address>(channel)->do_subscribe()->start();\n}\n\nvoid session_inbound::handle_channel_stop(const code &ec)\n{\n    log::trace(LOG_NETWORK)\n        << \"Inbound channel stopped: \" << ec.message();\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/sessions/session_manual.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/sessions/session_manual.hpp>\n\n#include <cstddef>\n#include <cstdint>\n#include <functional>\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/network/p2p.hpp>\n#include <UChain/network/protocols/protocol_address.hpp>\n#include <UChain/network/protocols/protocol_ping.hpp>\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\n#define CLASS session_manual\n\nusing namespace std::placeholders;\n\nsession_manual::session_manual(p2p &network)\n    : session_batch(network, true),\n      CONSTRUCT_TRACK(session_manual)\n{\n}\n\n// Start sequence.\n// ----------------------------------------------------------------------------\n// Manual connections are always enabled.\n\nvoid session_manual::start(result_handler handler)\n{\n    session::start(CONCURRENT2(handle_started, _1, handler));\n}\n\nvoid session_manual::handle_started(const code &ec, result_handler handler)\n{\n    if (ec)\n    {\n        handler(ec);\n        return;\n    }\n\n    connector_.store(create_connector());\n\n    // This is the end of the start sequence.\n    handler(error::success);\n}\n\n// Connect sequence/cycle.\n// ----------------------------------------------------------------------------\n\nvoid session_manual::connect(const std::string &hostname, uint16_t port)\n{\n    const auto unhandled = [](code, channel::ptr) {};\n    connect(hostname, port, unhandled);\n}\n\nvoid session_manual::connect(const std::string &hostname, uint16_t port,\n                             channel_handler handler)\n{\n    start_connect(hostname, port, handler, settings_.manual_attempt_limit);\n}\n\n// The first connect is a sequence, which then spawns a cycle.\nvoid session_manual::start_connect(const std::string &hostname, uint16_t port,\n                                   channel_handler handler, uint32_t retries)\n{\n    if (stopped())\n    {\n        log::debug(LOG_NETWORK)\n            << \"Suspended manual connection.\";\n\n        connector_.store(nullptr);\n        handler(error::service_stopped, nullptr);\n        return;\n    }\n\n    auto connector = connector_.load();\n    BITCOIN_ASSERT_MSG(connector, \"The manual session was not started.\");\n\n    // MANUAL CONNECT OUTBOUND\n    connector->connect(hostname, port,\n                       BIND6(handle_connect, _1, _2, hostname, port, handler, retries - 1));\n}\n\nvoid session_manual::handle_connect(const code &ec, channel::ptr channel,\n                                    const std::string &hostname, uint16_t port, channel_handler handler,\n                                    uint32_t retries)\n{\n    if (ec)\n    {\n        log::debug(LOG_NETWORK)\n            << \"Failure connecting [\" << config::endpoint(hostname, port)\n            << \"] manually: \" << ec.message();\n\n        auto shared_this = shared_from_base<session_manual>();\n        const auto timer = std::make_shared<deadline>(pool_, asio::seconds(3));\n\n        // Retry logic.\n        if (settings_.manual_attempt_limit == 0)\n            delay_new_connection(hostname, port, handler, 0);\n        else if (retries > 0)\n            delay_new_connection(hostname, port, handler, retries);\n        else\n            handler(ec, nullptr);\n\n        return;\n    }\n\n    log::debug(LOG_NETWORK)\n        << \"Connected manual channel [\" << config::endpoint(hostname, port)\n        << \"] as [\" << channel->authority() << \"]\";\n\n    register_channel(channel,\n                     BIND5(handle_channel_start, _1, hostname, port, channel, handler),\n                     BIND3(handle_channel_stop, _1, hostname, port));\n}\n\nvoid session_manual::handle_channel_start(const code &ec,\n                                          const std::string &hostname, uint16_t port, channel::ptr channel,\n                                          channel_handler handler)\n{\n    // Treat a start failure just like a stop, but preserve the start handler.\n    if (ec)\n    {\n        log::trace(LOG_NETWORK)\n            << \"Manual channel failed to start [\" << channel->authority()\n            << \"] \" << ec.message();\n\n        // Special case for already connected, do not keep trying.\n        if (ec == (code)error::address_in_use)\n        {\n            handler(ec, channel);\n            return;\n        }\n\n        return;\n    }\n\n    // This is the end of the connect sequence (the handler goes out of scope).\n    handler(error::success, channel);\n\n    // This is the beginning of the connect sequence.\n    attach_protocols(channel);\n};\n\nvoid session_manual::attach_protocols(channel::ptr channel)\n{\n    attach<protocol_ping>(channel)->do_subscribe()->start();\n    attach<protocol_address>(channel)->do_subscribe()->start();\n}\n\nvoid session_manual::delay_new_connection(const std::string &hostname, uint16_t port, channel_handler handler, uint32_t retries)\n{\n    auto timer = std::make_shared<deadline>(pool_, asio::seconds(2));\n    auto self = shared_from_this();\n    timer->start([this, timer, self, hostname, port, handler, retries](const code &ec) {\n        if (stopped())\n        {\n            return;\n        }\n        auto pThis = shared_from_this();\n        auto action = [this, pThis, hostname, port, handler, retries]() {\n            start_connect(hostname, port, handler, retries);\n        };\n        pool_.service().post(action);\n    });\n}\n\n// After a stop we don't use the caller's start handler, but keep connecting.\nvoid session_manual::handle_channel_stop(const code &ec,\n                                         const std::string &hostname, uint16_t port)\n{\n    log::debug(LOG_NETWORK)\n        << \"Manual channel stopped: \" << ec.message();\n\n    if (stopped() || (ec.value() == error::service_stopped))\n        return;\n\n    delay_new_connection(hostname, port, [](code, channel::ptr) {}, settings_.manual_attempt_limit);\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/sessions/session_outbound.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/sessions/session_outbound.hpp>\n\n#include <cstddef>\n#include <functional>\n#include <UChain/coin.hpp>\n#include <UChain/network/p2p.hpp>\n#include <UChain/network/protocols/protocol_address.hpp>\n#include <UChain/network/protocols/protocol_ping.hpp>\n#include <UChain/coin/utility/deadline.hpp>\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\n#define CLASS session_outbound\n\nusing namespace std::placeholders;\n\nsession_outbound::session_outbound(p2p &network)\n    : session_batch(network, true),\n      network__(network),\n      CONSTRUCT_TRACK(session_outbound)\n{\n    outbound_counter = 0;\n    in_reseeding = false;\n}\n\n// Start sequence.\n// ----------------------------------------------------------------------------\n\nvoid session_outbound::start(result_handler handler)\n{\n    if (settings_.outbound_connections == 0)\n    {\n        log::info(LOG_NETWORK)\n            << \"Not configured for generating outbound connections.\";\n        handler(error::success);\n        return;\n    }\n\n    session::start(CONCURRENT2(handle_started, _1, handler));\n}\n\nvoid session_outbound::handle_started(const code &ec, result_handler handler)\n{\n    if (ec)\n    {\n        handler(ec);\n        return;\n    }\n\n    outbound_counter = 0;\n    in_reseeding = false;\n\n    const auto connect = create_connector();\n    for (size_t peer = 0; peer < settings_.outbound_connections; ++peer)\n    {\n        log::debug(LOG_NETWORK) << \"new connection\";\n        new_connection(connect);\n    }\n\n    // This is the end of the start sequence.\n    handler(error::success);\n}\n\n// Connnect cycle.\n// ----------------------------------------------------------------------------\n\nvoid session_outbound::new_connection(connector::ptr connect)\n{\n    if (stopped())\n    {\n        log::trace(LOG_NETWORK)\n            << \"Suspended outbound connection.\";\n        return;\n    }\n    static int i{0};\n    int b = i++;\n    this->connect(connect, BIND3(handle_connect, _1, _2, connect));\n}\n\nvoid session_outbound::delay_new_connect(connector::ptr connect)\n{\n    auto timer = std::make_shared<deadline>(pool_, asio::seconds(2));\n    auto self = shared_from_this();\n    timer->start([this, connect, timer, self](const code &ec) {\n        if (stopped())\n        {\n            return;\n        }\n        auto pThis = shared_from_this();\n        auto action = [this, pThis, connect]() {\n            new_connection(connect);\n        };\n        pool_.service().post(action);\n    });\n}\n\nvoid session_outbound::delay_reseeding()\n{\n    if (!network__.network_settings().enable_re_seeding)\n    {\n        return;\n    }\n\n    if (in_reseeding)\n    {\n        return;\n    }\n    in_reseeding = true;\n    log::debug(LOG_NETWORK) << \"outbound channel counter decreased, the re-seeding will be triggered 60s later!\";\n    auto timer = std::make_shared<deadline>(pool_, asio::seconds(60));\n    auto self = shared_from_this();\n    timer->start([this, timer, self](const code &ec) {\n        if (stopped())\n        {\n            return;\n        }\n        auto pThis = shared_from_this();\n        auto action = [this, pThis]() {\n            const int counter = outbound_counter;\n            if (counter > 1)\n            {\n                log::debug(LOG_NETWORK) << \"outbound channel counter recovered to [\" << counter << \"], re-seeding is canceled!\";\n                in_reseeding = false;\n                return;\n            }\n            log::debug(LOG_NETWORK) << \"start re-seeding!\";\n            network__.restart_seeding();\n            in_reseeding = false;\n        };\n        pool_.service().post(action);\n    });\n}\n\nvoid session_outbound::handle_connect(const code &ec, channel::ptr channel,\n                                      connector::ptr connect)\n{\n    if (ec)\n    {\n        log::trace(LOG_NETWORK)\n            << \"Failure connecting outbound: \" << ec.message();\n        delay_new_connect(connect);\n        return;\n    }\n\n    log::trace(LOG_NETWORK)\n        << \"Connected to outbound channel [\" << channel->authority() << \"]\";\n    ++outbound_counter;\n    register_channel(channel,\n                     BIND3(handle_channel_start, _1, connect, channel),\n                     BIND3(handle_channel_stop, _1, connect, channel));\n}\n\nvoid session_outbound::handle_channel_start(const code &ec,\n                                            connector::ptr connect, channel::ptr channel)\n{\n    // Treat a start failure just like a stop.\n    if (ec)\n    {\n        log::trace(LOG_NETWORK)\n            << \"Outbound channel failed to start [\"\n            << channel->authority() << \"] \" << ec.message();\n        channel->invoke_protocol_start_handler(error::channel_stopped);\n        channel->stop(ec);\n        return;\n    }\n\n    attach_protocols(channel);\n};\n\nvoid session_outbound::attach_protocols(channel::ptr channel)\n{\n    attach<protocol_ping>(channel)->do_subscribe()->start();\n    attach<protocol_address>(channel)->do_subscribe()->start();\n}\n\nvoid session_outbound::handle_channel_stop(const code &ec,\n                                           connector::ptr connect, channel::ptr channel)\n{\n    channel->invoke_protocol_start_handler(error::channel_stopped);\n    log::debug(LOG_NETWORK) << \"channel stopped,\" << ec.message();\n\n    const int counter = --outbound_counter;\n\n    if (!stopped() && ec.value() != error::service_stopped)\n    {\n        delay_new_connect(connect);\n        //restart the seeding procedure with in 1 minutes when outbound session count reduce to 1.\n        if (counter <= 1)\n        {\n            delay_reseeding();\n        }\n    }\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/sessions/session_seed.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/sessions/session_seed.hpp>\n\n#include <cstddef>\n#include <cstdint>\n#include <functional>\n#include <UChain/coin.hpp>\n#include <UChain/network/p2p.hpp>\n#include <UChain/network/protocols/protocol_ping.hpp>\n#include <UChain/network/protocols/protocol_seed.hpp>\n#include <UChain/network/proxy.hpp>\n#include <UChain/coin/config/authority.hpp>\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\n#define CLASS session_seed\n#define NAME \"session_seed\"\n\nusing namespace std::placeholders;\nsession_seed::session_seed(p2p &network)\n    : session(network, true, false),\n      CONSTRUCT_TRACK(session_seed),\n      network_{network}\n{\n}\n\n// Start sequence.\n// ----------------------------------------------------------------------------\n\nvoid session_seed::start(result_handler handler)\n{\n    if (settings_.host_pool_capacity == 0)\n    {\n        log::info(LOG_NETWORK)\n            << \"Not configured to populate an address pool.\";\n        handler(error::success);\n        return;\n    }\n\n    session::start(CONCURRENT2(handle_started, _1, handler));\n}\n\nvoid session_seed::restart(result_handler handler)\n{\n    handle_started(error::success, handler);\n}\n\nvoid session_seed::handle_started(const code &ec, result_handler handler)\n{\n    if (ec)\n    {\n        handler(ec);\n        return;\n    }\n\n    address_count(BIND2(handle_count, _1, handler));\n}\n\nvoid session_seed::handle_count(size_t start_size, result_handler handler)\n{\n    if (start_size != 0)\n    {\n        log::debug(LOG_NETWORK)\n            << \"Seeding is not required because there are \"\n            << start_size << \" cached addresses.\";\n        handler(error::success);\n        return;\n    }\n\n    if (settings_.seeds.empty())\n    {\n        log::error(LOG_NETWORK)\n            << \"Seeding is required but no seeds are configured.\";\n        handler(error::operation_failed);\n        return;\n    }\n\n    // This is NOT technically the end of the start sequence, since the handler\n    // is not invoked until seeding operations are complete.\n    start_seeding(start_size, create_connector(), handler);\n}\n\n// Seed sequence.\n// ----------------------------------------------------------------------------\n\nvoid session_seed::start_seeding(size_t start_size, connector::ptr connect,\n                                 result_handler handler)\n{\n    // When all seeds are synchronized call session_seed::handle_complete.\n    auto all = BIND2(handle_complete, start_size, handler);\n\n    // Synchronize each individual seed before calling handle_complete.\n    auto each = synchronize(all, settings_.seeds.size(), NAME, true);\n\n    // We don't use parallel here because connect is itself asynchronous.\n    for (const auto &seed : settings_.seeds)\n        start_seed(seed, connect, each);\n}\n\nvoid session_seed::start_seed(const config::endpoint &seed,\n                              connector::ptr connect, result_handler handler)\n{\n    if (stopped())\n    {\n        log::debug(LOG_NETWORK)\n            << \"Suspended seed connection\";\n        handler(error::channel_stopped);\n        return;\n    }\n\n    log::info(LOG_NETWORK)\n        << \"Contacting seed [\" << seed << \"]\";\n\n    // OUTBOUND CONNECT\n    connect->connect(seed, BIND4(handle_connect, _1, _2, seed, handler), [this](const asio::endpoint &endpoint) {\n        network_.store(config::authority{endpoint}.to_network_address(), [](const code &ec) {});\n        log::debug(LOG_NETWORK) << \"session seed store,\" << endpoint;\n    });\n}\n\nvoid session_seed::handle_connect(const code &ec, channel::ptr channel,\n                                  const config::endpoint &seed, result_handler handler)\n{\n    if (ec)\n    {\n        log::info(LOG_NETWORK)\n            << \"Failure contacting seed [\" << seed << \"] \" << ec.message();\n        handler(ec);\n        return;\n    }\n\n    if (blacklisted(channel->authority()))\n    {\n        log::debug(LOG_NETWORK)\n            << \"Seed [\" << seed << \"] on blacklisted address [\"\n            << channel->authority() << \"]\";\n        handler(error::address_blocked);\n        return;\n    }\n\n    log::info(LOG_NETWORK)\n        << \"Connected seed [\" << seed << \"] as \" << channel->authority();\n\n    register_channel(channel,\n                     BIND3(handle_channel_start, _1, channel, handler),\n                     BIND1(handle_channel_stop, _1));\n}\n\nvoid session_seed::handle_channel_start(const code &ec, channel::ptr channel,\n                                        result_handler handler)\n{\n    if (ec)\n    {\n        handler(ec);\n        return;\n    }\n\n    attach_protocols(channel, handler);\n};\n\nvoid session_seed::attach_protocols(channel::ptr channel,\n                                    result_handler handler)\n{\n    attach<protocol_ping>(channel)->start();\n    attach<protocol_seed>(channel)->start(handler);\n}\n\nvoid session_seed::handle_channel_stop(const code &ec)\n{\n    log::info(LOG_NETWORK)\n        << \"Seed channel stopped: \" << ec.message();\n}\n\n// This accepts no error code because individual seed errors are suppressed.\nvoid session_seed::handle_complete(size_t start_size, result_handler handler)\n{\n    address_count(BIND3(handle_final_count, _1, start_size, handler));\n\n    log::info(LOG_NETWORK)\n        << \"session_seed complete!\";\n}\n\n// We succeed only if there is a host count increase.\nvoid session_seed::handle_final_count(size_t current_size, size_t start_size,\n                                      result_handler handler)\n{\n    const auto result = current_size > start_size ? error::success : error::operation_failed;\n\n    // This is the end of the seed sequence.\n    handler(result);\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/settings.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/settings.hpp>\n\n#include <UChain/coin.hpp>\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\nusing namespace bc::asio;\nusing namespace bc::message;\n\n// Common default values (no settings context).\nsettings::settings()\n    : threads(16),\n      protocol(version::level::maximum),\n      inbound_connections(32),\n      outbound_connections(8),\n      manual_attempt_limit(0),\n      connect_batch_size(5),\n      connect_timeout_seconds(5),\n      channel_handshake_seconds(30),\n      channel_heartbeat_minutes(5),\n      channel_inactivity_minutes(10),\n      channel_expiration_minutes(1440),\n      channel_germination_seconds(30),\n      host_pool_capacity(1000),\n      relay_transactions(true),\n      enable_re_seeding(true),\n      upnp_map_port(true),\n      be_found(true),\n      hosts_file(\"hosts.cache\"),\n      debug_file(\"debug.log\"),\n      error_file(\"error.log\"),\n      self(unspecified_network_address)\n{\n}\n\n// Use push_back due to initializer_list bug:\n// stackoverflow.com/a/20168627/1172329\nsettings::settings(bc::settings context)\n    : settings()\n{\n    // Handle deviations from common defaults.\n    switch (context)\n    {\n    case bc::settings::mainnet:\n    {\n        //identifier = 0x4d53564d;\n        //identifier = 1234567891;//for UIP0.2\n        identifier = 1234567904; //for UIP0.5\n        inbound_port = 5682;\n\n        // Seeds based on uc.live/network/dns-servers\n        seeds.reserve(5);\n        //seeds.push_back({ \"main-uchain-a.live\", 5682 });\n        //seeds.push_back({ \"main-uchain-b.live\", 5682 });\n        //seeds.push_back({ \"main-uchain-c.live\", 5682 });\n        //seeds.push_back({ \"main-uchain-d.live\", 5682 });\n        //seeds.push_back({ \"main-uchain-e.live\", 5682 });\n        //seeds.push_back({ \"main-uchain-f.live\", 5682 });\n        seeds.push_back({\"35.182.225.90\", 5682});\n        seeds.push_back({\"13.124.250.27\", 5682});\n        seeds.push_back({\"112.74.181.29\", 5682});\n        seeds.push_back({\"120.78.209.248\", 5682});\n        seeds.push_back({\"116.62.238.230\" /*\"seed.getuc.org\"*/, 5682});\n        break;\n    }\n\n    case bc::settings::testnet:\n    {\n        identifier = 0x73766d74;\n        inbound_port = 15678;\n\n        seeds.reserve(6);\n        seeds.push_back({\"test-uchain-a.live\", 15678});\n        seeds.push_back({\"test-uchain-b.live\", 15678});\n        seeds.push_back({\"test-uchain-c.live\", 15678});\n        seeds.push_back({\"test-uchain-d.live\", 15678});\n        seeds.push_back({\"test-uchain-e.live\", 15678});\n        seeds.push_back({\"test-uchain-f.live\", 15678});\n        break;\n    }\n\n    default:\n    case bc::settings::none:\n    {\n    }\n    }\n}\n\nduration settings::connect_timeout() const\n{\n    return seconds(connect_timeout_seconds);\n}\n\nduration settings::channel_handshake() const\n{\n    return seconds(channel_handshake_seconds);\n}\n\nduration settings::channel_heartbeat() const\n{\n    return minutes(channel_heartbeat_minutes);\n}\n\nduration settings::channel_inactivity() const\n{\n    return minutes(channel_inactivity_minutes);\n}\n\nduration settings::channel_expiration() const\n{\n    return minutes(channel_expiration_minutes);\n}\n\nduration settings::channel_germination() const\n{\n    return seconds(channel_germination_seconds);\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/network/socket.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/network/socket.hpp>\n\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/network/define.hpp>\n#include <UChain/network/locked_socket.hpp>\n\nnamespace libbitcoin\n{\nnamespace network\n{\n\nsocket::socket(threadpool &pool)\n    : socket_(pool.service()),\n      CONSTRUCT_TRACK(socket)\n{\n}\n\nconfig::authority socket::get_authority() const\n{\n    boost_code ec;\n    const auto endpoint = socket_.remote_endpoint(ec);\n    return ec ? config::authority() : config::authority(endpoint);\n}\n\nlocked_socket::ptr socket::get_socket()\n{\n    return std::make_shared<locked_socket>(socket_, mutex_);\n}\n\n// BUGBUG: socket::cancel fails with error::operation_not_supported\n// on Windows XP and Windows Server 2003, but handler invocation is required.\n// We should enable BOOST_ASIO_ENABLE_CANCELIO and BOOST_ASIO_DISABLE_IOCP\n// on these platforms only. See: bit.ly/1YC0p9e\nvoid socket::close()\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    mutex_.lock_upgrade();\n\n    if (socket_.is_open())\n    {\n        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n        mutex_.unlock_upgrade_and_lock();\n\n        // Ignoring socket error codes creates exception safety.\n        boost_code ignore;\n        socket_.shutdown(asio::socket::shutdown_both, ignore);\n        socket_.cancel(ignore);\n\n        mutex_.unlock();\n        //---------------------------------------------------------------------\n        return;\n    }\n\n    mutex_.unlock_upgrade();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n} // namespace network\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/node/CMakeLists.txt",
    "content": "FILE(GLOB_RECURSE node_SOURCES \"*.cpp\")\n\nADD_DEFINITIONS(-DBCN_STATIC=1)\n\nADD_LIBRARY(node_static STATIC ${node_SOURCES})\nSET_TARGET_PROPERTIES(node_static PROPERTIES OUTPUT_NAME uc_node)\nTARGET_LINK_LIBRARIES(node_static ${Boost_LIBRARIES} ${txs_LIBRARY} ${bitcoin_LIBRARY}\n      ${blockchain_LIBRARY} ${data_LIBRARY} ${database_LIBRARY} ${network_LIBRARY})\nINSTALL(TARGETS node_static DESTINATION lib)\n\nIF(ENABLE_SHARED_LIBS)\n    ADD_DEFINITIONS(-DBCN_DLL=1)\n  ADD_LIBRARY(node_shared SHARED ${node_SOURCES})\n  SET_TARGET_PROPERTIES(node_shared PROPERTIES OUTPUT_NAME uc_node)\n  TARGET_LINK_LIBRARIES(node_shared ${Boost_LIBRARIES} ${txs_LIBRARY} ${bitcoin_LIBRARY}\n      ${blockchain_LIBRARY} ${data_LIBRARY} ${database_LIBRARY} ${network_LIBRARY})\n  INSTALL(TARGETS node_shared DESTINATION lib)\nENDIF()\n"
  },
  {
    "path": "src/UChain/node/configuration.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/node/configuration.hpp>\n\n#include <cstddef>\n#include <UChain/blockchain.hpp>\n#include <UChain/network.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\n// Construct with defaults derived from given context.\nconfiguration::configuration(bc::settings context)\n    : help(false),\n      initchain(false),\n      settings(false),\n      version(false),\n      daemon{false},\n      use_testnet_rules{false},\n      upnp_map_port{true},\n      node(context),\n      chain(context),\n      database(context),\n      network(context)\n{\n}\n\n// Copy constructor.\nconfiguration::configuration(const configuration &other)\n    : help(other.help),\n      initchain(other.initchain),\n      settings(other.settings),\n      version(other.version),\n      daemon{other.daemon},\n      use_testnet_rules{other.use_testnet_rules},\n      upnp_map_port{other.upnp_map_port},\n      file(other.file),\n      node(other.node),\n      chain(other.chain),\n      database(other.database),\n      network(other.network)\n{\n}\n\n} // namespace node\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/node/p2p_node.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-node.\n *\n * UChain-node is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/node/p2p_node.hpp>\n\n#include <cstddef>\n#include <cstdint>\n#include <functional>\n#include <UChain/blockchain.hpp>\n#include <UChain/node/configuration.hpp>\n#include <UChain/node/sessions/session_block_sync.hpp>\n#include <UChain/node/sessions/session_header_sync.hpp>\n#include <UChain/node/sessions/session_inbound.hpp>\n#include <UChain/node/sessions/session_manual.hpp>\n#include <UChain/node/sessions/session_outbound.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\nusing namespace bc::blockchain;\nusing namespace bc::chain;\nusing namespace bc::config;\nusing namespace bc::network;\nusing namespace std::placeholders;\n\np2p_node::p2p_node(const configuration &configuration)\n    : p2p(configuration.network),\n      hashes_(configuration.chain.checkpoints),\n      blockchain_(thread_pool(), configuration.chain, configuration.database),\n      settings_(configuration.node)\n{\n}\n\np2p_node::~p2p_node()\n{\n    p2p_node::close();\n}\n\n// Start.\n// ----------------------------------------------------------------------------\n\nvoid p2p_node::start(result_handler handler)\n{\n    if (!stopped())\n    {\n        handler(error::operation_failed);\n        return;\n    }\n\n    if (!blockchain_.start())\n    {\n        log::error(LOG_NODE)\n            << \"Blockchain failed to start.\";\n        handler(error::operation_failed);\n        return;\n    }\n\n    // This is invoked on the same thread.\n    // Stopped is true and no network threads until after this call.\n    p2p::start(handler);\n}\n\n// Run sequence.\n// ----------------------------------------------------------------------------\n\nvoid p2p_node::run(result_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped);\n        return;\n    }\n\n    // The instance is retained by the stop handler (i.e. until shutdown).\n    const auto header_sync = attach_header_sync_session();\n\n    // This is invoked on a new thread.\n    header_sync->start(\n        std::bind(&p2p_node::handle_headers_synchronized,\n                  this, _1, handler));\n}\n\nvoid p2p_node::handle_headers_synchronized(const code &ec,\n                                           result_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped);\n        return;\n    }\n\n    if (ec)\n    {\n        log::error(LOG_NODE)\n            << \"Failure synchronizing headers: \" << ec.message();\n        handler(ec);\n        return;\n    }\n\n    // The instance is retained by the stop handler (i.e. until shutdown).\n    const auto block_sync = attach_block_sync_session();\n\n    // This is invoked on a new thread.\n    block_sync->start(\n        std::bind(&p2p_node::handle_running,\n                  this, _1, handler));\n}\n\nvoid p2p_node::handle_running(const code &ec, result_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped);\n        return;\n    }\n\n    if (ec)\n    {\n        log::error(LOG_NODE)\n            << \"Failure synchronizing blocks: \" << ec.message();\n        handler(ec);\n        return;\n    }\n\n    uint64_t height;\n\n    if (!blockchain_.get_last_height(height))\n    {\n        log::error(LOG_NODE)\n            << \"The blockchain is corrupt.\";\n        handler(error::operation_failed);\n        return;\n    }\n\n    BITCOIN_ASSERT(height <= max_size_t);\n    set_height(static_cast<size_t>(height));\n\n    log::info(LOG_NODE)\n        << \"Node start height is (\" << height << \").\";\n\n    subscribe_blockchain(\n        std::bind(&p2p_node::handle_reorganized,\n                  this, _1, _2, _3, _4));\n\n    // This is invoked on a new thread.\n    // This is the end of the derived run startup sequence.\n    p2p::run(handler);\n}\n\n// This maintains a height member.\nbool p2p_node::handle_reorganized(const code &ec, size_t fork_point,\n                                  const block_ptr_list &incoming, const block_ptr_list &outgoing)\n{\n    if (stopped() || ec == (code)error::service_stopped)\n        return false;\n\n    if (ec == (code)error::mock)\n        return true;\n\n    if (ec)\n    {\n        log::error(LOG_NODE)\n            << \"Failure handling reorganization: \" << ec.message();\n        stop();\n        return false;\n    }\n\n    for (const auto block : outgoing)\n        log::debug(LOG_NODE)\n            << \"Reorganization discarded block [\"\n            << encode_hash(block->header.hash()) << \"]\";\n\n    BITCOIN_ASSERT(max_size_t - fork_point >= incoming.size());\n    const auto height = fork_point + incoming.size();\n    set_height(height);\n    return true;\n}\n\n// Specializations.\n// ----------------------------------------------------------------------------\n// Create derived sessions and override these to inject from derived node.\n\n// Must not connect until running, otherwise imports may conflict with sync.\n// But we establish the session in network so caller doesn't need to run.\nnetwork::session_manual::ptr p2p_node::attach_manual_session()\n{\n    return attach<node::session_manual>(blockchain_, blockchain_.pool());\n}\n\nnetwork::session_inbound::ptr p2p_node::attach_inbound_session()\n{\n    return attach<node::session_inbound>(blockchain_, blockchain_.pool());\n}\n\nnetwork::session_outbound::ptr p2p_node::attach_outbound_session()\n{\n    return attach<node::session_outbound>(blockchain_, blockchain_.pool());\n}\n\nsession_header_sync::ptr p2p_node::attach_header_sync_session()\n{\n    const auto &checkpoints = blockchain_.chain_settings().checkpoints;\n    return attach<session_header_sync>(hashes_, blockchain_, checkpoints);\n}\n\nsession_block_sync::ptr p2p_node::attach_block_sync_session()\n{\n    return attach<session_block_sync>(hashes_, blockchain_, settings_);\n}\n\n// Shutdown\n// ----------------------------------------------------------------------------\n\nbool p2p_node::stop()\n{\n    // Suspend new work last so we can use work to clear subscribers.\n    return p2p::stop();\n}\n\n// This must be called from the thread that constructed this class (see join).\nbool p2p_node::close()\n{\n    // Invoke own stop to signal work suspension.\n    if (!p2p_node::stop())\n        return false;\n\n    // Join threads first so that there is no activity on the chain at close.\n    return p2p::close() && blockchain_.stop() && blockchain_.close();\n}\n\n// Properties.\n// ----------------------------------------------------------------------------\n\nconst settings &p2p_node::node_settings() const\n{\n    return settings_;\n}\n\nblock_chain &p2p_node::chain()\n{\n    return blockchain_;\n}\n\nblock_chain_impl &p2p_node::chain_impl()\n{\n    return blockchain_;\n}\n\ntx_pool &p2p_node::pool()\n{\n    return blockchain_.pool();\n}\n\n// Subscriptions.\n// ----------------------------------------------------------------------------\n\nvoid p2p_node::subscribe_blockchain(reorganize_handler handler)\n{\n    chain().subscribe_reorganize(handler);\n}\n\nvoid p2p_node::subscribe_tx_pool(transaction_handler handler)\n{\n    pool().subscribe_transaction(handler);\n}\n\n} // namespace node\n} //namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/node/parser.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/node/parser.hpp>\n\n#include <cstdint>\n#include <iostream>\n#include <string>\n#include <boost/filesystem.hpp>\n#include <boost/program_options.hpp>\n#include <UChain/blockchain.hpp>\n#include <UChain/network.hpp>\n#include <UChain/node/p2p_node.hpp>\n#include <UChain/node/settings.hpp>\n\nBC_DECLARE_CONFIG_DEFAULT_PATH(\"libbitcoin\" / \"bn.cfg\")\n\n// TODO: localize descriptions.\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\nusing namespace boost::filesystem;\nusing namespace boost::program_options;\nusing namespace bc::config;\n\n// Initialize configuration by copying the given instance.\nparser::parser(const configuration defaults)\n    : configured(defaults)\n{\n}\n\n// Initialize configuration using defaults of the given context.\nparser::parser(bc::settings context)\n    : configured(context)\n{\n    // A node doesn't require history by default, and history is expensive.\n    configured.database.history_start_height = 500000;\n}\n\noptions_metadata parser::load_options()\n{\n    options_metadata description(\"options\");\n    description.add_options()(\n        BN_CONFIG_VARIABLE \",c\",\n        value<path>(&configured.file),\n        \"Specify path to a configuration settings file.\")(\n        BN_HELP_VARIABLE \",h\",\n        value<bool>(&configured.help)->default_value(false)->zero_tokens(),\n        \"Display command line options.\")(\n        \"initchain,i\",\n        value<bool>(&configured.initchain)->default_value(false)->zero_tokens(),\n        \"Initialize blockchain in the configured directory.\")(\n        BN_SETTINGS_VARIABLE \",s\",\n        value<bool>(&configured.settings)->default_value(false)->zero_tokens(),\n        \"Display all configuration settings.\")(\n        BN_VERSION_VARIABLE \",v\",\n        value<bool>(&configured.version)->default_value(false)->zero_tokens(),\n        \"Display version information.\")(\n        \"daemon,d\",\n        value<bool>(&configured.daemon)->default_value(false)->zero_tokens(),\n        \"Run in daemon mode or not\")\n        //   (\n        //        BS_UI_VARIABLE \"ui,u\",\n        //        value<bool>(&configured.ui)->\n        //        default_value(false),\n        //       \"Open wallet UI.\"\n        //    )\n        ;\n\n    return description;\n}\n\narguments_metadata parser::load_arguments()\n{\n    arguments_metadata description;\n    return description\n        .add(BN_CONFIG_VARIABLE, 1);\n}\n\noptions_metadata parser::load_environment()\n{\n    options_metadata description(\"environment\");\n    description.add_options()(\n        // For some reason po requires this to be a lower case name.\n        // The case must match the other declarations for it to compose.\n        // This composes with the cmdline options and inits to system path.\n        BN_CONFIG_VARIABLE,\n        value<path>(&configured.file)->composing()->default_value(config_default_path()),\n        \"The path to the configuration settings file.\");\n\n    return description;\n}\n\noptions_metadata parser::load_settings()\n{\n    options_metadata description(\"settings\");\n    description.add_options()\n        /* [network] */\n        (\n            \"network.threads\",\n            value<uint32_t>(&configured.network.threads),\n            \"The number of threads in the application threadpool, defaults to 50.\")(\n            \"network.protocol\",\n            value<uint32_t>(&configured.network.protocol),\n            \"The network protocol version, defaults to 70012.\")(\n            \"network.identifier\",\n            value<uint32_t>(&configured.network.identifier),\n            \"The magic number for message headers, defaults to 0x4d53564d.\")(\n            \"network.inbound_port\",\n            value<uint16_t>(&configured.network.inbound_port),\n            \"The port for incoming connections, defaults to 5682.\")(\n            \"network.inbound_connections\",\n            value<uint32_t>(&configured.network.inbound_connections),\n            \"The target number of incoming network connections, defaults to 8.\")(\n            \"network.outbound_connections\",\n            value<uint32_t>(&configured.network.outbound_connections),\n            \"The target number of outgoing network connections, defaults to 8.\")(\n            \"network.manual_attempt_limit\",\n            value<uint32_t>(&configured.network.manual_attempt_limit),\n            \"The attempt limit for manual connection establishment, defaults to 0 (forever).\")(\n            \"network.connect_batch_size\",\n            value<uint32_t>(&configured.network.connect_batch_size),\n            \"The number of concurrent attempts to estalish one connection, defaults to 5.\")(\n            \"network.connect_timeout_seconds\",\n            value<uint32_t>(&configured.network.connect_timeout_seconds),\n            \"The time limit for connection establishment, defaults to 5.\")(\n            \"network.channel_handshake_seconds\",\n            value<uint32_t>(&configured.network.channel_handshake_seconds),\n            \"The time limit to complete the connection handshake, defaults to 30.\")(\n            \"network.channel_heartbeat_minutes\",\n            value<uint32_t>(&configured.network.channel_heartbeat_minutes),\n            \"The time between ping messages, defaults to 5.\")(\n            \"network.channel_inactivity_minutes\",\n            value<uint32_t>(&configured.network.channel_inactivity_minutes),\n            \"The inactivity time limit for any connection, defaults to 30.\")(\n            \"network.channel_expiration_minutes\",\n            value<uint32_t>(&configured.network.channel_expiration_minutes),\n            \"The maximum age limit for an outbound connection, defaults to 1440.\")(\n            \"network.channel_germination_seconds\",\n            value<uint32_t>(&configured.network.channel_germination_seconds),\n            \"The maximum time limit for obtaining seed addresses, defaults to 30.\")(\n            \"network.host_pool_capacity\",\n            value<uint32_t>(&configured.network.host_pool_capacity),\n            \"The maximum number of peer hosts in the pool, defaults to 1000.\")(\n            \"network.relay_transactions\",\n            value<bool>(&configured.network.relay_transactions),\n            \"Request that peers relay transactions, defaults to true.\")(\n            \"network.enable_re_seeding\",\n            value<bool>(&configured.network.enable_re_seeding),\n            \"Re-connect the seed nodes to refresh local hosts cache, when the actual number of outgoing network connection <= 1. defaults to true.\")(\n            \"network.hosts_file\",\n            value<path>(&configured.network.hosts_file),\n            \"The peer hosts cache file path, defaults to 'hosts.cache'.\")(\n            \"network.debug_file\",\n            value<path>(&configured.network.debug_file),\n            \"The debug log file path, defaults to 'debug.log'.\")(\n            \"network.error_file\",\n            value<path>(&configured.network.error_file),\n            \"The error log file path, defaults to 'error.log'.\")(\n            \"network.self\",\n            value<config::authority>(&configured.network.self),\n            \"The advertised public address of this node, defaults to none.\")(\n            \"network.blacklist\",\n            value<config::authority::list>(&configured.network.blacklists),\n            \"IP address to disallow as a peer, multiple entries allowed.\")(\n            \"network.peer\",\n            value<config::endpoint::list>(&configured.network.peers),\n            \"Persistent host:port channels, multiple entries allowed.\")(\n            \"network.upnp_map_port\",\n            value<bool>(&configured.network.upnp_map_port),\n            \"Persistent host:port channels, multiple entries allowed.\")(\n            \"network.be_found\",\n            value<bool>(&configured.network.be_found),\n            \"If broadcast your upnp extern address on the network to allow others find you and connect you.\")(\n            \"network.seed\",\n            value<config::endpoint::list>(&configured.network.seeds),\n            \"A seed node for initializing the host pool, multiple entries allowed.\")\n\n        /* [database] */\n        (\n            \"database.history_start_height\",\n            value<uint32_t>(&configured.database.history_start_height),\n            \"The lower limit of spend indexing, defaults to 500000.\")(\n            \"database.stealth_start_height\",\n            value<uint32_t>(&configured.database.stealth_start_height),\n            \"The lower limit of stealth indexing, defaults to 500000.\")(\n            \"database.directory\",\n            value<path>(&configured.database.directory),\n            \"The blockchain database directory, defaults to 'mainnet'.\")\n\n        /* [blockchain] */\n        (\n            \"blockchain.block_pool_capacity\",\n            value<uint32_t>(&configured.chain.block_pool_capacity),\n            \"The maximum number of orphan blocks in the pool, defaults to 50.\")(\n            \"blockchain.tx_pool_capacity\",\n            value<uint32_t>(&configured.chain.tx_pool_capacity),\n            \"The maximum number of transactions in the pool, defaults to 2000.\")(\n            \"blockchain.tx_pool_consistency\",\n            value<bool>(&configured.chain.tx_pool_consistency),\n            \"Enforce consistency between the pool and the blockchain, defaults to false.\")(\n            \"blockchain.use_testnet_rules\",\n            value<bool>(&configured.chain.use_testnet_rules),\n            \"Use testnet rules for determination of work required, defaults to false.\")(\n            \"blockchain.checkpoint\",\n            value<config::checkpoint::list>(&configured.chain.checkpoints),\n            \"A hash:height checkpoint, multiple entries allowed.\")\n\n        /* [node] */\n        (\n            \"node.block_timeout_seconds\",\n            value<uint32_t>(&configured.node.block_timeout_seconds),\n            \"The time limit for block receipt during initial block download, defaults to 5.\")(\n            \"node.download_connections\",\n            value<uint32_t>(&configured.node.download_connections),\n            \"The maximum number of connections for initial block download, defaults to 8.\")(\n            \"node.tx_pool_refresh\",\n            value<bool>(&configured.node.tx_pool_refresh),\n            \"Refresh the transaction pool on reorganization and channel start, defaults to true.\");\n\n    return description;\n}\n\nbool parser::parse(int argc, const char *argv[], std::ostream &error)\n{\n    try\n    {\n        auto file = false;\n        variables_map variables;\n        load_command_variables(variables, argc, argv);\n        load_environment_variables(variables, BN_ENVIRONMENT_VARIABLE_PREFIX);\n\n        // Don't load the rest if any of these options are specified.\n        if (!get_option(variables, BN_VERSION_VARIABLE) &&\n            !get_option(variables, BN_SETTINGS_VARIABLE) &&\n            !get_option(variables, BN_HELP_VARIABLE))\n        {\n            // Returns true if the settings were loaded from a file.\n            file = load_configuration_variables(variables, BN_CONFIG_VARIABLE);\n        }\n\n        // Update bound variables in metadata.settings.\n        notify(variables);\n\n        // Clear the config file path if it wasn't used.\n        if (!file)\n            configured.file.clear();\n    }\n    catch (const boost::program_options::error &e)\n    {\n        // This is obtained from boost, which circumvents our localization.\n        error << format_invalid_parameter(e.what()) << std::endl;\n        return false;\n    }\n\n    return true;\n}\n\n} // namespace node\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/node/protocols/protocol_block_in.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/node/protocols/protocol_block_in.hpp>\n\n#include <algorithm>\n#include <functional>\n#include <memory>\n#include <string>\n#include <UChain/blockchain.hpp>\n#include <UChain/network.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\n#define NAME \"block\"\n#define CLASS protocol_block_in\n\nusing namespace bc::blockchain;\nusing namespace bc::message;\nusing namespace bc::network;\nusing namespace std::placeholders;\n\nstatic constexpr auto perpetual_timer = true;\nstatic const auto get_blocks_interval = asio::seconds(100);\n\nprotocol_block_in::protocol_block_in(p2p &network, channel::ptr channel,\n                                     block_chain &blockchain)\n    : protocol_timer(network, channel, perpetual_timer, NAME),\n      blockchain_(blockchain),\n      last_locator_top_(null_hash),\n      current_chain_top_(null_hash),\n\n      // TODO: move send_headers to a derived class protocol_block_in_70012.\n      headers_from_peer_(peer_version().value >= version::level::bip130),\n      headers_batch_size_{0},\n\n      CONSTRUCT_TRACK(protocol_block_in)\n{\n}\n\nprotocol_block_in::ptr protocol_block_in::do_subscribe()\n{\n    // TODO: move headers to a derived class protocol_block_in_31800.\n    SUBSCRIBE2(headers, handle_receive_headers, _1, _2);\n\n    // TODO: move not_found to a derived class protocol_block_in_70001.\n    SUBSCRIBE2(not_found, handle_receive_not_found, _1, _2);\n\n    SUBSCRIBE2(inventory, handle_receive_inventory, _1, _2);\n    SUBSCRIBE2(block_msg, handle_receive_block, _1, _2);\n    protocol_timer::start(get_blocks_interval, BIND1(get_block_inventory, _1));\n    return std::dynamic_pointer_cast<protocol_block_in>(protocol::shared_from_this());\n}\n\n// Start.\n//-----------------------------------------------------------------------------\n\nvoid protocol_block_in::start()\n{\n    // Use perpetual protocol timer to prevent stall (our heartbeat).\n\n    // TODO: move send_headers to a derived class protocol_block_in_70012.\n    if (headers_from_peer_)\n    {\n        // Allow peer to send headers vs. inventory block anncements.\n        //        SEND2(send_headers(), handle_send, _1, send_headers::command);\n    }\n\n    // Subscribe to block acceptance notifications (for gap fill redundancy).\n    blockchain_.subscribe_reorganize(\n        BIND4(handle_reorganized, _1, _2, _3, _4));\n    if (channel_stopped())\n    {\n        blockchain_.fired();\n    }\n\n    // Send initial get_[blocks|headers] message by simulating first heartbeat.\n    //    set_event(error::success);\n    //    send_get_blocks(null_hash);\n    get_block_inventory(error::success);\n}\n\n// Send get_[headers|blocks] sequence.\n//-----------------------------------------------------------------------------\n\n// This is fired by the callback (i.e. base timer and stop handler).\nvoid protocol_block_in::get_block_inventory(const code &ec)\n{\n    if (stopped())\n    {\n        blockchain_.fired();\n        return;\n    }\n\n    if (ec && ec != (code)error::channel_timeout)\n    {\n        log::trace(LOG_NODE)\n            << \"Failure in block timer for [\" << authority() << \"] \"\n            << ec.message();\n        stop(ec);\n        return;\n    }\n\n    auto &blockchain = static_cast<block_chain_impl &>(blockchain_);\n    uint64_t top;\n    auto is_got = blockchain.get_last_height(top);\n    int64_t block_interval = 20000;\n    auto res = static_cast<int64_t>(top) - static_cast<int64_t>(peer_start_height()) - block_interval;\n    if (!is_got || res > 0)\n    {\n        return;\n    }\n\n    static uint32_t num = 0;\n    // This is also sent after each reorg.\n    send_get_blocks(null_hash);\n\n    if (num++ % 4 == 3)\n    {\n        organizer &organizer = blockchain_.get_organizer();\n        auto &&hashes = organizer.get_fork_chain_last_block_hashes();\n        for (auto &i : hashes)\n        {\n            log::trace(LOG_NODE) << \"send fetch_more_block hasese size:\" << hashes.size() << \" hash:\" << encode_hash(i.first);\n            send_get_blocks(i.first, null_hash);\n        }\n    }\n}\n\nvoid protocol_block_in::send_get_blocks(const hash_digest &stop_hash)\n{\n    const auto chain_top = current_chain_top_.load();\n    const auto last_locator_top = last_locator_top_.load();\n\n    // Avoid requesting from the same start as last request to this peer.\n    // This does not guarantee prevention, it's just an optimization.\n    if (chain_top == null_hash || last_locator_top != chain_top)\n        blockchain_.fetch_block_locator(\n            BIND3(handle_fetch_block_locator, _1, _2, stop_hash));\n}\n\nvoid protocol_block_in::send_get_blocks(const hash_digest &from_hash, const hash_digest &to_hash)\n{\n    hash_list locator;\n    locator.push_back(from_hash);\n    code code;\n    handle_fetch_block_locator(code, locator, to_hash);\n}\n\nvoid protocol_block_in::handle_fetch_block_locator(const code &ec,\n                                                   const hash_list &locator, const hash_digest &stop_hash)\n{\n    if (stopped() || ec == (code)error::service_stopped || locator.empty())\n        return;\n\n    if (ec)\n    {\n        log::error(LOG_NODE)\n            << \"Internal failure generating block locator for [\"\n            << authority() << \"] \" << ec.message();\n        stop(ec);\n        return;\n    }\n\n    log::trace(LOG_NODE)\n        << \"Ask [\" << authority() << \"] for block inventory from [\"\n        << encode_hash(locator.front()) << \"] (\" << locator.size()\n        << \") to [\"\n        << (stop_hash == null_hash ? \"500\" : encode_hash(stop_hash)) << \"]\";\n\n    // TODO: move get_headers to a derived class protocol_block_in_31800.\n    if (headers_from_peer_)\n    {\n        const get_headers request{std::move(locator), stop_hash};\n        SEND2(request, handle_send, _1, request.command);\n    }\n    else\n    {\n        const get_blocks request{std::move(locator), stop_hash};\n        SEND2(request, handle_send, _1, request.command);\n    }\n\n    // Save the locator top to prevent a redundant future request.\n    last_locator_top_.store(locator.front());\n}\n\n// Receive headers|inventory sequence.\n//-----------------------------------------------------------------------------\n\n// TODO: move headers to a derived class protocol_block_in_31800.\n// This originates from send_header->annoucements and get_headers requests.\nbool protocol_block_in::handle_receive_headers(const code &ec,\n                                               headers_ptr message)\n{\n    if (stopped())\n        return false;\n\n    if (ec)\n    {\n        log::trace(LOG_NODE)\n            << \"Failure getting headers from [\" << authority() << \"] \"\n            << ec.message();\n        stop(ec);\n        return false;\n    }\n\n    // There is no benefit to this use of headers, in fact it is suboptimal.\n    // In v3 headers will be used to build block tree before getting blocks.\n    const auto response = std::make_shared<get_data>();\n    message->to_inventory(response->inventories, inventory::type_id::block);\n    log::trace(LOG_NODE) << \"protocol_block_in handle_receive_headers size,\" << message->elements.size();\n\n    // Remove block hashes found in the orphan pool.\n    blockchain_.filter_orphans(response,\n                               BIND2(handle_filter_orphans, _1, response));\n    return true;\n}\n\n// This originates from default annoucements and get_blocks requests.\nbool protocol_block_in::handle_receive_inventory(const code &ec,\n                                                 inventory_ptr message)\n{\n    if (stopped())\n    {\n        return false;\n    }\n\n    if (ec)\n    {\n        log::trace(LOG_NODE)\n            << \"Failure getting inventory from [\" << authority() << \"] \"\n            << ec.message();\n        stop(ec);\n        return false;\n    }\n\n    log::trace(LOG_NODE) << \"protocol block in, handle receive inventory,size,\" << message->inventories.size();\n\n    const auto response = std::make_shared<get_data>();\n    message->reduce(response->inventories, inventory::type_id::block);\n    if (response->inventories.empty())\n    {\n        return true;\n    }\n\n    // Remove block hashes found in the orphan pool.\n    blockchain_.filter_orphans(response,\n                               BIND2(handle_filter_orphans, _1, response));\n    return true;\n}\n\nvoid protocol_block_in::handle_filter_orphans(const code &ec,\n                                              get_data_ptr message)\n{\n    if (stopped() || ec == (code)error::service_stopped ||\n        message->inventories.empty())\n        return;\n\n    if (ec)\n    {\n        log::error(LOG_NODE)\n            << \"Internal failure locating missing orphan hashes for [\"\n            << authority() << \"] \" << ec.message();\n        stop(ec);\n        return;\n    }\n\n    // Remove block hashes found in the blockchain (dups not allowed).\n    blockchain_.filter_blocks(message, BIND2(send_get_data, _1, message));\n}\n\nvoid protocol_block_in::send_get_data(const code &ec, get_data_ptr message)\n{\n    if (stopped() || ec == (code)error::service_stopped ||\n        message->inventories.empty())\n        return;\n\n    if (ec)\n    {\n        log::error(LOG_NODE)\n            << \"Internal failure locating missing block hashes for [\"\n            << authority() << \"] \" << ec.message();\n        stop(ec);\n        return;\n    }\n\n    headers_batch_size_ += message->inventories.size();\n\n    // inventory|headers->get_data[blocks]\n    SEND2(*message, handle_send, _1, message->command);\n}\n\n// Receive not_found sequence.\n//-----------------------------------------------------------------------------\n\n// TODO: move not_found to a derived class protocol_block_in_70001.\nbool protocol_block_in::handle_receive_not_found(const code &ec,\n                                                 message::not_found::ptr message)\n{\n    if (stopped())\n        return false;\n\n    if (ec)\n    {\n        log::trace(LOG_NODE)\n            << \"Failure getting block not_found from [\" << authority() << \"] \"\n            << ec.message();\n        stop(ec);\n        return false;\n    }\n\n    hash_list hashes;\n    message->to_hashes(hashes, inventory::type_id::block);\n\n    headers_batch_size_ -= hashes.size();\n\n    // The peer cannot locate a block that it told us it had.\n    // This only results from reorganization assuming peer is proper.\n    for (const auto hash : hashes)\n    {\n        log::trace(LOG_NODE)\n            << \"Block not_found [\" << encode_hash(hash) << \"] from [\"\n            << authority() << \"]\";\n    }\n\n    return true;\n}\n\n// Receive block sequence.\n//-----------------------------------------------------------------------------\n\nbool protocol_block_in::handle_receive_block(const code &ec, block_ptr message)\n{\n    if (stopped())\n        return false;\n\n    if (ec)\n    {\n        log::trace(LOG_NODE)\n            << \"Failure getting block from [\" << authority() << \"] \"\n            << ec.message();\n        stop(ec);\n        return false;\n    }\n\n    --headers_batch_size_;\n\n    if (!headers_batch_size_.load())\n    {\n        send_get_blocks(null_hash);\n    }\n\n    // Reset the timer because we just received a block from this peer.\n    // Once we are at the top this will end up polling the peer.\n    reset_timer();\n\n    // We will pick this up in handle_reorganized.\n    message->set_originator(nonce());\n\n    log::trace(LOG_NODE) << \"from \" << authority() << \",receive block hash,\" << encode_hash(message->header.hash()) << \",tx-size,\" << message->header.transaction_count << \",number,\" << message->header.number;\n\n    blockchain_.store(message, BIND2(handle_store_block, _1, message));\n    return true;\n}\n\nvoid protocol_block_in::handle_store_block(const code &ec, block_ptr message)\n{\n    if (stopped() || ec == (code)error::service_stopped)\n        return;\n\n    // Ignore the block that we already have, a common result.\n    if (ec == (code)error::duplicate)\n    {\n        log::trace(LOG_NODE)\n            << \"Redundant block from [\" << authority() << \"] \"\n            << ec.message();\n        return;\n    }\n\n    if (ec == (code)error::fetch_more_block)\n    {\n        log::trace(LOG_NODE)\n            << \"fetch more blocks start_hash:\"\n            << encode_hash(message->header.hash());\n        send_get_blocks(message->header.hash(), null_hash);\n        return;\n    }\n\n    // There are no other expected errors from the store call.\n    if (ec)\n    {\n        log::warning(LOG_NODE)\n            << \"Error storing block from [\" << authority() << \"] \"\n            << ec.message();\n        stop(ec);\n        return;\n    }\n\n    // The block is accepted as an orphan, possibly for immediate acceptance.\n    log::trace(LOG_NODE)\n        << \"Potential block from [\" << authority() << \"].\";\n\n    // Ask the peer for blocks from the top up to this orphan.\n    //    send_get_blocks(message->header.hash());\n}\n\n// Subscription.\n//-----------------------------------------------------------------------------\n\n// At least one block was accepted into the chain, originating from any peer.\nbool protocol_block_in::handle_reorganized(const code &ec, size_t fork_point,\n                                           const block_ptr_list &incoming, const block_ptr_list &outgoing)\n{\n    if (stopped() || ec == (code)error::service_stopped || incoming.empty())\n    {\n        log::trace(LOG_NODE) << \"protocol_block_in::handle_reorganized ,\" << stopped() << \",\" << ec.message() << \",\" << incoming.size();\n        return false;\n    }\n\n    if (ec == (code)error::mock)\n    {\n        return true;\n    }\n\n    if (ec)\n    {\n        log::error(LOG_NODE)\n            << \"Failure handling reorganization for [\" << authority() << \"] \"\n            << ec.message();\n        stop(ec);\n        return false;\n    }\n\n    // TODO: use p2p_node instead.\n    // Update the top of the chain.\n    current_chain_top_.store(incoming.back()->header.hash());\n    auto last_hash = incoming.back()->header.hash();\n    blockchain_.fetch_block_height(last_hash, [&last_hash](const code &ec, uint64_t height) {\n        log::trace(LOG_NODE) << encode_hash(last_hash) << \",latest block,\" << height;\n    });\n\n    // Report the blocks that originated from this peer.\n    // If originating peer is dropped there will be no report here.\n    for (const auto block : incoming)\n        if (block->originator() == nonce())\n            log::trace(LOG_NODE)\n                << \"Block [\" << encode_hash(block->header.hash()) << \"] from [\"\n                << authority() << \"].\";\n\n    return true;\n}\n\n} // namespace node\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/node/protocols/protocol_block_out.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/node/protocols/protocol_block_out.hpp>\n\n#include <algorithm>\n#include <cstddef>\n#include <cmath>\n#include <functional>\n#include <string>\n#include <UChain/blockchain.hpp>\n#include <UChain/network.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\n#define NAME \"block\"\n#define CLASS protocol_block_out\n\nusing namespace bc::blockchain;\nusing namespace bc::message;\nusing namespace bc::network;\nusing namespace std::placeholders;\n\n// The largest reasonable search is 10 for the first block of 10 hashes,\n// 1 for the genesis block, 1 for disparity between peers and log2(top)\n// for the exponential back-off algorithm.\nstatic constexpr auto locator_allowance = 12u;\n\nprotocol_block_out::protocol_block_out(p2p &network, channel::ptr channel,\n                                       block_chain &blockchain)\n    : protocol_events(network, channel, NAME),\n      last_locator_top_(null_hash),\n      current_chain_height_(0),\n      blockchain_(blockchain),\n\n      // TODO: move send_headers to a derived class protocol_block_out_70012.\n      headers_to_peer_(network.network_settings().protocol >=\n                       version::level::bip130),\n\n      CONSTRUCT_TRACK(protocol_block_out)\n{\n}\n\nprotocol_block_out::ptr protocol_block_out::do_subscribe()\n{\n    if (headers_to_peer_)\n    {\n        // Send headers vs. inventory anncements if headers_to_peer_ is set.\n        log::trace(LOG_NODE) << \"protocol block out headers to peer\";\n        SUBSCRIBE2(send_headers, handle_receive_send_headers, _1, _2);\n    }\n\n    // TODO: move get_headers to a derived class protocol_block_out_31800.\n    SUBSCRIBE2(get_headers, handle_receive_get_headers, _1, _2);\n    SUBSCRIBE2(get_blocks, handle_receive_get_blocks, _1, _2);\n    SUBSCRIBE2(get_data, handle_receive_get_data, _1, _2);\n\n    protocol_events::start(BIND1(handle_stop, _1));\n    return std::dynamic_pointer_cast<protocol_block_out>(protocol::shared_from_this());\n}\n\n// Start.\n//-----------------------------------------------------------------------------\n\nvoid protocol_block_out::start()\n{\n\n    // TODO: move send_headers to a derived class protocol_block_out_70012.\n\n    // Subscribe to block acceptance notifications (our heartbeat).\n    blockchain_.subscribe_reorganize(\n        BIND4(handle_reorganized, _1, _2, _3, _4));\n    if (channel_stopped())\n    {\n        blockchain_.fired();\n    }\n}\n\n// Receive send_headers.\n//-----------------------------------------------------------------------------\n\n// TODO: move send_headers to a derived class protocol_block_out_70012.\nbool protocol_block_out::handle_receive_send_headers(const code &ec,\n                                                     send_headers_ptr message)\n{\n    if (stopped())\n        return false;\n\n    if (ec)\n    {\n        log::trace(LOG_NODE)\n            << \"Failure getting \" << message->command << \" from [\"\n            << authority() << \"] \" << ec.message();\n        stop(ec);\n        return false;\n    }\n\n    // Block annoucements will be headers messages instead of inventory.\n    headers_to_peer_.store(true);\n\n    // Do not resubscribe after handling this one-time message.\n    return false;\n}\n\n// Receive get_headers sequence.\n//-----------------------------------------------------------------------------\n\n// The locator cannot be longer than allowed by our chain length.\n// This is DoS protection, otherwise a peer could tie up our database.\n// If we are not synced to near the height of peers then this effectively\n// prevents peers from syncing from us. Ideally we should use initial block\n// download to get close before enabling this protocol.\nsize_t protocol_block_out::locator_limit() const\n{\n    const auto height = current_chain_height_.load();\n    return static_cast<size_t>(std::log2(height) + locator_allowance);\n}\n\n// TODO: move get_headers to a derived class protocol_block_out_31800.\nbool protocol_block_out::handle_receive_get_headers(const code &ec,\n                                                    get_headers_ptr message)\n{\n    if (stopped())\n        return false;\n\n    if (ec)\n    {\n        log::trace(LOG_NODE)\n            << \"Failure getting get_headers from [\" << ec.message();\n        stop(ec);\n        return false;\n    }\n\n    const auto locator_size = message->start_hashes.size();\n\n    if (locator_size > locator_limit())\n    {\n        log::debug(LOG_NODE)\n            << \"Invalid get_headers locator size (\" << locator_size\n            << \") from [\" << authority() << \"] \";\n        stop(error::channel_stopped);\n        return false;\n    }\n\n    // The peer threshold prevents a peer from creating an unnecessary backlog\n    // for itself in the case where it is requesting without having processed\n    // all of its existing backlog. This also reduces its load on us.\n    // This could cause a problem during a reorg, where the peer regresses\n    // and one of its other peers populates the chain back to this level. In\n    // that case we would not respond but our peer's other peer should.\n    const auto threshold = last_locator_top_.load();\n\n    auto need_to_locate = true;\n    if (locator_size > 0)\n    {\n        auto &blockchain = static_cast<simple_chain &>(static_cast<block_chain_impl &>(blockchain_));\n        uint64_t height{0};\n        auto ok = blockchain.get_height(height, message->start_hashes.back());\n        if (!ok)\n        {\n            need_to_locate = false;\n        }\n    }\n\n    if (need_to_locate)\n    {\n        auto &blockchain = static_cast<simple_chain &>(static_cast<block_chain_impl &>(blockchain_));\n        uint64_t top;\n        auto is_got = blockchain.get_last_height(top);\n        int64_t block_interval = 2000;\n        auto res = static_cast<int64_t>(top) - static_cast<int64_t>(peer_start_height()) - block_interval;\n        blockchain_.fetch_locator_block_headers(*message, threshold, res > 0 ? locator_cap : 10,\n                                                BIND2(handle_fetch_locator_headers, _1, _2));\n    }\n\n    return true;\n}\n\n// TODO: move headers to a derived class protocol_block_out_31800.\nvoid protocol_block_out::handle_fetch_locator_headers(const code &ec,\n                                                      const header_list &headers)\n{\n    if (stopped() || ec == (code)error::service_stopped)\n        return;\n\n    if (ec)\n    {\n        log::error(LOG_NODE)\n            << \"Internal failure locating locator block headers for [\"\n            << authority() << \"] \" << ec.message();\n        stop(ec);\n        return;\n    }\n\n    if (headers.empty())\n    {\n        return;\n    }\n    log::trace(LOG_NODE)\n        << \"handle fetch locator headers size,\" << headers.size();\n\n    // Respond to get_headers with headers.\n    const message::headers response(headers);\n    SEND2(response, handle_send, _1, response.command);\n}\n\n// Receive get_blocks sequence.\n//-----------------------------------------------------------------------------\n\nbool protocol_block_out::handle_receive_get_blocks(const code &ec,\n                                                   get_blocks_ptr message)\n{\n    if (stopped())\n        return false;\n\n    if (ec)\n    {\n        log::trace(LOG_NODE)\n            << \"Failure getting get_blocks from [\" << ec.message();\n        stop(ec);\n        return false;\n    }\n\n    const auto locator_size = message->start_hashes.size();\n\n    if (locator_size > locator_limit())\n    {\n        log::warning(LOG_NODE)\n            << \"Invalid get_blocks locator size (\" << locator_size\n            << \") from [\" << authority() << \"] \";\n        stop(error::channel_stopped);\n        return false;\n    }\n\n    // The peer threshold prevents a peer from creating an unnecessary backlog\n    // for itself in the case where it is requesting without having processed\n    // all of its existing backlog. This also reduces its load on us.\n    // This could cause a problem during a reorg, where the peer regresses\n    // and one of its other peers populates the chain back to this level. In\n    // that case we would not respond but our peer's other peer should.\n    const auto threshold = last_locator_top_.load();\n    auto &blockchain = static_cast<block_chain_impl &>(blockchain_);\n    uint64_t top;\n    auto is_got = blockchain.get_last_height(top);\n    int64_t block_interval = 2000;\n    auto res = static_cast<int64_t>(top) - static_cast<int64_t>(peer_start_height()) - block_interval;\n\n    blockchain_.fetch_locator_block_hashes(*message, threshold, res > 0 ? locator_cap : 10,\n                                           BIND2(handle_fetch_locator_hashes, _1, _2));\n    return true;\n}\n\nvoid protocol_block_out::handle_fetch_locator_hashes(const code &ec,\n                                                     const hash_list &hashes)\n{\n    if (stopped() || ec == (code)error::service_stopped)\n        return;\n\n    if (ec)\n    {\n        log::error(LOG_NODE)\n            << \"Internal failure locating locator block hashes for [\"\n            << authority() << \"] \" << ec.message();\n        stop(ec);\n        return;\n    }\n\n    // Respond to get_blocks with inventory.\n    const inventory response(hashes, inventory::type_id::block);\n    SEND2(response, handle_send, _1, response.command);\n\n    // Save the locator top to limit an overlapping future request.\n    if (!hashes.empty())\n        last_locator_top_.store(hashes.front());\n}\n\n// Receive get_data sequence.\n//-----------------------------------------------------------------------------\n\n// TODO: move filtered_block to derived class protocol_block_out_70001.\nbool protocol_block_out::handle_receive_get_data(const code &ec,\n                                                 get_data_ptr message)\n{\n    if (stopped())\n    {\n        return false;\n    }\n\n    if (ec)\n    {\n        log::trace(LOG_NODE)\n            << \"Failure getting inventory from [\" << authority() << \"] \"\n            << ec.message();\n        stop(ec);\n        return false;\n    }\n\n    // TODO: these must return message objects or be copied!\n    // Ignore non-block inventory requests in this protocol.\n    for (const auto &inventory : message->inventories)\n    {\n        if (inventory.type == inventory::type_id::block)\n            blockchain_.fetch_block(inventory.hash,\n                                    BIND3(send_block, _1, _2, inventory.hash));\n        else if (inventory.type == inventory::type_id::filtered_block)\n            blockchain_.fetch_merkle_block(inventory.hash,\n                                           BIND3(send_merkle_block, _1, _2, inventory.hash));\n    }\n\n    return true;\n}\n\n// TODO: move not_found to derived class protocol_block_out_70001.\nvoid protocol_block_out::send_block(const code &ec, chain::block::ptr block,\n                                    const hash_digest &hash)\n{\n    if (stopped() || ec == (code)error::service_stopped)\n    {\n        return;\n    }\n\n    if (ec == (code)error::not_found)\n    {\n        log::trace(LOG_NODE)\n            << \"Block requested by [\" << authority() << \"] not found.\" << encode_hash(hash);\n\n        const not_found reply{{inventory::type_id::block, hash}};\n        SEND2(reply, handle_send, _1, reply.command);\n        return;\n    }\n\n    if (ec)\n    {\n        log::error(LOG_NODE)\n            << \"Internal failure locating block requested by [\"\n            << authority() << \"] \" << ec.message();\n        stop(ec);\n        return;\n    }\n\n    // TODO: eliminate copy.\n    SEND2(block_msg(*block), handle_send, _1, block_msg::command);\n}\n\n// TODO: move filtered_block to derived class protocol_block_out_70001.\nvoid protocol_block_out::send_merkle_block(const code &ec,\n                                           merkle_block_ptr message, const hash_digest &hash)\n{\n    if (stopped() || ec == (code)error::service_stopped)\n        return;\n\n    if (ec == (code)error::not_found)\n    {\n        log::trace(LOG_NODE)\n            << \"Merkle block requested by [\" << authority() << \"] not found.\";\n\n        const not_found reply{{inventory::type_id::filtered_block, hash}};\n        SEND2(reply, handle_send, _1, reply.command);\n        return;\n    }\n\n    if (ec)\n    {\n        log::error(LOG_NODE)\n            << \"Internal failure locating merkle block requested by [\"\n            << authority() << \"] \" << ec.message();\n        stop(ec);\n        return;\n    }\n\n    SEND2(*message, handle_send, _1, message->command);\n}\n\n// Subscription.\n//-----------------------------------------------------------------------------\n\n// TODO: make sure we are announcing older blocks first here.\n// We never announce or inventory an orphan, only indexed blocks.\nbool protocol_block_out::handle_reorganized(const code &ec, size_t fork_point,\n                                            const block_ptr_list &incoming, const block_ptr_list &outgoing)\n{\n    if (stopped() || ec == (code)error::service_stopped)\n        return false;\n\n    if (ec == (code)error::mock)\n    {\n        return true;\n    }\n\n    if (ec)\n    {\n        log::error(LOG_NODE)\n            << \"Failure handling reorganization: \" << ec.message();\n        stop(ec);\n        return false;\n    }\n\n    // TODO: use p2p_node instead.\n    // Save the latest height.\n    BITCOIN_ASSERT(max_size_t - fork_point >= incoming.size());\n    current_chain_height_.store(fork_point + incoming.size());\n\n    // TODO: move announce headers to a derived class protocol_block_in_70012.\n    if (headers_to_peer_)\n    {\n        headers announcement;\n\n        for (const auto block : incoming)\n            if (block->originator() != nonce())\n                announcement.elements.push_back(block->header);\n\n        if (!announcement.elements.empty())\n        {\n            auto &blockchain = static_cast<block_chain_impl &>(blockchain_);\n            uint64_t top;\n            auto is_got = blockchain.get_last_height(top);\n            int64_t block_interval = 20000;\n            auto res = std::abs(static_cast<int64_t>(top) - static_cast<int64_t>(peer_start_height()));\n            if (!is_got || res > block_interval)\n            {\n                return true;\n            }\n            SEND2(announcement, handle_send, _1, announcement.command);\n        }\n        return true;\n    }\n\n    static const auto id = inventory::type_id::block;\n    inventory announcement;\n\n    for (const auto block : incoming)\n        if (block->originator() != nonce())\n            announcement.inventories.push_back({id, block->header.hash()});\n\n    if (!announcement.inventories.empty())\n    {\n        auto &blockchain = static_cast<block_chain_impl &>(blockchain_);\n        uint64_t top;\n        auto is_got = blockchain.get_last_height(top);\n        int64_t block_interval = 20000;\n        auto res = std::abs(static_cast<int64_t>(top) - static_cast<int64_t>(peer_start_height()));\n        if (!is_got || res > block_interval)\n        {\n            return true;\n        }\n        SEND2(announcement, handle_send, _1, announcement.command);\n    }\n    return true;\n}\n\nvoid protocol_block_out::handle_stop(const code &)\n{\n    log::trace(LOG_NETWORK)\n        << \"Stopped block_out protocol\";\n    blockchain_.fired();\n}\n\n} // namespace node\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/node/protocols/protocol_block_sync.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/node/protocols/protocol_block_sync.hpp>\n\n#include <algorithm>\n#include <cstddef>\n#include <functional>\n#include <stdexcept>\n#include <UChain/blockchain.hpp>\n#include <UChain/network.hpp>\n#include <UChain/node/utility/reservation.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\n#define NAME \"block_sync\"\n#define CLASS protocol_block_sync\n\nusing namespace bc::message;\nusing namespace bc::network;\nusing namespace std::placeholders;\n\n// The interval in which block download rate is tested.\nstatic const asio::seconds expiry_interval(5);\n\n// Depends on protocol_header_sync, which requires protocol version 31800.\nprotocol_block_sync::protocol_block_sync(p2p &network, channel::ptr channel,\n                                         reservation::ptr row)\n    : protocol_timer(network, channel, true, NAME),\n      reservation_(row),\n      CONSTRUCT_TRACK(protocol_block_sync)\n{\n}\n\n// Start sequence.\n// ----------------------------------------------------------------------------\n\nvoid protocol_block_sync::start(event_handler handler)\n{\n    auto complete = synchronize(BIND2(blocks_complete, _1, handler), 1, NAME);\n    protocol_timer::start(expiry_interval, BIND2(handle_event, _1, complete));\n\n    SUBSCRIBE3(block_msg, handle_receive, _1, _2, complete);\n\n    // This is the end of the start sequence.\n    send_get_blocks(complete, true);\n}\n\n// Peer sync sequence.\n// ----------------------------------------------------------------------------\n\nvoid protocol_block_sync::send_get_blocks(event_handler complete, bool reset)\n{\n    if (stopped())\n        return;\n\n    if (reservation_->stopped())\n    {\n        log::trace(LOG_NODE)\n            << \"Stopping complete slot (\" << reservation_->slot() << \").\";\n        complete(error::success);\n        return;\n    }\n\n    // We may be a new channel (reset) or may have a new packet.\n    const auto request = reservation_->request(reset);\n\n    // Or we may be the same channel and with hashes already requested.\n    if (request.inventories.empty())\n        return;\n\n    log::trace(LOG_NODE)\n        << \"Sending request of \" << request.inventories.size()\n        << \" hashes for slot (\" << reservation_->slot() << \").\";\n\n    SEND2(request, handle_send, _1, complete);\n}\n\nvoid protocol_block_sync::handle_send(const code &ec, event_handler complete)\n{\n    if (stopped())\n        return;\n\n    if (ec)\n    {\n        log::warning(LOG_NODE)\n            << \"Failure sending get blocks to slot (\" << reservation_->slot()\n            << \") \" << ec.message();\n        complete(ec);\n    }\n}\n\n// The message subscriber implements an optimization to bypass queueing of\n// block messages. This requires that this handler never call back into the\n// subscriber. Otherwise a deadlock will result. This in turn requires that\n// the 'complete' parameter handler never call into the message subscriber.\nbool protocol_block_sync::handle_receive(const code &ec, block_ptr message,\n                                         event_handler complete)\n{\n    if (stopped())\n        return false;\n\n    if (ec)\n    {\n        log::trace(LOG_NODE)\n            << \"Receive failure on slot (\" << reservation_->slot() << \") \"\n            << ec.message();\n        complete(ec);\n        return false;\n    }\n\n    // Add the block to the blockchain store.\n    reservation_->import(message);\n\n    if (reservation_->toggle_partitioned())\n    {\n        log::trace(LOG_NODE)\n            << \"Restarting partitioned slot (\" << reservation_->slot() << \").\";\n        complete(error::channel_stopped);\n        return false;\n    }\n\n    // Request more blocks if our reservation has been expanded.\n    send_get_blocks(complete, false);\n    return true;\n}\n\n// This is fired by the base timer and stop handler.\nvoid protocol_block_sync::handle_event(const code &ec, event_handler complete)\n{\n    if (ec == (code)error::service_stopped)\n    {\n        complete(ec);\n        return;\n    }\n\n    if (ec == (code)error::channel_stopped)\n    {\n        complete(ec);\n        return;\n    }\n\n    if (ec && ec != (code)error::channel_timeout)\n    {\n        log::trace(LOG_NODE)\n            << \"Failure in block sync timer for slot (\" << reservation_->slot()\n            << \") \" << ec.message();\n        complete(ec);\n        return;\n    }\n\n    // This results from other channels taking this channel's hashes in\n    // combination with this channel's peer not responding to the last request.\n    // Causing a successful stop here prevents channel startup just to stop.\n    if (reservation_->stopped())\n    {\n        log::trace(LOG_NODE)\n            << \"Stopping complete slot (\" << reservation_->slot() << \").\";\n        complete(error::success);\n        return;\n    }\n\n    if (reservation_->expired())\n    {\n        log::trace(LOG_NODE)\n            << \"Restarting slow slot (\" << reservation_->slot() << \")\";\n        complete(error::channel_timeout);\n        return;\n    }\n    complete(ec);\n}\n\nvoid protocol_block_sync::blocks_complete(const code &ec,\n                                          event_handler handler)\n{\n    // We are no longer receiving blocks, so exclude from average.\n    reservation_->reset();\n    log::trace(LOG_NODE) << \"protocol block sync blocks complete,\" << ec.message();\n    // The session does not need to handle the stop.\n    stop(error::channel_stopped);\n    // This is the end of the peer sync sequence.\n    // If there is no error the hash list must be empty and remain so.\n    handler(ec);\n}\n\n} // namespace node\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/node/protocols/protocol_header_sync.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/node/protocols/protocol_header_sync.hpp>\n\n#include <algorithm>\n#include <cstddef>\n#include <functional>\n#include <UChain/network.hpp>\n#include <UChain/node/p2p_node.hpp>\n#include <UChain/node/utility/header_queue.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\n#define NAME \"header_sync\"\n#define CLASS protocol_header_sync\n\nusing namespace bc::config;\nusing namespace bc::message;\nusing namespace bc::network;\nusing namespace std::placeholders;\n\n// The protocol maximum size for get data header requests.\nstatic constexpr size_t max_header_response = 500;\n\n// The interval in which header download rate is measured and tested.\nstatic const asio::seconds expiry_interval(5);\n\n// This class requires protocol version 31800.\nprotocol_header_sync::protocol_header_sync(p2p &network,\n                                           channel::ptr channel, header_queue &hashes, uint32_t minimum_rate,\n                                           const checkpoint &last)\n    : protocol_timer(network, channel, true, NAME),\n      hashes_(hashes),\n      current_second_(0),\n      minimum_rate_(minimum_rate),\n      start_size_(hashes.size()),\n      last_(last),\n      CONSTRUCT_TRACK(protocol_header_sync)\n{\n}\n\n// Utilities\n// ----------------------------------------------------------------------------\n\nsize_t protocol_header_sync::next_height() const\n{\n    return hashes_.last_height() + 1;\n}\n\nsize_t protocol_header_sync::sync_rate() const\n{\n    // We can never roll back prior to start size since it's min final height.\n    return (hashes_.size() - start_size_) / current_second_;\n}\n\n// Start sequence.\n// ----------------------------------------------------------------------------\n\nvoid protocol_header_sync::start(event_handler handler)\n{\n    auto complete = synchronize(BIND2(headers_complete, _1, handler), 1, NAME);\n    protocol_timer::start(expiry_interval, BIND2(handle_event, _1, complete));\n\n    SUBSCRIBE3(headers, handle_receive, _1, _2, complete);\n\n    log::trace(LOG_NODE) << \"begin to sync header\";\n    // This is the end of the start sequence.\n    send_get_headers(complete);\n}\n\n// Header sync sequence.\n// ----------------------------------------------------------------------------\n\nvoid protocol_header_sync::send_get_headers(event_handler complete)\n{\n    if (stopped())\n        return;\n\n    const get_headers request{\n        {hashes_.last_hash()},\n        last_.hash()};\n    log::trace(LOG_NODE) << \"send get headers, [\" << encode_hash(hashes_.last_hash()) << \"], stop hash[\" << encode_hash(last_.hash()) << ']';\n    SEND2(request, handle_send, _1, complete);\n}\n\nvoid protocol_header_sync::handle_send(const code &ec, event_handler complete)\n{\n    if (stopped())\n        return;\n\n    if (ec)\n    {\n        log::trace(LOG_NODE)\n            << \"Failure sending get headers to sync [\" << authority() << \"] \"\n            << ec.message();\n        complete(ec);\n    }\n}\n\nbool protocol_header_sync::handle_receive(const code &ec, headers_ptr message,\n                                          event_handler complete)\n{\n    if (stopped())\n        return false;\n\n    if (ec)\n    {\n        log::trace(LOG_NODE)\n            << \"Failure receiving headers from sync [\"\n            << authority() << \"] \" << ec.message();\n        complete(ec);\n        return false;\n    }\n\n    // A merge failure includes automatic rollback to last trust point.\n    if (!hashes_.enqueue(message))\n    {\n        log::warning(LOG_NODE)\n            << \"Failure merging headers from [\" << authority() << \"]\";\n        complete(error::previous_block_invalid);\n        return false;\n    }\n\n    const auto next = next_height();\n\n    log::info(LOG_NODE)\n        << \"Synced headers \" << next - message->elements.size()\n        << \"-\" << (next - 1) << \" from [\" << authority() << \"]\";\n\n    // If we completed the last height the sync is complete/success.\n    if (next > last_.height())\n    {\n        log::trace(LOG_NODE) << \"protocol header sync handle receive complete\";\n        complete(error::success);\n        return false;\n    }\n\n    // If we received fewer than 2000 the peer is exhausted, try another.\n    if (message->elements.size() < max_header_response)\n    {\n        log::trace(LOG_NODE) << \"protocol header sync handle receive message size < max header response\";\n        complete(error::operation_failed);\n        return false;\n    }\n\n    // This peer has more headers.\n    send_get_headers(complete);\n    return true;\n}\n\n// This is fired by the base timer and stop handler.\nvoid protocol_header_sync::handle_event(const code &ec, event_handler complete)\n{\n    if (ec == (code)error::channel_stopped)\n    {\n        complete(ec);\n        return;\n    }\n\n    if (ec && ec != (code)error::channel_timeout)\n    {\n        log::warning(LOG_NODE)\n            << \"Failure in header sync timer for [\" << authority() << \"] \"\n            << ec.message();\n        complete(ec);\n        return;\n    }\n\n    // It was a timeout, so ten more seconds have passed.\n    current_second_ += expiry_interval.count();\n\n    // Drop the channel if it falls below the min sync rate averaged over all.\n    if (sync_rate() < minimum_rate_)\n    {\n        log::trace(LOG_NODE)\n            << \"Header sync rate (\" << sync_rate() << \"/sec) from [\"\n            << authority() << \"]\";\n        complete(error::channel_timeout);\n        return;\n    }\n}\n\nvoid protocol_header_sync::headers_complete(const code &ec,\n                                            event_handler handler)\n{\n\n    // This is end of the header sync sequence.\n    handler(ec);\n\n    // The session does not need to handle the stop.\n    stop(error::channel_stopped);\n}\n\n} // namespace node\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/node/protocols/protocol_miner.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/node/protocols/protocol_miner.hpp>\n\n#define NAME \"miner\"\n#define CLASS protocol_miner\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\nprotocol_miner::protocol_miner(network::p2p &network, network::channel::ptr channel, blockchain::block_chain &blockchain\n                               /*, blockchain::tx_pool& pool*/)\n    : protocol_events{network, channel, NAME},\n      blockchain_{blockchain},\n      /*pool_{pool},*/\n      CONSTRUCT_TRACK(protocol_miner)\n{\n}\n\nvoid protocol_miner::start()\n{\n    using namespace std::placeholders;\n    protocol_events::start(BIND1(handle_stop, _1));\n    //    pool_.subscribe_transaction(BIND3(handle_accept_transaction, _1, _2, _3));\n}\n\nvoid protocol_miner::handle_stop(const code &ec)\n{\n    log::trace(LOG_NODE) << \"protocol miner handle stop,\" << ec.message();\n}\n\n/*\nbool protocol_miner::handle_accept_transaction(const code&, const indexes&, transaction_ptr)\n{\n    return true;\n}\n*/\n\n} // namespace node\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/node/protocols/protocol_tx_in.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/node/protocols/protocol_tx_in.hpp>\n\n#include <cstddef>\n#include <functional>\n#include <memory>\n#include <UChain/network.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\n#define NAME \"transaction\"\n#define CLASS protocol_tx_in\n\nusing namespace bc::blockchain;\nusing namespace bc::message;\nusing namespace bc::network;\nusing namespace std::placeholders;\n\n// TODO: derive from protocol_session_node abstract intermediate base class.\n// TODO: Pass p2p_node on construct, obtaining node configuration settings.\nprotocol_tx_in::protocol_tx_in(p2p &network,\n                                                 channel::ptr channel, block_chain &blockchain, tx_pool &pool)\n    : protocol_events(network, channel, NAME),\n      blockchain_(blockchain),\n      pool_(pool),\n\n      // TODO: move relay to a derived class protocol_tx_in_70001.\n      relay_from_peer_(network.network_settings().relay_transactions),\n\n      // TODO: move memory_pool to a derived class protocol_tx_in_60002.\n      peer_suports_memory_pool_(peer_version().value >= version::level::bip35),\n      refresh_pool_(relay_from_peer_ && peer_suports_memory_pool_\n                    /*&& network.node_settings().tx_pool_refresh*/),\n\n      CONSTRUCT_TRACK(protocol_tx_in)\n{\n}\n\nprotocol_tx_in::ptr protocol_tx_in::do_subscribe()\n{\n    SUBSCRIBE2(inventory, handle_receive_inventory, _1, _2);\n    SUBSCRIBE2(tx_message, handle_receive_transaction, _1, _2);\n    protocol_events::start(BIND1(handle_stop, _1));\n    return std::dynamic_pointer_cast<protocol_tx_in>(protocol::shared_from_this());\n}\n\n// Start.\n//-----------------------------------------------------------------------------\n\nvoid protocol_tx_in::start()\n{\n\n    // TODO: move memory_pool to a derived class protocol_tx_in_70002.\n    // Prior to this level the mempool message is not available.\n    if (refresh_pool_)\n    {\n        log::trace(LOG_NODE) << \"protocol transaction in refresh pool\";\n        // Refresh transaction pool on connect.\n        SEND2(memory_pool(), handle_send, _1, memory_pool::command);\n\n        // Refresh transaction pool on blockchain reorganization.\n        blockchain_.subscribe_reorganize(\n            BIND4(handle_reorganized, _1, _2, _3, _4));\n        if (channel_stopped())\n        {\n            blockchain_.fired();\n        }\n    }\n}\n\n// Receive inventory sequemessagence.\n//-----------------------------------------------------------------------------\n\nbool protocol_tx_in::handle_receive_inventory(const code &ec,\n                                                       inventory_ptr message)\n{\n    if (stopped())\n        return false;\n\n    if (ec)\n    {\n        log::trace(LOG_NODE)\n            << \"Failure getting inventory from [\" << authority() << \"] \"\n            << ec.message();\n        stop(ec);\n        return false;\n    }\n\n    const auto response = std::make_shared<get_data>();\n    message->reduce(response->inventories, inventory::type_id::transaction);\n\n    // TODO: move relay to a derived class protocol_tx_in_70001.\n    // Prior to this level transaction relay is not configurable.\n    if (!relay_from_peer_ && !response->inventories.empty())\n    {\n        //        log::trace(LOG_NODE)\n        //            << \"Unexpected transaction inventory from [\" << authority() << \"]\";\n        //        return ! misbehaving(20);\n        stop(error::not_found);\n        return false;\n    }\n\n    auto hash = message->inventories.empty() ? \"\" : encode_hash(message->inventories[0].hash);\n    log::trace(LOG_NODE) << \"protocol_tx_in::handle_receive_inventory pool filter,\" << hash;\n    // This is returned on a new thread.\n    // Remove matching transaction hashes found in the transaction pool.\n    pool_.filter(response, BIND2(handle_filter_floaters, _1, response));\n    return true;\n}\n\nvoid protocol_tx_in::handle_filter_floaters(const code &ec,\n                                                     get_data_ptr message)\n{\n    if (stopped() || ec == (code)error::service_stopped ||\n        message->inventories.empty())\n        return;\n\n    if (ec)\n    {\n        log::error(LOG_NODE)\n            << \"Internal failure locating pool transaction pool hashes for [\"\n            << authority() << \"] \" << ec.message();\n        stop(ec);\n        return;\n    }\n\n    // BUGBUG: this removes spent transactions which it should not (see BIP30).\n    blockchain_.filter_transactions(message,\n                                    BIND2(send_get_data, _1, message));\n}\n\nvoid protocol_tx_in::send_get_data(const code &ec,\n                                            get_data_ptr message)\n{\n    if (stopped() || ec == (code)error::service_stopped ||\n        message->inventories.empty())\n        return;\n\n    if (ec)\n    {\n        log::error(LOG_NODE)\n            << \"Internal failure locating confirmed transaction hashes for [\"\n            << authority() << \"] \" << ec.message();\n        stop(ec);\n        return;\n    }\n    log::trace(LOG_NODE) << \"protocol_tx_in::send_get_data\";\n    // inventory->get_data[transaction]\n    SEND2(*message, handle_send, _1, message->command);\n}\n\n// Receive transaction sequence.\n//-----------------------------------------------------------------------------\n\nbool protocol_tx_in::handle_receive_transaction(const code &ec,\n                                                         transaction_ptr message)\n{\n    if (stopped())\n        return false;\n\n    if (ec)\n    {\n        log::trace(LOG_NODE)\n            << \"Failure getting transaction from [\" << authority() << \"] \"\n            << ec.message();\n        stop(ec);\n        return false;\n    }\n\n    // TODO: move relay to a derived class protocol_tx_in_70001.\n    // Prior to this level transaction relay is not configurable.\n    if (!relay_from_peer_)\n    {\n        log::trace(LOG_NODE)\n            << \"Unexpected transaction relay from [\" << authority() << \"]\";\n        stop(error::channel_stopped);\n        return false;\n    }\n\n    log::debug(LOG_NODE)\n        << \"Potential transaction from [\" << authority() << \"].\" << encode_hash(message->hash());\n\n    pool_.store(message,\n                BIND2(handle_store_confirmed, _1, _2),\n                BIND3(handle_store_validated, _1, _2, _3));\n    return true;\n}\n\n// The transaction has been saved to the memory pool (or not).\n// This will be picked up by subscription in transaction_out and will cause\n// the transaction to be announced to non-originating relay-accepting peers.\nvoid protocol_tx_in::handle_store_validated(const code &ec,\n                                                     transaction_ptr message, const index_list &unconfirmed)\n{\n    // Examples:\n    // error::service_stopped\n    // error::input_not_found\n    // error::validate_inputs_failed\n    // error::duplicate\n    // error::success (transaction is valid and indexed into the mempool)\n}\n\n// The transaction has been confirmed in a block.\nvoid protocol_tx_in::handle_store_confirmed(const code &ec,\n                                                     transaction_ptr message)\n{\n    // Examples:\n    // error::service_stopped\n    // error::pool_filled\n    // error::double_spend\n    // error::blockchain_reorganized\n    // error::success (tx was found in a block and removed from the mempool)\n}\n\n// Subscription.\n//-----------------------------------------------------------------------------\n\n// TODO: move memory_pool to a derived class protocol_tx_in_70002.\n// Prior to this level the mempool message is not available.\nbool protocol_tx_in::handle_reorganized(const code &ec, size_t,\n                                                 const block_ptr_list &, const block_ptr_list &outgoing)\n{\n    if (stopped() || ec == (code)error::service_stopped)\n        return false;\n\n    if (ec == (code)error::mock)\n    {\n        return true;\n    }\n\n    if (ec)\n    {\n        log::error(LOG_NODE)\n            << \"Internal failure handling reorganization for [\"\n            << authority() << \"] \" << ec.message();\n        stop(ec);\n        return false;\n    }\n\n    // If there are no outgoing blocks then the memory pool is intact.\n    if (outgoing.empty())\n        return true;\n\n    SEND2(memory_pool(), handle_send, _1, memory_pool::command);\n    return true;\n}\n\n// Stop.\n//-----------------------------------------------------------------------------\n\nvoid protocol_tx_in::handle_stop(const code &)\n{\n    log::trace(LOG_NETWORK)\n        << \"Stopped transaction_in protocol\";\n    blockchain_.fired();\n}\n\n} // namespace node\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/node/protocols/protocol_tx_out.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/node/protocols/protocol_tx_out.hpp>\n\n#include <cstddef>\n#include <functional>\n#include <memory>\n#include <UChain/network.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\n#define NAME \"transaction\"\n#define CLASS protocol_tx_out\n\nusing namespace bc::blockchain;\nusing namespace bc::message;\nusing namespace bc::network;\nusing namespace std::placeholders;\n\nprotocol_tx_out::protocol_tx_out(p2p &network,\n                                                   channel::ptr channel, block_chain &blockchain, tx_pool &pool)\n    : protocol_events(network, channel, NAME),\n      blockchain_(blockchain),\n      pool_(pool),\n\n      // TODO: move fee filter to a derived class protocol_tx_out_70013.\n      minimum_fee_(0),\n\n      // TODO: move relay to a derived class protocol_tx_out_70001.\n      relay_to_peer_(peer_version().relay),\n      CONSTRUCT_TRACK(protocol_tx_out)\n{\n}\n\nprotocol_tx_out::ptr protocol_tx_out::do_subscribe()\n{\n    SUBSCRIBE2(memory_pool, handle_receive_memory_pool, _1, _2);\n    SUBSCRIBE2(fee_filter, handle_receive_fee_filter, _1, _2);\n    SUBSCRIBE2(get_data, handle_receive_get_data, _1, _2);\n    protocol_events::start(BIND1(handle_stop, _1));\n    return std::dynamic_pointer_cast<protocol_tx_out>(protocol::shared_from_this());\n}\n\n// TODO: move not_found to derived class protocol_tx_out_70001.\n\n// Start.\n//-----------------------------------------------------------------------------\n\nvoid protocol_tx_out::start()\n{\n    // TODO: move relay to a derived class protocol_tx_out_70001.\n    // Prior to this level transaction relay is not configurable.\n    if (relay_to_peer_)\n    {\n        // Subscribe to transaction pool notifications and relay txs.\n        pool_.subscribe_transaction(BIND3(handle_floated, _1, _2, _3));\n        if (channel_stopped())\n        {\n            pool_.fired();\n        }\n    }\n\n    // TODO: move fee filter to a derived class protocol_tx_out_70013.\n    // Filter announcements by fee if set.\n}\n\n// Receive send_headers.\n//-----------------------------------------------------------------------------\n\n// TODO: move fee_filters to a derived class protocol_tx_out_70013.\nbool protocol_tx_out::handle_receive_fee_filter(const code &ec,\n                                                         fee_filter_ptr message)\n{\n    if (stopped())\n        return false;\n\n    if (ec)\n    {\n        log::trace(LOG_NODE)\n            << \"Failure getting \" << message->command << \" from [\"\n            << authority() << \"] \" << ec.message();\n        stop(ec);\n        return false;\n    }\n\n    // TODO: move fee filter to a derived class protocol_tx_out_70013.\n    // Transaction annoucements will be filtered by fee amount.\n    minimum_fee_.store(message->minimum_fee);\n\n    // The fee filter may be adjusted.\n    return true;\n}\n\n// Receive mempool sequence.\n//-----------------------------------------------------------------------------\n\nbool protocol_tx_out::handle_receive_memory_pool(const code &ec,\n                                                          memory_pool_ptr)\n{\n    if (stopped())\n    {\n        return false;\n    }\n\n    if (ec)\n    {\n        return false;\n    }\n\n    auto self = shared_from_this();\n    pool_.fetch([this, self](const code &ec, const std::vector<transaction_ptr> &txs) {\n        if (stopped() || ec)\n        {\n            log::debug(LOG_NODE) << \"pool fetch transaction failed,\" << ec.message();\n            return;\n        }\n\n        if (txs.empty())\n        {\n            return;\n        }\n        std::vector<hash_digest> hashes;\n        hashes.reserve(txs.size());\n        for (auto &t : txs)\n        {\n            hashes.push_back(t->hash());\n        }\n        send<protocol_tx_out>(inventory{hashes, inventory::type_id::transaction}, &protocol_tx_out::handle_send, _1, inventory::command);\n    });\n    return false;\n}\n\n// Receive get_data sequence.\n//-----------------------------------------------------------------------------\n\nbool protocol_tx_out::handle_receive_get_data(const code &ec,\n                                                       get_data_ptr message)\n{\n    if (stopped())\n        return false;\n\n    if (ec)\n    {\n        log::trace(LOG_NODE)\n            << \"Failure getting inventory from [\" << authority() << \"] \"\n            << ec.message();\n        stop(ec);\n        return false;\n    }\n\n    //    if (message->inventories.size() > 50000)\n    //    {\n    //        return ! misbehaving(20);\n    //    }\n\n    // TODO: these must return message objects or be copied!\n    // Ignore non-transaction inventory requests in this protocol.\n    for (const auto &inv : message->inventories)\n        if (inv.type == inventory::type_id::transaction)\n        {\n            auto pThis = shared_from_this();\n            pool_.fetch(inv.hash, [this, &inv, pThis](const code &ec, transaction_ptr tx) {\n                auto t = tx ? *tx : chain::transaction{};\n                send_transaction(ec, t, inv.hash);\n                if (ec)\n                {\n                    blockchain_.fetch_transaction(inv.hash,\n                                                  BIND3(send_transaction, _1, _2, inv.hash));\n                }\n            });\n        }\n\n    return true;\n}\n\nvoid protocol_tx_out::send_transaction(const code &ec,\n                                                const chain::transaction &transaction, const hash_digest &hash)\n{\n    if (stopped() || ec == (code)error::service_stopped)\n        return;\n\n    if (ec == (code)error::not_found)\n    {\n        log::trace(LOG_NODE)\n            << \"Transaction requested by [\" << authority() << \"] not found.\";\n\n        //        const not_found reply{ { inventory::type_id::transaction, hash } };\n        //        SEND2(reply, handle_send, _1, reply.command);\n        return;\n    }\n\n    if (ec)\n    {\n        log::error(LOG_NODE)\n            << \"Internal failure locating trnsaction requested by [\"\n            << authority() << \"] \" << ec.message();\n        stop(ec);\n        return;\n    }\n\n    log::trace(LOG_NODE) << \"send transaction \" << encode_hash(transaction.hash()) << \", to \" << authority();\n\n    // TODO: eliminate copy.\n    SEND2(tx_message(transaction), handle_send, _1,\n          tx_message::command);\n}\n\n// Subscription.\n//-----------------------------------------------------------------------------\n\nbool protocol_tx_out::handle_floated(const code &ec,\n                                              const index_list &unconfirmed, transaction_ptr message)\n{\n    if (stopped() || ec == (code)error::service_stopped)\n        return false;\n\n    if (ec == (code)error::mock)\n        return true;\n\n    if (ec)\n    {\n        log::error(LOG_NODE)\n            << \"Failure handling transaction float: \" << ec.message();\n        stop(ec);\n        return false;\n    }\n\n    // TODO: move fee filter to a derived class protocol_tx_out_70013.\n    // TODO: implement fee computation.\n    const uint64_t fee = 0;\n\n    // Transactions are discovered and announced individually.\n    if (message->originator() != nonce() && fee >= minimum_fee_.load())\n    {\n        static const auto id = inventory::type_id::transaction;\n        const inventory announcement{{id, message->hash()}};\n        log::trace(LOG_NODE) << \"handle floated send transaction hash,\" << encode_hash(message->hash());\n        SEND2(announcement, handle_send, _1, announcement.command);\n    }\n\n    return true;\n}\n\nvoid protocol_tx_out::handle_stop(const code &)\n{\n    log::trace(LOG_NETWORK)\n        << \"Stopped transaction_out protocol\";\n    pool_.fired();\n}\n\n} // namespace node\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/node/protocols/protocol_version_quiet.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/node/protocols/protocol_version_quiet.hpp>\n\n#include <UChain/network.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\nusing namespace bc::network;\n\nprotocol_version_quiet::protocol_version_quiet(p2p &network,\n                                               channel::ptr channel)\n    : protocol_version(network, channel)\n{\n}\n\nvoid protocol_version_quiet::send_version(const message::version &self)\n{\n  auto version = self;\n  version.relay = false;\n  protocol_version::send_version(version);\n}\n\n} // namespace node\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/node/sessions/session_block_sync.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/node/sessions/session_block_sync.hpp>\n\n#include <cstddef>\n#include <memory>\n#include <UChain/blockchain.hpp>\n#include <UChain/network.hpp>\n#include <UChain/node/define.hpp>\n#include <UChain/node/protocols/protocol_block_sync.hpp>\n#include <UChain/node/protocols/protocol_version_quiet.hpp>\n#include <UChain/node/settings.hpp>\n#include <UChain/node/utility/header_queue.hpp>\n#include <UChain/node/utility/reservation.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\n#define CLASS session_block_sync\n#define NAME \"session_block_sync\"\n\nusing namespace blockchain;\nusing namespace config;\nusing namespace network;\nusing namespace std::placeholders;\n\n// The interval in which all-channel block download performance is tested.\nstatic const asio::seconds regulator_interval(5);\n\nsession_block_sync::session_block_sync(p2p &network, header_queue &hashes,\n                                       simple_chain &chain, const settings &settings)\n    : session_batch(network, false),\n      blockchain_(chain),\n      reservations_count_{0},\n      settings_(settings),\n      reservations_(hashes, chain, settings),\n      CONSTRUCT_TRACK(session_block_sync)\n{\n}\n\n// Start sequence.\n// ----------------------------------------------------------------------------\n\nvoid session_block_sync::start(result_handler handler)\n{\n    // TODO: create session_timer base class and pass interval via start.\n    timer_ = std::make_shared<deadline>(pool_, regulator_interval);\n    session::start(CONCURRENT2(handle_started, _1, handler));\n}\n\nvoid session_block_sync::handle_started(const code &ec, result_handler handler)\n{\n    if (ec)\n    {\n        handler(ec);\n        return;\n    }\n\n    // Copy the reservations table.\n    const auto table = reservations_.table();\n\n    if (table.empty())\n    {\n        handler(error::success);\n        return;\n    }\n\n    // TODO: expose valid block count from reservations and emit here.\n    log::info(LOG_NODE)\n        << \"Getting blocks.\";\n    const auto connector = create_connector();\n    reservations_count_ = table.size();\n    const auto complete = synchronize(handler, table.size(), NAME);\n    std::function<void(const code &)> func = complete;\n    // This is the end of the start sequence.\n    for (const auto row : table)\n        new_connection(connector, row, [func](const code &ec) {\n            func(ec);\n        });\n    log::info(LOG_NODE)\n        << \"table size,\" << table.size();\n\n    ////reset_timer(connector);\n}\n\n// Block sync sequence.\n// ----------------------------------------------------------------------------\n\nvoid session_block_sync::new_connection(connector::ptr connect,\n                                        reservation::ptr row, result_handler handler)\n{\n    if (stopped())\n    {\n        log::debug(LOG_NODE)\n            << \"Suspending slot (\" << row->slot() << \").\";\n        return;\n    }\n\n    log::debug(LOG_NODE)\n        << \"Starting slot (\" << row->slot() << \").\";\n\n    // BLOCK SYNC CONNECT\n    this->connect(connect,\n                  BIND5(handle_connect, _1, _2, connect, row, handler));\n}\n\nvoid session_block_sync::handle_connect(const code &ec, channel::ptr channel,\n                                        connector::ptr connect, reservation::ptr row, result_handler handler)\n{\n    if (ec)\n    {\n        log::debug(LOG_NODE)\n            << \"Failure connecting slot (\" << row->slot() << \") \"\n            << ec.message();\n        if (ec.value() == error::not_satisfied)\n        {\n            log::debug(LOG_NETWORK) << \"session block sync handle connect, not satified\";\n            handle_complete(ec, channel, connect, row, handler);\n            return;\n        }\n        new_connection(connect, row, handler);\n        return;\n    }\n\n    log::debug(LOG_NODE)\n        << \"Connected slot (\" << row->slot() << \") [\"\n        << channel->authority() << \"]\";\n\n    register_channel(channel,\n                     BIND5(handle_channel_start, _1, channel, connect, row, handler),\n                     BIND4(handle_channel_stop, _1, connect, row, handler));\n}\n\nvoid session_block_sync::attach_handshake_protocols(channel::ptr channel,\n                                                    result_handler handle_started)\n{\n    attach<protocol_version_quiet>(channel)->start(handle_started);\n}\n\nvoid session_block_sync::handle_channel_start(const code &ec,\n                                              channel::ptr channel, connector::ptr connect, reservation::ptr row,\n                                              result_handler handler)\n{\n    // Treat a start failure just like a completion failure.\n    if (ec)\n    {\n        handle_complete(ec, channel, connect, row, handler);\n        return;\n    }\n\n    attach_protocols(channel, connect, row, handler);\n}\n\nvoid session_block_sync::attach_protocols(channel::ptr channel,\n                                          connector::ptr connect, reservation::ptr row, result_handler handler)\n{\n    attach<protocol_ping>(channel)->start();\n    attach<protocol_address>(channel)->start();\n    attach<protocol_block_sync>(channel, row)->start(BIND5(handle_complete, _1, channel, connect, row, handler));\n}\n\nvoid session_block_sync::handle_complete(const code &ec, channel::ptr channel,\n                                         network::connector::ptr connect, reservation::ptr row,\n                                         result_handler handler)\n{\n    if (!ec)\n    {\n        timer_->stop();\n        scoped_lock lock{mutex_};\n        --reservations_count_;\n        reservations_.remove(row);\n        log::debug(LOG_NODE)\n            << \"Completed slot (\" << row->slot() << \")\"\n            << \",resd size,\" << reservations_.size();\n        // This is the end of the block sync sequence.\n        handler(ec);\n\n        return;\n    }\n\n    if (ec.value() == error::not_satisfied)\n    {\n        scoped_lock lock{mutex_};\n        if (reservations_count_ != 1)\n        {\n            --reservations_count_;\n            handler(error::success);\n            return;\n        }\n    }\n\n    // There is no failure scenario, we ignore the result code here.\n    new_connection(connect, row, handler);\n}\n\nvoid session_block_sync::handle_channel_stop(const code &ec,\n                                             network::connector::ptr connect, reservation::ptr row, result_handler handler)\n{\n    log::info(LOG_NODE)\n        << \"Channel stopped on slot (\" << row->slot() << \") \" << ec.message();\n}\n\n// Timer.\n// ----------------------------------------------------------------------------\n\n// private:\nvoid session_block_sync::reset_timer(connector::ptr connect)\n{\n    if (stopped())\n        return;\n\n    timer_->start(BIND2(handle_timer, _1, connect));\n}\n\nvoid session_block_sync::handle_timer(const code &ec, connector::ptr connect)\n{\n    if (stopped())\n        return;\n\n    log::debug(LOG_NODE)\n        << \"Fired session_block_sync timer: \" << ec.message();\n\n    ////// TODO: If (total database time as a fn of total time) add a channel.\n    ////// TODO: push into reservations_ implementation.\n    ////// TODO: add a boolean increment method to the synchronizer and pass here.\n    ////const size_t id = reservations_.table().size();\n    ////const auto row = std::make_shared<reservation>(reservations_, id);\n    ////const synchronizer<result_handler> handler({}, 0, \"name\", true);\n\n    ////if (add) new_connection(connect, row, handler);\n\n    ////// TODO: drop the slowest channel\n    //////If (drop) reservations_.prune();\n\n    reset_timer(connect);\n}\n\n} // namespace node\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/node/sessions/session_header_sync.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/node/sessions/session_header_sync.hpp>\n\n#include <algorithm>\n#include <cstddef>\n#include <cstdint>\n#include <memory>\n#include <utility>\n#include <UChain/blockchain.hpp>\n#include <UChain/network.hpp>\n#include <UChain/node/define.hpp>\n#include <UChain/node/protocols/protocol_header_sync.hpp>\n#include <UChain/node/protocols/protocol_version_quiet.hpp>\n#include <UChain/node/settings.hpp>\n#include <UChain/node/utility/header_queue.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\n#define CLASS session_header_sync\n\nusing namespace bc::blockchain;\nusing namespace bc::chain;\nusing namespace bc::config;\nusing namespace bc::network;\nusing namespace std::placeholders;\n\n// The minimum rate back off factor, must be < 1.0.\nstatic constexpr float back_off_factor = 0.75f;\n\n// The starting minimum header download rate, exponentially backs off.\nstatic constexpr uint32_t headers_per_second = 10000;\n\n// Sort is required here but not in configuration settings.\nsession_header_sync::session_header_sync(p2p &network, header_queue &hashes,\n                                         simple_chain &blockchain, const checkpoint::list &checkpoints)\n    : session_batch(network, false),\n      hashes_(hashes),\n      minimum_rate_(headers_per_second),\n      blockchain_(blockchain),\n      checkpoints_(checkpoint::sort(checkpoints)),\n      try_count_{0},\n      synced_{false},\n      CONSTRUCT_TRACK(session_header_sync)\n{\n    static_assert(back_off_factor < 1.0, \"invalid back-off factor\");\n}\n\n// Start sequence.\n// ----------------------------------------------------------------------------\n\nvoid session_header_sync::start(result_handler handler)\n{\n    session::start(CONCURRENT2(handle_started, _1, handler));\n}\n\nvoid session_header_sync::handle_started(const code &ec,\n                                         result_handler handler)\n{\n    if (ec)\n    {\n        handler(ec);\n        return;\n    }\n\n    if (!initialize(handler))\n        return;\n\n    // This is the end of the start sequence.\n    new_connection(create_connector(), handler);\n}\n\n// Header sync sequence.\n// ----------------------------------------------------------------------------\n\nvoid session_header_sync::new_connection(connector::ptr connect,\n                                         result_handler handler)\n{\n    if (stopped())\n    {\n        log::debug(LOG_NODE)\n            << \"Suspending header sync session.\";\n        return;\n    }\n\n    // HEADER SYNC CONNECT\n    this->connect(connect, BIND4(handle_connect, _1, _2, connect, handler));\n}\n\nvoid session_header_sync::handle_connect(const code &ec, channel::ptr channel,\n                                         connector::ptr connect, result_handler handler)\n{\n    if (ec)\n    {\n        log::debug(LOG_NODE)\n            << \"Failure connecting header sync channel: \" << ec.message();\n        if (ec.value() == error::not_satisfied)\n        {\n            log::debug(LOG_NETWORK) << \"session header sync handle connect, not satified\";\n            handler(ec);\n            return;\n        }\n        handle_channel_stop(ec, connect, handler);\n        return;\n    }\n\n    log::debug(LOG_NODE)\n        << \"Connected to header sync channel [\" << channel->authority() << \"]\";\n\n    register_channel(channel,\n                     BIND4(handle_channel_start, _1, connect, channel, handler),\n                     BIND3(handle_channel_stop, _1, connect, handler));\n}\n\nvoid session_header_sync::attach_handshake_protocols(channel::ptr channel,\n                                                     result_handler handle_started)\n{\n    attach<protocol_version_quiet>(channel)->start(handle_started);\n}\n\nvoid session_header_sync::handle_channel_start(const code &ec,\n                                               connector::ptr connect, channel::ptr channel, result_handler handler)\n{\n    // Treat a start failure just like a completion failure.\n    if (ec)\n    {\n        handle_complete(ec, channel, connect, handler);\n        return;\n    }\n    try_count_.store(0);\n    attach_protocols(channel, connect, handler);\n}\n\nvoid session_header_sync::attach_protocols(channel::ptr channel,\n                                           connector::ptr connect, result_handler handler)\n{\n    attach<protocol_ping>(channel)->start();\n    attach<protocol_address>(channel)->start();\n    attach<protocol_header_sync>(channel, hashes_, minimum_rate_, last_)\n        ->start(BIND4(handle_complete, _1, channel, connect, handler));\n}\n\nvoid session_header_sync::handle_complete(const code &ec, channel::ptr channel,\n                                          network::connector::ptr connect, result_handler handler)\n{\n    channel->stop(error::channel_stopped);\n    if (!ec)\n    {\n        synced_.store(true);\n        log::debug(LOG_NODE)\n            << \"header sync handle complete successfully,\" << ec.message();\n        // This is the end of the header sync sequence.\n        handler(ec);\n        return;\n    }\n\n    // Reduce the rate minimum so that we don't get hung up.\n    minimum_rate_ = static_cast<uint32_t>(minimum_rate_ * back_off_factor);\n\n    log::debug(LOG_NODE)\n        << \"handle complete failed,\" << ec.message();\n\n    //    // There is no failure scenario, we ignore the result code here.\n    //    new_connection(connect, handler);\n}\n\nvoid session_header_sync::handle_channel_stop(const code &ec, network::connector::ptr connect, result_handler handler)\n{\n    log::debug(LOG_NODE)\n        << \"Header sync channel stopped: \" << ec.message();\n    if (!synced_)\n    {\n        ++try_count_;\n        if (try_count_ == 10)\n        {\n            log::info(LOG_NETWORK) << \"session header sync handle connect try count reach 10\";\n            handler(error::network_unreachable);\n            return;\n        }\n        new_connection(connect, handler);\n    }\n}\n\n// Utility.\n// ----------------------------------------------------------------------------\n\nbool session_header_sync::initialize(result_handler handler)\n{\n    if (!hashes_.empty())\n    {\n        log::error(LOG_NODE)\n            << \"Header hash list must not be initialized.\";\n        handler(error::operation_failed);\n        return false;\n    }\n\n    checkpoint seed;\n    const auto ec = get_range(seed, last_);\n\n    if (ec)\n    {\n        log::error(LOG_NODE)\n            << \"Error getting header sync range: \" << ec.message();\n        handler(ec);\n        return false;\n    }\n\n    if (seed == last_)\n    {\n        handler(error::success);\n        return false;\n    }\n\n    // The stop is either a block or a checkpoint, so it may be downloaded.\n    const auto stop_height = last_.height();\n\n    // The seed is a block that we already have, so it will not be downloaded.\n    const auto first_height = seed.height() + 1;\n\n    log::info(LOG_NODE)\n        << \"Getting headers \" << first_height << \"-\" << stop_height << \".\";\n\n    hashes_.initialize(seed);\n    return true;\n}\n\n// Get the block hashes that bracket the range to download.\ncode session_header_sync::get_range(checkpoint &out_seed, checkpoint &out_stop)\n{\n    uint64_t last_height;\n\n    if (!blockchain_.get_last_height(last_height))\n        return error::operation_failed;\n\n    uint64_t last_gap;\n    uint64_t first_gap;\n    auto first_height = last_height;\n\n    if (blockchain_.get_gap_range(first_gap, last_gap))\n    {\n        last_height = last_gap + 1;\n        first_height = first_gap - 1;\n    }\n\n    header first_header;\n\n    if (!blockchain_.get_header(first_header, first_height))\n        return error::not_found;\n\n    if (!checkpoints_.empty() && checkpoints_.back().height() > last_height)\n    {\n        out_stop = checkpoints_.back();\n    }\n    else if (first_height == last_height)\n    {\n        out_stop = std::move(checkpoint{first_header.hash(), first_height});\n    }\n    else\n    {\n        header last_header;\n\n        if (!blockchain_.get_header(last_header, last_height))\n            return error::not_found;\n\n        out_stop = std::move(checkpoint{last_header.hash(), last_height});\n    }\n\n    out_seed = std::move(checkpoint{first_header.hash(), first_height});\n    return error::success;\n}\n\n} // namespace node\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/node/sessions/session_inbound.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/node/sessions/session_inbound.hpp>\n\n#include <UChain/blockchain.hpp>\n#include <UChain/network.hpp>\n#include <UChain/node/protocols/protocol_block_in.hpp>\n#include <UChain/node/protocols/protocol_block_out.hpp>\n#include <UChain/node/protocols/protocol_tx_in.hpp>\n#include <UChain/node/protocols/protocol_tx_out.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\nusing namespace bc::blockchain;\nusing namespace bc::network;\nusing namespace std::placeholders;\n\nsession_inbound::session_inbound(p2p &network, block_chain &blockchain,\n                                 tx_pool &pool)\n    : network::session_inbound(network),\n      blockchain_(blockchain),\n      pool_(pool)\n{\n    log::info(LOG_NODE)\n        << \"Starting inbound session.\";\n}\n\nvoid session_inbound::attach_handshake_protocols(channel::ptr channel,\n                                                 result_handler handle_started)\n{\n    auto self = shared_from_this();\n    attach<protocol_version>(channel)->start([channel, handle_started, this, self](const code &ec) {\n        if (!ec)\n        {\n            auto pt_ping = attach<protocol_ping>(channel);\n            auto pt_address = attach<protocol_address>(channel);\n            auto pt_block_in = attach<protocol_block_in>(channel, blockchain_);\n            auto pt_block_out = attach<protocol_block_out>(channel, blockchain_);\n            auto pt_tx_in = attach<protocol_tx_in>(channel, blockchain_, pool_);\n            auto pt_tx_out = attach<protocol_tx_out>(channel, blockchain_, pool_);\n\n            pt_ping->do_subscribe();\n            pt_address->do_subscribe();\n            pt_block_in->do_subscribe();\n            pt_block_out->do_subscribe();\n            pt_tx_in->do_subscribe();\n            pt_tx_out->do_subscribe();\n\n            channel->set_protocol_start_handler([pt_ping, pt_address, pt_block_in, pt_block_out, pt_tx_in, pt_tx_out]() {\n                pt_ping->start();\n                pt_address->start();\n                pt_block_in->start();\n                pt_block_out->start();\n                pt_tx_in->start();\n                pt_tx_out->start();\n            });\n        }\n\n        if (stopped() || ec)\n        {\n            channel->invoke_protocol_start_handler(error::channel_stopped);\n        }\n        handle_started(ec);\n    });\n}\n\nvoid session_inbound::attach_protocols(channel::ptr channel)\n{\n    channel->invoke_protocol_start_handler(error::success);\n}\n\n} // namespace node\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/node/sessions/session_manual.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/node/sessions/session_manual.hpp>\n\n#include <UChain/blockchain.hpp>\n#include <UChain/network.hpp>\n#include <UChain/node/protocols/protocol_block_in.hpp>\n#include <UChain/node/protocols/protocol_block_out.hpp>\n#include <UChain/node/protocols/protocol_tx_in.hpp>\n#include <UChain/node/protocols/protocol_tx_out.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\nusing namespace bc::blockchain;\nusing namespace bc::network;\nusing namespace std::placeholders;\n\nsession_manual::session_manual(p2p &network, block_chain &blockchain,\n                               tx_pool &pool)\n    : network::session_manual(network),\n      blockchain_(blockchain),\n      pool_(pool)\n{\n    log::info(LOG_NODE)\n        << \"Starting manual session.\";\n}\n\nvoid session_manual::attach_handshake_protocols(channel::ptr channel,\n                                                result_handler handle_started)\n{\n    auto self = shared_from_this();\n    attach<protocol_version>(channel)->start([channel, handle_started, this, self](const code &ec) {\n        if (!ec)\n        {\n            auto pt_ping = attach<protocol_ping>(channel)->do_subscribe();\n            auto pt_address = attach<protocol_address>(channel)->do_subscribe();\n            auto pt_block_in = attach<protocol_block_in>(channel, blockchain_)->do_subscribe();\n            auto pt_block_out = attach<protocol_block_out>(channel, blockchain_)->do_subscribe();\n            auto pt_tx_in = attach<protocol_tx_in>(channel, blockchain_, pool_)->do_subscribe();\n            auto pt_tx_out = attach<protocol_tx_out>(channel, blockchain_, pool_)->do_subscribe();\n            channel->set_protocol_start_handler([pt_ping, pt_address, pt_block_in, pt_block_out, pt_tx_in, pt_tx_out]() {\n                pt_ping->start();\n                pt_address->start();\n                pt_block_in->start();\n                pt_block_out->start();\n                pt_tx_in->start();\n                pt_tx_out->start();\n            });\n        }\n        else\n        {\n            channel->invoke_protocol_start_handler(error::channel_stopped);\n        }\n        handle_started(ec);\n        if (stopped())\n            channel->invoke_protocol_start_handler(error::channel_stopped);\n    });\n}\n\nvoid session_manual::attach_protocols(channel::ptr channel)\n{\n    channel->invoke_protocol_start_handler(error::success);\n}\n\n} // namespace node\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/node/sessions/session_outbound.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/node/sessions/session_outbound.hpp>\n\n#include <UChain/blockchain.hpp>\n#include <UChain/network.hpp>\n#include <UChain/node/protocols/protocol_block_in.hpp>\n#include <UChain/node/protocols/protocol_block_out.hpp>\n#include <UChain/node/protocols/protocol_tx_in.hpp>\n#include <UChain/node/protocols/protocol_tx_out.hpp>\n#include <UChain/node/protocols/protocol_miner.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\nusing namespace bc::blockchain;\nusing namespace bc::network;\nusing namespace std::placeholders;\n\nsession_outbound::session_outbound(p2p &network, block_chain &blockchain,\n                                   tx_pool &pool)\n    : network::session_outbound(network),\n      blockchain_(blockchain),\n      pool_(pool)\n{\n    log::info(LOG_NODE)\n        << \"Starting outbound session.\";\n}\n\nvoid session_outbound::attach_handshake_protocols(channel::ptr channel,\n                                                  result_handler handle_started)\n{\n    auto self = shared_from_this();\n    attach<protocol_version>(channel)->start([channel, handle_started, this, self](const code &ec) {\n        if (!ec)\n        {\n            auto pt_ping = attach<protocol_ping>(channel)->do_subscribe();\n            auto pt_address = attach<protocol_address>(channel)->do_subscribe();\n            auto pt_block_in = attach<protocol_block_in>(channel, blockchain_)->do_subscribe();\n            auto pt_block_out = attach<protocol_block_out>(channel, blockchain_)->do_subscribe();\n            auto pt_tx_in = attach<protocol_tx_in>(channel, blockchain_, pool_)->do_subscribe();\n            auto pt_tx_out = attach<protocol_tx_out>(channel, blockchain_, pool_)->do_subscribe();\n            channel->set_protocol_start_handler([pt_ping, pt_address, pt_block_in, pt_block_out, pt_tx_in, pt_tx_out]() {\n                pt_ping->start();\n                pt_address->start();\n                pt_block_in->start();\n                pt_block_out->start();\n                pt_tx_in->start();\n                pt_tx_out->start();\n            });\n        }\n\n        if (stopped() || ec)\n        {\n            channel->invoke_protocol_start_handler(error::channel_stopped);\n            channel->stop(error::channel_stopped);\n        }\n\n        handle_started(ec);\n    });\n}\n\nvoid session_outbound::attach_protocols(channel::ptr channel)\n{\n    //    attach<protocol_miner>(channel, blockchain_)->start();\n    channel->invoke_protocol_start_handler(error::success);\n}\n\n} // namespace node\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/node/settings.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/node/settings.hpp>\n\n#include <thread>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\nsettings::settings()\n    : block_timeout_seconds(5),\n      download_connections(8),\n      tx_pool_refresh(true)\n{\n}\n\n// There are no current distinctions spanning chain contexts.\nsettings::settings(bc::settings context)\n    : settings()\n{\n}\n\n} // namespace node\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/node/utility/header_queue.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/node/utility/header_queue.hpp>\n\n#include <algorithm>\n#include <cstddef>\n#include <iterator>\n#include <memory>\n#include <UChain/blockchain.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\nusing namespace bc::blockchain;\nusing namespace bc::chain;\nusing namespace bc::config;\nusing namespace bc::message;\n\nheader_queue::header_queue(const config::checkpoint::list &checkpoints)\n    : height_(0),\n      head_(list_.begin()),\n      checkpoints_(checkpoints)\n{\n}\n\nbool header_queue::empty() const\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    shared_lock lock(mutex_);\n\n    return is_empty();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nsize_t header_queue::size() const\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    shared_lock lock(mutex_);\n\n    return get_size();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nsize_t header_queue::first_height() const\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    shared_lock lock(mutex_);\n\n    return height_;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nsize_t header_queue::last_height() const\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    shared_lock lock(mutex_);\n\n    return last();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nhash_digest header_queue::last_hash() const\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    shared_lock lock(mutex_);\n\n    return is_empty() ? null_hash : list_.back();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid header_queue::initialize(const checkpoint &check)\n{\n    initialize(check.hash(), check.height());\n}\n\nvoid header_queue::initialize(const hash_digest &hash, size_t height)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    mutex_.lock_upgrade();\n\n    const auto size =\n        (checkpoints_.empty() || height > checkpoints_.back().height()) ? 1 : (checkpoints_.back().height() - height + 1);\n\n    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n    mutex_.unlock_upgrade_and_lock();\n\n    list_.clear();\n    list_.reserve(size);\n    list_.emplace_back(hash);\n    head_ = list_.begin();\n    height_ = height;\n\n    mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid header_queue::invalidate(size_t first_height, size_t count)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    mutex_.lock_upgrade();\n\n    if (first_height < height_ || first_height > last())\n    {\n        mutex_.unlock_upgrade();\n        //---------------------------------------------------------------------\n        return;\n    }\n\n    const auto first = first_height - height_;\n    const auto end = std::min(first + count, get_size());\n\n    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n    mutex_.unlock_upgrade_and_lock();\n\n    for (size_t index = first; index < end; ++index)\n        list_[index] = null_hash;\n\n    mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n// static\nbool header_queue::valid(const hash_digest &hash)\n{\n    return hash != null_hash;\n}\n\nbool header_queue::dequeue(size_t count)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    mutex_.lock_upgrade();\n\n    if (count == 0)\n    {\n        mutex_.unlock_upgrade();\n        //---------------------------------------------------------------------\n        return true;\n    }\n\n    if (is_empty())\n    {\n        mutex_.unlock_upgrade();\n        //---------------------------------------------------------------------\n        return false;\n    }\n\n    const auto size = get_size();\n\n    if (count > size)\n    {\n        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n        mutex_.unlock_upgrade_and_lock();\n\n        BITCOIN_ASSERT(size <= max_size_t - height_);\n        height_ += size;\n\n        list_.clear();\n        head_ = list_.begin();\n\n        mutex_.unlock();\n        //---------------------------------------------------------------------\n        return false;\n    }\n\n    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n    mutex_.unlock_upgrade_and_lock();\n\n    BITCOIN_ASSERT(count <= max_size_t - height_);\n    height_ += count;\n\n    list_.erase(list_.begin(), head_ + count);\n    head_ = list_.begin();\n\n    mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n\n    return true;\n}\n\n// This allows the list to become emptied, which breaks the chain.\nbool header_queue::dequeue(hash_digest &out_hash, size_t &out_height)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    mutex_.lock_upgrade();\n\n    if (is_empty())\n    {\n        mutex_.unlock_upgrade();\n        //---------------------------------------------------------------------\n        return false;\n    }\n\n    out_height = height_;\n\n    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n    mutex_.unlock_upgrade_and_lock();\n\n    std::swap(out_hash, *head_);\n    ++head_;\n    ++height_;\n\n    mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n\n    return true;\n}\n\nbool header_queue::enqueue(headers::ptr message)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    mutex_.lock_upgrade();\n\n    // Cannot merge into an empty chain (must be initialized and not cleared).\n    if (is_empty())\n    {\n        mutex_.unlock_upgrade();\n        //---------------------------------------------------------------------\n        return false;\n    }\n\n    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n    mutex_.unlock_upgrade_and_lock();\n\n    const auto result = merge(message->elements);\n\n    mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n\n    return result;\n}\n\n// private\n//-----------------------------------------------------------------------------\n\n// TODO: add PoW validation to reduce importance of intermediate checkpoints.\nbool header_queue::merge(const header::list &headers)\n{\n    // If we exceed capacity the header pointer becomes invalid, so prevent.\n    const auto size = get_size();\n    list_.erase(list_.begin(), head_);\n    list_.reserve(size + headers.size());\n    head_ = list_.begin();\n\n    for (const auto &header : headers)\n    {\n        const auto &new_hash = header.hash();\n        const auto next_height = last() + 1;\n        const auto &last_hash = is_empty() ? null_hash : list_.back();\n\n        if (!linked(header, last_hash) || !check(new_hash, next_height))\n        {\n            rollback();\n            return false;\n        }\n\n        list_.emplace_back(new_hash);\n    }\n\n    return true;\n}\n\nvoid header_queue::rollback()\n{\n    if (!checkpoints_.empty())\n    {\n        for (auto it = checkpoints_.rbegin(); it != checkpoints_.rend(); ++it)\n        {\n            auto match = std::find(head_, list_.end(), it->hash());\n\n            if (match != list_.end())\n            {\n                list_.erase(++match, list_.end());\n                return;\n            }\n        }\n    }\n\n    // This assumes that if there are no checkpoints that currently match we\n    // trust only the first logical element in the list. This may not be\n    // the case depending on how the list has been initialized and/or used.\n    if (!is_empty())\n    {\n        list_.erase(head_ + 1, list_.end());\n        list_.erase(list_.begin(), head_);\n    }\n\n    head_ = list_.begin();\n}\n\nbool header_queue::check(const hash_digest &hash, size_t height) const\n{\n    return checkpoint::validate(hash, height, checkpoints_);\n}\n\nbool header_queue::linked(const chain::header &header,\n                          const hash_digest &hash) const\n{\n    return header.previous_block_hash == hash;\n}\n\nbool header_queue::is_empty() const\n{\n    return get_size() == 0;\n}\n\nsize_t header_queue::get_size() const\n{\n    hash_list::const_iterator it = head_;\n    const auto value = std::distance(it, list_.end());\n    return value;\n}\n\nsize_t header_queue::last() const\n{\n    return is_empty() ? height_ : height_ + get_size() - 1;\n}\n\n} // namespace node\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/node/utility/performance.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/node/utility/performance.hpp>\n\n#include <UChain/coin.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\ndouble performance::normal() const\n{\n    // If numerator is small we can overflow (infinity).\n    return divide<double>(events, static_cast<double>(window) - database);\n}\n\ndouble performance::total() const\n{\n    return divide<double>(events, window);\n}\n\ndouble performance::ratio() const\n{\n    return divide<double>(database, window);\n}\n\n} // namespace node\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/node/utility/reservation.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/node/utility/reservation.hpp>\n\n#include <chrono>\n#include <cmath>\n#include <cstddef>\n#include <cstdint>\n#include <utility>\n#include <boost/format.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/node/utility/performance.hpp>\n#include <UChain/node/utility/reservations.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\nusing namespace std::chrono;\nusing namespace bc::chain;\n\n// The allowed number of standard deviations below the norm.\n// With 1 channel this multiple is irrelevant, no channels are dropped.\n// With 2 channels a < 1.0 multiple will drop a channel on every test.\n// With 2 channels a 1.0 multiple will fluctuate based on rounding deviations.\n// With 2 channels a > 1.0 multiple will prevent all channel drops.\n// With 3+ channels the multiple determines allowed deviation from the norm.\nstatic constexpr float multiple = 1.01f;\n\n// The minimum amount of block history to move the state from idle.\nstatic constexpr size_t minimum_history = 3;\n\n// Simple conversion factor, since we trace in micro and report in seconds.\nstatic constexpr size_t micro_per_second = 1000 * 1000;\n\nreservation::reservation(reservations &reservations, size_t slot,\n                         uint32_t block_timeout_seconds)\n    : rate_({true, 0, 0, 0}),\n      stopped_(false),\n      pending_(true),\n      partitioned_(false),\n      reservations_(reservations),\n      slot_(slot),\n      rate_window_(minimum_history * block_timeout_seconds * micro_per_second)\n{\n}\n\nreservation::~reservation()\n{\n    // This complicates unit testing and isn't strictly necessary.\n    ////BITCOIN_ASSERT_MSG(heights_.empty(), \"The reservation is not empty.\");\n}\n\nsize_t reservation::slot() const\n{\n    return slot_;\n}\n\nbool reservation::pending() const\n{\n    return pending_;\n}\n\nvoid reservation::set_pending(bool value)\n{\n    pending_ = value;\n}\n\nstd::chrono::microseconds reservation::rate_window() const\n{\n    return rate_window_;\n}\n\nhigh_resolution_clock::time_point reservation::now() const\n{\n    return high_resolution_clock::now();\n}\n\n// Rate methods.\n//-----------------------------------------------------------------------------\n\n// Clears rate/history but leaves hashes unchanged.\nvoid reservation::reset()\n{\n    set_rate({true, 0, 0, 0});\n    clear_history();\n}\n\n// Shortcut for rate().idle call.\nbool reservation::idle() const\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    shared_lock lock(rate_mutex_);\n\n    return rate_.idle;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid reservation::set_rate(const performance &rate)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    unique_lock lock(rate_mutex_);\n\n    rate_ = rate;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nperformance reservation::rate() const\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    shared_lock lock(rate_mutex_);\n\n    return rate_;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n// Ignore idleness here, called only from an active channel, avoiding a race.\nbool reservation::expired() const\n{\n    const auto record = rate();\n    const auto normal_rate = record.normal();\n    const auto statistics = reservations_.rates();\n    const auto deviation = normal_rate - statistics.arithmentic_mean;\n    const auto absolute_deviation = std::fabs(deviation);\n    const auto allowed_deviation = multiple * statistics.standard_deviation;\n    const auto outlier = absolute_deviation > allowed_deviation;\n    const auto below_average = deviation < 0;\n    const auto expired = below_average && outlier;\n\n    ////log::debug(LOG_NODE)\n    ////    << \"Statistics for slot (\" << slot() << \")\"\n    ////    << \" adj:\" << (normal_rate * micro_per_second)\n    ////    << \" avg:\" << (statistics.arithmentic_mean * micro_per_second)\n    ////    << \" dev:\" << (deviation * micro_per_second)\n    ////    << \" sdv:\" << (statistics.standard_deviation * micro_per_second)\n    ////    << \" cnt:\" << (statistics.active_count)\n    ////    << \" neg:\" << (below_average ? \"T\" : \"F\")\n    ////    << \" out:\" << (outlier ? \"T\" : \"F\")\n    ////    << \" exp:\" << (expired ? \"T\" : \"F\");\n\n    return expired;\n}\n\nvoid reservation::clear_history()\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    unique_lock lock(history_mutex_);\n\n    history_.clear();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n// It is possible to get a rate update after idling and before starting anew.\n// This can reduce the average during startup of the new channel until start.\nvoid reservation::update_rate(size_t events, const microseconds &database)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    history_mutex_.lock();\n\n    performance rate{false, 0, 0, 0};\n    const auto end = now();\n    const auto event_start = end - microseconds(database);\n    const auto start = end - rate_window();\n    const auto history_count = history_.size();\n\n    // Remove expired entries from the head of the queue.\n    for (auto it = history_.begin(); it != history_.end() && it->time < start;\n         it = history_.erase(it))\n        ;\n\n    const auto window_full = history_count > history_.size();\n    const auto event_cost = static_cast<uint64_t>(database.count());\n    history_.push_back({events, event_cost, event_start});\n\n    // We can't set the rate until we have a period (two or more data points).\n    if (history_.size() < minimum_history)\n    {\n        history_mutex_.unlock();\n        //---------------------------------------------------------------------\n        return;\n    }\n\n    // Summarize event count and database cost.\n    for (const auto &record : history_)\n    {\n        BITCOIN_ASSERT(rate.events <= max_size_t - record.events);\n        rate.events += record.events;\n        BITCOIN_ASSERT(rate.database <= max_uint64 - record.database);\n        rate.database += record.database;\n    }\n\n    // Calculate the duration of the rate window.\n    auto window = window_full ? rate_window() : (end - history_.front().time);\n    auto count = duration_cast<microseconds>(window).count();\n    rate.window = static_cast<uint64_t>(count);\n\n    history_mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n\n    // Update the rate cache.\n    set_rate(rate);\n\n    ////log::debug(LOG_NODE)\n    ////    << \"Records (\" << slot() << \") \"\n    ////    << \" size: \" << rate.events\n    ////    << \" time: \" << divide<double>(rate.window, micro_per_second)\n    ////    << \" cost: \" << divide<double>(rate.database, micro_per_second)\n    ////    << \" full: \" << (full ? \"true\" : \"false\");\n}\n\n// Hash methods.\n//-----------------------------------------------------------------------------\n\nbool reservation::empty() const\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    shared_lock lock(hash_mutex_);\n\n    return heights_.empty();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nsize_t reservation::size() const\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    shared_lock lock(hash_mutex_);\n\n    return heights_.size();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nbool reservation::stopped() const\n{\n    // Critical Section (stop)\n    ///////////////////////////////////////////////////////////////////////////\n    shared_lock lock(stop_mutex_);\n\n    return stopped_;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n// Obtain and clear the outstanding blocks request.\nmessage::get_data reservation::request(bool new_channel)\n{\n    message::get_data packet;\n\n    // We are a new channel, clear history and rate data, next block starts.\n    if (new_channel)\n        reset();\n\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    hash_mutex_.lock_upgrade();\n\n    if (!new_channel && !pending_)\n    {\n        hash_mutex_.unlock_upgrade();\n        //---------------------------------------------------------------------\n        return packet;\n    }\n\n    // Build get_blocks request message.\n    for (auto height = heights_.right.begin(); height != heights_.right.end();\n         ++height)\n    {\n        static const auto id = message::inventory::type_id::block;\n        const message::inventory_vector inventory{id, height->second};\n        packet.inventories.emplace_back(inventory);\n    }\n\n    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n    hash_mutex_.unlock_upgrade_and_lock();\n    pending_ = false;\n    hash_mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n\n    return packet;\n}\n\nvoid reservation::insert(const config::checkpoint &checkpoint)\n{\n    insert(checkpoint.hash(), checkpoint.height());\n}\n\nvoid reservation::insert(const hash_digest &hash, size_t height)\n{\n    BITCOIN_ASSERT(height <= max_uint32);\n    const auto height32 = static_cast<uint32_t>(height);\n\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    unique_lock lock(hash_mutex_);\n\n    pending_ = true;\n    heights_.insert({hash, height32});\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid reservation::import(block::ptr block)\n{\n    uint32_t height;\n    const auto hash = block->header.hash();\n    const auto encoded = encode_hash(hash);\n\n    if (!find_height_and_erase(hash, height))\n    {\n        log::debug(LOG_NODE)\n            << \"Ignoring unsolicited block (\" << slot() << \") [\"\n            << encoded << \"]\";\n        return;\n    }\n\n    bool success;\n    const auto importer = [this, &block, &height, &success]() {\n        success = reservations_.import(block, height);\n    };\n\n    // Do the block import with timer.\n    const auto cost = timer<microseconds>::duration(importer);\n\n    if (success)\n    {\n        static const auto unit_size = 1u;\n        update_rate(unit_size, cost);\n        const auto record = rate();\n        static const auto formatter =\n            \"Imported block #%06i (%02i) [%s] %06.2f %05.2f%%\";\n\n        log::info(LOG_NODE)\n            << boost::format(formatter) % height % slot() % encoded %\n                   (record.total() * micro_per_second) % (record.ratio() * 100);\n    }\n    else\n    {\n        log::debug(LOG_NODE)\n            << \"Stopped before importing block (\" << slot() << \") [\"\n            << encoded << \"]\";\n    }\n\n    populate();\n}\n\nvoid reservation::populate()\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    stop_mutex_.lock_upgrade();\n\n    if (!stopped_ && empty())\n    {\n        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n        stop_mutex_.unlock_upgrade_and_lock();\n        stopped_ = !reservations_.populate(shared_from_this());\n        stop_mutex_.unlock();\n        //---------------------------------------------------------------------\n        return;\n    }\n\n    stop_mutex_.unlock_upgrade();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nbool reservation::toggle_partitioned()\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    hash_mutex_.lock_upgrade();\n\n    if (partitioned_)\n    {\n        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n        hash_mutex_.unlock_upgrade_and_lock();\n        partitioned_ = false;\n        pending_ = true;\n        hash_mutex_.unlock();\n        //---------------------------------------------------------------------\n        return true;\n    }\n\n    hash_mutex_.unlock_upgrade();\n    ///////////////////////////////////////////////////////////////////////////\n\n    return false;\n}\n\n// Give the minimal row ~ half of our hashes, return false if minimal is empty.\nbool reservation::partition(reservation::ptr minimal)\n{\n    // This assumes that partition has been called under a table mutex.\n    if (!minimal->empty())\n        return true;\n\n    // Critical Section (hash)\n    ///////////////////////////////////////////////////////////////////////////\n    hash_mutex_.lock_upgrade();\n\n    // Take half of the maximal reservation, rounding up to get last entry.\n    const auto own_size = heights_.size();\n    BITCOIN_ASSERT(own_size < max_size_t && (own_size + 1) / 2 <= max_uint32);\n    const auto offset = static_cast<uint32_t>(own_size + 1) / 2;\n    auto it = heights_.right.begin();\n\n    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n    hash_mutex_.unlock_upgrade_and_lock();\n\n    // TODO: move the range in a single command.\n    for (size_t index = 0; index < offset; ++index)\n    {\n        minimal->heights_.right.insert(std::move(*it));\n        it = heights_.right.erase(it);\n    }\n\n    partitioned_ = !heights_.empty();\n    const auto populated = !minimal->empty();\n    minimal->pending_ = populated;\n\n    if (!partitioned_)\n    {\n        // Critical Section (stop)\n        ///////////////////////////////////////////////////////////////////////\n        unique_lock lock(stop_mutex_);\n\n        // If the channel has been emptied it will not repopulate.\n        stopped_ = true;\n        ///////////////////////////////////////////////////////////////////////\n    }\n\n    hash_mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n\n    if (populated)\n        log::debug(LOG_NODE)\n            << \"Moved [\" << minimal->size() << \"] blocks from slot (\" << slot()\n            << \") to (\" << minimal->slot() << \") leaving [\" << size() << \"].\";\n\n    return populated;\n}\n\nbool reservation::find_height_and_erase(const hash_digest &hash,\n                                        uint32_t &out_height)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    hash_mutex_.lock_upgrade();\n\n    const auto it = heights_.left.find(hash);\n\n    if (it == heights_.left.end())\n    {\n        hash_mutex_.unlock_upgrade();\n        //---------------------------------------------------------------------\n        return false;\n    }\n\n    out_height = it->second;\n\n    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n    hash_mutex_.unlock_upgrade_and_lock();\n    heights_.left.erase(it);\n    hash_mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n\n    return true;\n}\n\n} // namespace node\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/node/utility/reservations.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/node/utility/reservations.hpp>\n\n#include <algorithm>\n#include <cmath>\n#include <cstddef>\n#include <memory>\n#include <numeric>\n#include <utility>\n#include <vector>\n#include <UChain/coin.hpp>\n#include <UChain/node/utility/header_queue.hpp>\n#include <UChain/node/utility/performance.hpp>\n#include <UChain/node/utility/reservation.hpp>\n\nnamespace libbitcoin\n{\nnamespace node\n{\n\nusing namespace bc::blockchain;\nusing namespace bc::chain;\n\n// The protocol maximum size of get data block requests.\nstatic constexpr size_t max_block_request = 50000;\n\nreservations::reservations(header_queue &hashes, simple_chain &chain,\n                           const settings &settings)\n    : hashes_(hashes),\n      blockchain_(chain),\n      max_request_(max_block_request),\n      timeout_(settings.block_timeout_seconds)\n{\n    initialize(settings.download_connections);\n}\n\nbool reservations::import(block::ptr block, size_t height)\n{\n    // Thread safe.\n    return blockchain_.import(block, height);\n}\n\n// Rate methods.\n//-----------------------------------------------------------------------------\n\n// A statistical summary of block import rates.\n// This computation is not synchronized across rows because rates are cached.\nreservations::rate_statistics reservations::rates() const\n{\n    // Copy row pointer table to prevent need for lock during iteration.\n    auto rows = table();\n    const auto idle = [](reservation::ptr row) {\n        return row->idle();\n    };\n\n    // Remove idle rows from the table.\n    rows.erase(std::remove_if(rows.begin(), rows.end(), idle), rows.end());\n    const auto active_rows = rows.size();\n\n    std::vector<double> rates(active_rows);\n    const auto normal_rate = [](reservation::ptr row) {\n        return row->rate().normal();\n    };\n\n    // Convert to a rates table and sum.\n    std::transform(rows.begin(), rows.end(), rates.begin(), normal_rate);\n    const auto total = std::accumulate(rates.begin(), rates.end(), 0.0);\n\n    // Calculate mean and sum of deviations.\n    const auto mean = divide<double>(total, active_rows);\n    const auto summary = [mean](double initial, double rate) {\n        const auto difference = mean - rate;\n        return initial + (difference * difference);\n    };\n\n    // Calculate the standard deviation in the rate deviations.\n    auto squares = std::accumulate(rates.begin(), rates.end(), 0.0, summary);\n    auto quotient = divide<double>(squares, active_rows);\n    auto standard_deviation = std::sqrt(quotient);\n    return {active_rows, mean, standard_deviation};\n}\n\n// Table methods.\n//-----------------------------------------------------------------------------\n\nreservation::list reservations::table() const\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    shared_lock lock(mutex_);\n\n    return table_;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid reservations::remove(reservation::ptr row)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    mutex_.lock_upgrade();\n\n    const auto it = std::find(table_.begin(), table_.end(), row);\n\n    if (it == table_.end())\n    {\n        mutex_.unlock_upgrade();\n        //---------------------------------------------------------------------\n        return;\n    }\n\n    //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n    mutex_.unlock_upgrade_and_lock();\n\n    table_.erase(it);\n\n    mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n// Hash methods.\n//-----------------------------------------------------------------------------\n\n// Mark hashes for blocks we already have.\nvoid reservations::mark_existing()\n{\n    uint64_t gap;\n    auto start = hashes_.first_height();\n\n    // Not thread safe. Returns false when first is > count (last gap).\n    while (blockchain_.get_next_gap(gap, start))\n    {\n        hashes_.invalidate(start, gap - start);\n        start = gap + 1;\n    }\n}\n\n// No critical section because this is private to the constructor.\n// TODO: Optimize by modifying allocation loop to evenly dstribute gap\n// reservations so that re-population is not required. Alternatively\n// convert header_queue to a height/header map and remove instead of mark.\nvoid reservations::initialize(size_t size)\n{\n    // Guard against overflow by capping size.\n    const size_t max_rows = max_size_t / max_request();\n    auto rows = std::min(max_rows, size);\n\n    // Ensure that there is at least one block per row.\n    const auto blocks = hashes_.size();\n    rows = std::min(rows, blocks);\n\n    if (rows == 0)\n        return;\n\n    mark_existing();\n    table_.reserve(rows);\n\n    // Allocate no more than 50k headers per row.\n    const auto max_allocation = rows * max_request();\n    const auto allocation = std::min(blocks, max_allocation);\n\n    for (auto row = 0u; row < rows; ++row)\n        table_.push_back(std::make_shared<reservation>(*this, row, timeout_));\n\n    size_t count = 0;\n    size_t height;\n    hash_digest hash;\n\n    // The (allocation / rows) * rows cannot exceed allocation.\n    // The remainder is retained by the hash list for later reservation.\n    for (size_t base = 0; base < (allocation / rows); ++base)\n    {\n        for (size_t row = 0; row < rows; ++row)\n        {\n            hashes_.dequeue(hash, height);\n\n            if (hashes_.valid(hash))\n            {\n                ++count;\n                table_[row]->insert(hash, height);\n            }\n        }\n    }\n\n    // This is required as any rows left empty above will not populate or stop.\n    for (auto row : table_)\n        row->populate();\n\n    log::debug(LOG_NODE)\n        << \"Reserved \" << count << \" blocks to \" << rows << \" slots.\";\n}\n\n// Call when minimal is empty.\nbool reservations::populate(reservation::ptr minimal)\n{\n    // Critical Section\n    ///////////////////////////////////////////////////////////////////////////\n    mutex_.lock();\n\n    // Take from unallocated or allocated hashes, true if minimal not empty.\n    const auto populated = reserve(minimal) || partition(minimal);\n\n    mutex_.unlock();\n    ///////////////////////////////////////////////////////////////////////////\n\n    if (populated)\n        log::debug(LOG_NODE)\n            << \"Populated \" << minimal->size() << \" blocks to slot (\"\n            << minimal->slot() << \").\";\n\n    return populated;\n}\n\n// This can cause reduction of an active reservation.\nbool reservations::partition(reservation::ptr minimal)\n{\n    const auto maximal = find_maximal();\n    return maximal && maximal != minimal && maximal->partition(minimal);\n}\n\nreservation::ptr reservations::find_maximal()\n{\n    if (table_.empty())\n        return nullptr;\n\n    // The maximal row is that with the most block hashes reserved.\n    const auto comparer = [](reservation::ptr left, reservation::ptr right) {\n        return left->size() < right->size();\n    };\n\n    return *std::max_element(table_.begin(), table_.end(), comparer);\n}\n\n// Return false if minimal is empty.\nbool reservations::reserve(reservation::ptr minimal)\n{\n    if (!minimal->empty())\n        return true;\n\n    const auto allocation = std::min(hashes_.size(), max_request());\n\n    size_t height;\n    hash_digest hash;\n\n    for (size_t block = 0; block < allocation; ++block)\n    {\n        hashes_.dequeue(hash, height);\n\n        if (hashes_.valid(hash))\n            minimal->insert(hash, height);\n    }\n\n    // This may become empty between insert and this test, which is okay.\n    return !minimal->empty();\n}\n\n// Exposed for test to be able to control the request size.\nsize_t reservations::max_request() const\n{\n    return max_request_.load();\n}\n\n// Exposed for test to be able to control the request size.\nvoid reservations::set_max_request(size_t value)\n{\n    max_request_.store(value);\n}\n\n} // namespace node\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/protocol/CMakeLists.txt",
    "content": "FILE(GLOB_RECURSE protocol_SOURCES \"*.cpp\")\n\nSET(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fno-strict-aliasing\")\n\nADD_DEFINITIONS(-DBCP_STATIC=1)\n\nADD_LIBRARY(zmq_static STATIC IMPORTED)\nSET_TARGET_PROPERTIES(zmq_static PROPERTIES IMPORTED_LOCATION ${ZeroMQ_ROOT_DIR}/lib/libzmq.a)\n\nADD_LIBRARY(protocol_static STATIC ${protocol_SOURCES})\nSET_TARGET_PROPERTIES(protocol_static PROPERTIES OUTPUT_NAME uc_protocol)\nTARGET_LINK_LIBRARIES(protocol_static zmq_static ${Boost_LIBRARIES} ${txs_LIBRARY} ${bitcoin_LIBRARY})\nINSTALL(TARGETS protocol_static DESTINATION lib)\n\nIF(ENABLE_SHARED_LIBS)\n    ADD_DEFINITIONS(-DBCP_DLL=1)\n  ADD_LIBRARY(protocol_shared SHARED ${protocol_SOURCES})\n  SET_TARGET_PROPERTIES(protocol_shared PROPERTIES OUTPUT_NAME uc_protocol)\n  TARGET_LINK_LIBRARIES(protocol_shared zmq ${Boost_LIBRARIES} ${txs_LIBRARY} ${bitcoin_LIBRARY})\n  INSTALL(TARGETS protocol_shared DESTINATION lib)\nENDIF()\n"
  },
  {
    "path": "src/UChain/protocol/converter.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifdef UC_VERSION4\n\n#include <UChain/protocol/converter.hpp>\n\n#include <string>\n#include <UChain/coin.hpp>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\n\n/**\n * Copy `binary` data from protobuf's storage format (std::string)\n * to libbitcoin's storage format (hash_digest).\n */\nstatic bool unpack_hash(hash_digest &out, const std::string &in)\n{\n    if (in.size() != hash_size)\n        return false;\n\n    std::copy(in.begin(), in.end(), out.begin());\n    return true;\n}\n\nstatic std::string pack_hash(hash_digest in)\n{\n    return std::string(in.begin(), in.end());\n}\n\nbool converter::from_protocol(const point *point, chain::output_point &result)\n{\n    if (point == nullptr)\n        return false;\n\n    result.index = point->index();\n    return unpack_hash(result.hash, point->hash());\n}\n\nbool converter::from_protocol(const std::shared_ptr<point> point,\n                              chain::output_point &result)\n{\n    return from_protocol(point.get(), result);\n}\n\nbool converter::from_protocol(const tx_input *input, chain::input &result)\n{\n    if (input == nullptr)\n        return false;\n\n    chain::output_point previous;\n    if (!input->has_previous_output() ||\n        !from_protocol(&(input->previous_output()), previous) ||\n        !input->has_script())\n        return false;\n\n    result.previous_output = previous;\n    result.sequence = input->sequence();\n    const auto script_text = input->script();\n    const data_chunk data(script_text.begin(), script_text.end());\n\n    // protocol question - is the data encoding of the script to be\n    // prefixed with operation count?\n    return result.script.from_data(data, false,\n                                   chain::script::parse_mode::raw_data_fallback);\n}\n\nbool converter::from_protocol(const std::shared_ptr<tx_input> input,\n                              chain::input &result)\n{\n    return from_protocol(input.get(), result);\n}\n\nbool converter::from_protocol(const tx_output *output, chain::output &result)\n{\n    if (output == nullptr || !output->has_script())\n        return false;\n\n    result.value = output->value();\n    const auto script_text = output->script();\n    const data_chunk data(script_text.begin(), script_text.end());\n\n    // protocol question - is the data encoding of the script to be\n    // prefixed with operation count?\n    return result.script.from_data(data, false,\n                                   chain::script::parse_mode::raw_data_fallback);\n}\n\nbool converter::from_protocol(const std::shared_ptr<tx_output> output,\n                              chain::output &result)\n{\n    return from_protocol(output.get(), result);\n}\n\nbool converter::from_protocol(const tx *transaction,\n                              chain::transaction &result)\n{\n    if (transaction == nullptr)\n        return false;\n\n    auto success = true;\n    result.version = transaction->version();\n    result.locktime = transaction->locktime();\n\n    for (auto input : transaction->inputs())\n    {\n        chain::input bitcoin_input;\n\n        if (!from_protocol(&input, bitcoin_input))\n        {\n            success = false;\n            break;\n        }\n\n        result.inputs.push_back(bitcoin_input);\n    }\n\n    if (success)\n    {\n        for (auto output : transaction->outputs())\n        {\n            chain::output bitcoin_output;\n\n            if (!from_protocol(&output, bitcoin_output))\n            {\n                success = false;\n                break;\n            }\n\n            result.outputs.push_back(bitcoin_output);\n        }\n    }\n\n    if (!success)\n    {\n        result.version = 0;\n        result.locktime = 0;\n        result.inputs.clear();\n        result.outputs.clear();\n    }\n\n    return success;\n}\n\nbool converter::from_protocol(const std::shared_ptr<tx> transaction,\n                              chain::transaction &result)\n{\n    return from_protocol(transaction.get(), result);\n}\n\nbool converter::from_protocol(const block_header *header,\n                              chain::header &result)\n{\n    if (header == nullptr)\n        return false;\n\n    result.version = header->version();\n    result.timestamp = header->timestamp();\n    result.bits = header->bits();\n    result.nonce = header->nonce();\n    result.transaction_count = header->tx_count();\n    return unpack_hash(result.merkle, header->merkle_root()) &&\n           unpack_hash(result.previous_block_hash, header->previous_block_hash());\n}\n\nbool converter::from_protocol(const std::shared_ptr<block_header> header,\n                              chain::header &result)\n{\n    return from_protocol(header.get(), result);\n}\n\nbool converter::from_protocol(const protocol::block *block,\n                              chain::block &result)\n{\n    if (block == nullptr || !from_protocol(&(block->header()), result.header))\n        return false;\n\n    for (auto tx : block->transactions())\n    {\n        chain::transaction bitcoin_tx;\n\n        if (!from_protocol(&tx, bitcoin_tx))\n        {\n            result.transactions.clear();\n            return false;\n            ;\n        }\n\n        result.transactions.push_back(bitcoin_tx);\n    }\n\n    return true;\n}\n\nbool converter::from_protocol(const std::shared_ptr<block> block,\n                              chain::block &result)\n{\n    return from_protocol(block.get(), result);\n}\n\nbool converter::to_protocol(const chain::output_point &point,\n                            protocol::point &result)\n{\n    result.set_hash(pack_hash(point.hash));\n    result.set_index(point.index);\n    return true;\n}\n\npoint *converter::to_protocol(const chain::output_point &point)\n{\n    std::unique_ptr<protocol::point> result(new protocol::point());\n\n    if (!to_protocol(point, *(result.get())))\n        result.reset();\n\n    return result.release();\n}\n\nbool converter::to_protocol(const chain::input &input, tx_input &result)\n{\n    const auto &previous_output = input.previous_output;\n    result.set_allocated_previous_output(to_protocol(previous_output));\n\n    // protocol question - is the data encoding of the script to be prefixed\n    // with operation count?\n    const auto script_data = input.script.to_data(false);\n    result.set_script(std::string(script_data.begin(), script_data.end()));\n    result.set_sequence(input.sequence);\n    return true;\n}\n\ntx_input *converter::to_protocol(const chain::input &input)\n{\n    std::unique_ptr<tx_input> result(new tx_input());\n\n    if (!to_protocol(input, *(result.get())))\n        result.reset();\n\n    return result.release();\n}\n\nbool converter::to_protocol(const chain::output &output, tx_output &result)\n{\n    result.set_value(output.value);\n\n    // protocol question - is the data encoding of the script to be prefixed\n    // with operation count?\n    const auto script_data = output.script.to_data(false);\n    result.set_script({script_data.begin(), script_data.end()});\n    return true;\n}\n\ntx_output *converter::to_protocol(const chain::output &output)\n{\n    std::unique_ptr<tx_output> result(new tx_output());\n\n    if (!to_protocol(output, *(result.get())))\n        result.reset();\n\n    return result.release();\n}\n\nbool converter::to_protocol(const chain::transaction &transaction, tx &result)\n{\n    result.set_version(transaction.version);\n    result.set_locktime(transaction.locktime);\n    auto repeated_inputs = result.mutable_inputs();\n\n    auto success = true;\n\n    for (const auto &input : transaction.inputs)\n    {\n        if (!to_protocol(input, *(repeated_inputs->Add())))\n        {\n            success = false;\n            break;\n        }\n    }\n\n    auto repeated_outputs = result.mutable_outputs();\n\n    if (success)\n    {\n        for (const auto &output : transaction.outputs)\n        {\n            if (!to_protocol(output, *(repeated_outputs->Add())))\n            {\n                success = false;\n                break;\n            }\n        }\n    }\n\n    if (!success)\n    {\n        result.clear_version();\n        result.clear_locktime();\n        result.clear_inputs();\n        result.clear_outputs();\n    }\n\n    return success;\n}\n\ntx *converter::to_protocol(const chain::transaction &transaction)\n{\n    std::unique_ptr<tx> result(new tx());\n\n    if (!to_protocol(transaction, *(result.get())))\n        result.reset();\n\n    return result.release();\n}\n\nbool converter::to_protocol(const chain::header &header, block_header &result)\n{\n    result.set_version(header.version);\n    result.set_timestamp(header.timestamp);\n    result.set_bits(header.bits);\n    result.set_nonce(header.nonce);\n    result.set_merkle_root(pack_hash(header.merkle));\n    result.set_previous_block_hash(pack_hash(header.previous_block_hash));\n    result.set_tx_count(header.transaction_count);\n    return true;\n}\n\nblock_header *converter::to_protocol(const chain::header &header)\n{\n    std::unique_ptr<block_header> result(new block_header());\n\n    if (!to_protocol(header, *(result.get())))\n        result.reset();\n\n    return result.release();\n}\n\nbool converter::to_protocol(const chain::block &block, protocol::block &result)\n{\n    result.set_allocated_header(to_protocol(block.header));\n    if (!result.has_header())\n        return false;\n\n    auto repeated_transactions = result.mutable_transactions();\n\n    for (const auto &transaction : block.transactions)\n    {\n        if (!to_protocol(transaction, *(repeated_transactions->Add())))\n        {\n            result.clear_header();\n            result.clear_transactions();\n            return false;\n        }\n    }\n\n    return true;\n}\n\nprotocol::block *converter::to_protocol(const chain::block &block)\n{\n    std::unique_ptr<protocol::block> result(new protocol::block());\n\n    if (!to_protocol(block, *(result.get())))\n        result.reset();\n\n    return result.release();\n}\n\n} // namespace protocol\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "src/UChain/protocol/interface.pb.cc",
    "content": "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n// source: bitcoin/protocol/interface.proto\n\n#ifdef UC_VERSION4\n\n#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION\n#include \"bitcoin/protocol/interface.pb.h\"\n\n#include <algorithm>\n\n#include <google/protobuf/stubs/common.h>\n#include <google/protobuf/stubs/once.h>\n#include <google/protobuf/io/coded_stream.h>\n#include <google/protobuf/wire_format_lite_inl.h>\n#include <google/protobuf/descriptor.h>\n#include <google/protobuf/generated_message_reflection.h>\n#include <google/protobuf/reflection_ops.h>\n#include <google/protobuf/wire_format.h>\n// @@protoc_insertion_point(includes)\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\n\nnamespace\n{\n\nconst ::google::protobuf::Descriptor *block_header_descriptor_ = NULL;\nconst ::google::protobuf::internal::GeneratedMessageReflection *\n    block_header_reflection_ = NULL;\nconst ::google::protobuf::Descriptor *point_descriptor_ = NULL;\nconst ::google::protobuf::internal::GeneratedMessageReflection *\n    point_reflection_ = NULL;\nconst ::google::protobuf::Descriptor *tx_input_descriptor_ = NULL;\nconst ::google::protobuf::internal::GeneratedMessageReflection *\n    tx_input_reflection_ = NULL;\nconst ::google::protobuf::Descriptor *tx_output_descriptor_ = NULL;\nconst ::google::protobuf::internal::GeneratedMessageReflection *\n    tx_output_reflection_ = NULL;\nconst ::google::protobuf::Descriptor *tx_descriptor_ = NULL;\nconst ::google::protobuf::internal::GeneratedMessageReflection *\n    tx_reflection_ = NULL;\nconst ::google::protobuf::Descriptor *block_descriptor_ = NULL;\nconst ::google::protobuf::internal::GeneratedMessageReflection *\n    block_reflection_ = NULL;\nconst ::google::protobuf::Descriptor *filter_descriptor_ = NULL;\nconst ::google::protobuf::internal::GeneratedMessageReflection *\n    filter_reflection_ = NULL;\nconst ::google::protobuf::Descriptor *block_id_descriptor_ = NULL;\nconst ::google::protobuf::internal::GeneratedMessageReflection *\n    block_id_reflection_ = NULL;\nconst ::google::protobuf::Descriptor *block_location_descriptor_ = NULL;\nconst ::google::protobuf::internal::GeneratedMessageReflection *\n    block_location_reflection_ = NULL;\nconst ::google::protobuf::Descriptor *tx_hash_result_descriptor_ = NULL;\nconst ::google::protobuf::internal::GeneratedMessageReflection *\n    tx_hash_result_reflection_ = NULL;\nconst ::google::protobuf::Descriptor *tx_result_descriptor_ = NULL;\nconst ::google::protobuf::internal::GeneratedMessageReflection *\n    tx_result_reflection_ = NULL;\nconst ::google::protobuf::Descriptor *output_descriptor_ = NULL;\nconst ::google::protobuf::internal::GeneratedMessageReflection *\n    output_reflection_ = NULL;\nconst ::google::protobuf::Descriptor *utxo_result_descriptor_ = NULL;\nconst ::google::protobuf::internal::GeneratedMessageReflection *\n    utxo_result_reflection_ = NULL;\nconst ::google::protobuf::Descriptor *block_headers_request_descriptor_ = NULL;\nconst ::google::protobuf::internal::GeneratedMessageReflection *\n    block_headers_request_reflection_ = NULL;\nconst ::google::protobuf::Descriptor *transactions_request_descriptor_ = NULL;\nconst ::google::protobuf::internal::GeneratedMessageReflection *\n    transactions_request_reflection_ = NULL;\nconst ::google::protobuf::Descriptor *request_descriptor_ = NULL;\nconst ::google::protobuf::internal::GeneratedMessageReflection *\n    request_reflection_ = NULL;\nstruct requestOneofInstance\n{\n  const ::libbitcoin::protocol::block_headers_request *get_block_headers_;\n  const ::libbitcoin::protocol::transactions_request *get_transactions_;\n  const ::libbitcoin::protocol::tx *post_transaction_;\n  const ::libbitcoin::protocol::tx *validate_tx_engine_;\n  const ::libbitcoin::protocol::block *post_block_;\n  const ::libbitcoin::protocol::block *validate_block_;\n} *request_default_oneof_instance_ = NULL;\nconst ::google::protobuf::Descriptor *response_descriptor_ = NULL;\nconst ::google::protobuf::internal::GeneratedMessageReflection *\n    response_reflection_ = NULL;\nstruct responseOneofInstance\n{\n  const ::libbitcoin::protocol::response_block_headers *get_block_headers_response_;\n  const ::libbitcoin::protocol::response_transactions *get_transactions_response_;\n  bool post_transaction_succeeded_;\n  bool validate_tx_engine_succeeded_;\n  bool post_block_succeeded_;\n  bool validate_block_succeeded_;\n} *response_default_oneof_instance_ = NULL;\nconst ::google::protobuf::Descriptor *response_block_headers_descriptor_ = NULL;\nconst ::google::protobuf::internal::GeneratedMessageReflection *\n    response_block_headers_reflection_ = NULL;\nconst ::google::protobuf::Descriptor *response_transactions_descriptor_ = NULL;\nconst ::google::protobuf::internal::GeneratedMessageReflection *\n    response_transactions_reflection_ = NULL;\nconst ::google::protobuf::EnumDescriptor *filters_descriptor_ = NULL;\nconst ::google::protobuf::EnumDescriptor *tx_results_descriptor_ = NULL;\nconst ::google::protobuf::EnumDescriptor *locations_descriptor_ = NULL;\n\n} // namespace\n\nvoid protobuf_AssignDesc_bitcoin_2fprotocol_2finterface_2eproto()\n{\n  protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  const ::google::protobuf::FileDescriptor *file =\n      ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(\n          \"bitcoin/protocol/interface.proto\");\n  GOOGLE_CHECK(file != NULL);\n  block_header_descriptor_ = file->message_type(0);\n  static const int block_header_offsets_[7] = {\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block_header, version_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block_header, previous_block_hash_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block_header, merkle_root_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block_header, timestamp_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block_header, bits_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block_header, nonce_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block_header, tx_count_),\n  };\n  block_header_reflection_ =\n      new ::google::protobuf::internal::GeneratedMessageReflection(\n          block_header_descriptor_,\n          block_header::default_instance_,\n          block_header_offsets_,\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block_header, _has_bits_[0]),\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block_header, _unknown_fields_),\n          -1,\n          ::google::protobuf::DescriptorPool::generated_pool(),\n          ::google::protobuf::MessageFactory::generated_factory(),\n          sizeof(block_header));\n  point_descriptor_ = file->message_type(1);\n  static const int point_offsets_[2] = {\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(point, hash_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(point, index_),\n  };\n  point_reflection_ =\n      new ::google::protobuf::internal::GeneratedMessageReflection(\n          point_descriptor_,\n          point::default_instance_,\n          point_offsets_,\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(point, _has_bits_[0]),\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(point, _unknown_fields_),\n          -1,\n          ::google::protobuf::DescriptorPool::generated_pool(),\n          ::google::protobuf::MessageFactory::generated_factory(),\n          sizeof(point));\n  tx_input_descriptor_ = file->message_type(2);\n  static const int tx_input_offsets_[3] = {\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(tx_input, previous_output_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(tx_input, script_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(tx_input, sequence_),\n  };\n  tx_input_reflection_ =\n      new ::google::protobuf::internal::GeneratedMessageReflection(\n          tx_input_descriptor_,\n          tx_input::default_instance_,\n          tx_input_offsets_,\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(tx_input, _has_bits_[0]),\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(tx_input, _unknown_fields_),\n          -1,\n          ::google::protobuf::DescriptorPool::generated_pool(),\n          ::google::protobuf::MessageFactory::generated_factory(),\n          sizeof(tx_input));\n  tx_output_descriptor_ = file->message_type(3);\n  static const int tx_output_offsets_[2] = {\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(tx_output, value_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(tx_output, script_),\n  };\n  tx_output_reflection_ =\n      new ::google::protobuf::internal::GeneratedMessageReflection(\n          tx_output_descriptor_,\n          tx_output::default_instance_,\n          tx_output_offsets_,\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(tx_output, _has_bits_[0]),\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(tx_output, _unknown_fields_),\n          -1,\n          ::google::protobuf::DescriptorPool::generated_pool(),\n          ::google::protobuf::MessageFactory::generated_factory(),\n          sizeof(tx_output));\n  tx_descriptor_ = file->message_type(4);\n  static const int tx_offsets_[4] = {\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(tx, version_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(tx, locktime_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(tx, inputs_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(tx, outputs_),\n  };\n  tx_reflection_ =\n      new ::google::protobuf::internal::GeneratedMessageReflection(\n          tx_descriptor_,\n          tx::default_instance_,\n          tx_offsets_,\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(tx, _has_bits_[0]),\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(tx, _unknown_fields_),\n          -1,\n          ::google::protobuf::DescriptorPool::generated_pool(),\n          ::google::protobuf::MessageFactory::generated_factory(),\n          sizeof(tx));\n  block_descriptor_ = file->message_type(5);\n  static const int block_offsets_[3] = {\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block, header_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block, transactions_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block, tree_),\n  };\n  block_reflection_ =\n      new ::google::protobuf::internal::GeneratedMessageReflection(\n          block_descriptor_,\n          block::default_instance_,\n          block_offsets_,\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block, _has_bits_[0]),\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block, _unknown_fields_),\n          -1,\n          ::google::protobuf::DescriptorPool::generated_pool(),\n          ::google::protobuf::MessageFactory::generated_factory(),\n          sizeof(block));\n  filter_descriptor_ = file->message_type(6);\n  static const int filter_offsets_[3] = {\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(filter, filter_type_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(filter, bits_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(filter, prefix_),\n  };\n  filter_reflection_ =\n      new ::google::protobuf::internal::GeneratedMessageReflection(\n          filter_descriptor_,\n          filter::default_instance_,\n          filter_offsets_,\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(filter, _has_bits_[0]),\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(filter, _unknown_fields_),\n          -1,\n          ::google::protobuf::DescriptorPool::generated_pool(),\n          ::google::protobuf::MessageFactory::generated_factory(),\n          sizeof(filter));\n  block_id_descriptor_ = file->message_type(7);\n  static const int block_id_offsets_[2] = {\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block_id, height_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block_id, hash_),\n  };\n  block_id_reflection_ =\n      new ::google::protobuf::internal::GeneratedMessageReflection(\n          block_id_descriptor_,\n          block_id::default_instance_,\n          block_id_offsets_,\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block_id, _has_bits_[0]),\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block_id, _unknown_fields_),\n          -1,\n          ::google::protobuf::DescriptorPool::generated_pool(),\n          ::google::protobuf::MessageFactory::generated_factory(),\n          sizeof(block_id));\n  block_location_descriptor_ = file->message_type(8);\n  static const int block_location_offsets_[3] = {\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block_location, identity_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block_location, index_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block_location, branch_),\n  };\n  block_location_reflection_ =\n      new ::google::protobuf::internal::GeneratedMessageReflection(\n          block_location_descriptor_,\n          block_location::default_instance_,\n          block_location_offsets_,\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block_location, _has_bits_[0]),\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block_location, _unknown_fields_),\n          -1,\n          ::google::protobuf::DescriptorPool::generated_pool(),\n          ::google::protobuf::MessageFactory::generated_factory(),\n          sizeof(block_location));\n  tx_hash_result_descriptor_ = file->message_type(9);\n  static const int tx_hash_result_offsets_[2] = {\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(tx_hash_result, hash_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(tx_hash_result, location_),\n  };\n  tx_hash_result_reflection_ =\n      new ::google::protobuf::internal::GeneratedMessageReflection(\n          tx_hash_result_descriptor_,\n          tx_hash_result::default_instance_,\n          tx_hash_result_offsets_,\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(tx_hash_result, _has_bits_[0]),\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(tx_hash_result, _unknown_fields_),\n          -1,\n          ::google::protobuf::DescriptorPool::generated_pool(),\n          ::google::protobuf::MessageFactory::generated_factory(),\n          sizeof(tx_hash_result));\n  tx_result_descriptor_ = file->message_type(10);\n  static const int tx_result_offsets_[2] = {\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(tx_result, transaction_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(tx_result, location_),\n  };\n  tx_result_reflection_ =\n      new ::google::protobuf::internal::GeneratedMessageReflection(\n          tx_result_descriptor_,\n          tx_result::default_instance_,\n          tx_result_offsets_,\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(tx_result, _has_bits_[0]),\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(tx_result, _unknown_fields_),\n          -1,\n          ::google::protobuf::DescriptorPool::generated_pool(),\n          ::google::protobuf::MessageFactory::generated_factory(),\n          sizeof(tx_result));\n  output_descriptor_ = file->message_type(11);\n  static const int output_offsets_[3] = {\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(output, index_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(output, satoshis_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(output, script_),\n  };\n  output_reflection_ =\n      new ::google::protobuf::internal::GeneratedMessageReflection(\n          output_descriptor_,\n          output::default_instance_,\n          output_offsets_,\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(output, _has_bits_[0]),\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(output, _unknown_fields_),\n          -1,\n          ::google::protobuf::DescriptorPool::generated_pool(),\n          ::google::protobuf::MessageFactory::generated_factory(),\n          sizeof(output));\n  utxo_result_descriptor_ = file->message_type(12);\n  static const int utxo_result_offsets_[3] = {\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(utxo_result, tx_hash_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(utxo_result, location_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(utxo_result, outputs_),\n  };\n  utxo_result_reflection_ =\n      new ::google::protobuf::internal::GeneratedMessageReflection(\n          utxo_result_descriptor_,\n          utxo_result::default_instance_,\n          utxo_result_offsets_,\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(utxo_result, _has_bits_[0]),\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(utxo_result, _unknown_fields_),\n          -1,\n          ::google::protobuf::DescriptorPool::generated_pool(),\n          ::google::protobuf::MessageFactory::generated_factory(),\n          sizeof(utxo_result));\n  block_headers_request_descriptor_ = file->message_type(13);\n  static const int block_headers_request_offsets_[2] = {\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block_headers_request, start_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block_headers_request, results_per_page_),\n  };\n  block_headers_request_reflection_ =\n      new ::google::protobuf::internal::GeneratedMessageReflection(\n          block_headers_request_descriptor_,\n          block_headers_request::default_instance_,\n          block_headers_request_offsets_,\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block_headers_request, _has_bits_[0]),\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(block_headers_request, _unknown_fields_),\n          -1,\n          ::google::protobuf::DescriptorPool::generated_pool(),\n          ::google::protobuf::MessageFactory::generated_factory(),\n          sizeof(block_headers_request));\n  transactions_request_descriptor_ = file->message_type(14);\n  static const int transactions_request_offsets_[5] = {\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(transactions_request, start_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(transactions_request, results_per_page_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(transactions_request, query_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(transactions_request, result_type_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(transactions_request, location_type_),\n  };\n  transactions_request_reflection_ =\n      new ::google::protobuf::internal::GeneratedMessageReflection(\n          transactions_request_descriptor_,\n          transactions_request::default_instance_,\n          transactions_request_offsets_,\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(transactions_request, _has_bits_[0]),\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(transactions_request, _unknown_fields_),\n          -1,\n          ::google::protobuf::DescriptorPool::generated_pool(),\n          ::google::protobuf::MessageFactory::generated_factory(),\n          sizeof(transactions_request));\n  request_descriptor_ = file->message_type(15);\n  static const int request_offsets_[8] = {\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(request, id_),\n      PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(request_default_oneof_instance_, get_block_headers_),\n      PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(request_default_oneof_instance_, get_transactions_),\n      PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(request_default_oneof_instance_, post_transaction_),\n      PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(request_default_oneof_instance_, validate_tx_engine_),\n      PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(request_default_oneof_instance_, post_block_),\n      PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(request_default_oneof_instance_, validate_block_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(request, request_type_),\n  };\n  request_reflection_ =\n      new ::google::protobuf::internal::GeneratedMessageReflection(\n          request_descriptor_,\n          request::default_instance_,\n          request_offsets_,\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(request, _has_bits_[0]),\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(request, _unknown_fields_),\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(request, _extensions_),\n          request_default_oneof_instance_,\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(request, _oneof_case_[0]),\n          ::google::protobuf::DescriptorPool::generated_pool(),\n          ::google::protobuf::MessageFactory::generated_factory(),\n          sizeof(request));\n  response_descriptor_ = file->message_type(16);\n  static const int response_offsets_[9] = {\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(response, id_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(response, status_),\n      PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(response_default_oneof_instance_, get_block_headers_response_),\n      PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(response_default_oneof_instance_, get_transactions_response_),\n      PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(response_default_oneof_instance_, post_transaction_succeeded_),\n      PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(response_default_oneof_instance_, validate_tx_engine_succeeded_),\n      PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(response_default_oneof_instance_, post_block_succeeded_),\n      PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(response_default_oneof_instance_, validate_block_succeeded_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(response, response_type_),\n  };\n  response_reflection_ =\n      new ::google::protobuf::internal::GeneratedMessageReflection(\n          response_descriptor_,\n          response::default_instance_,\n          response_offsets_,\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(response, _has_bits_[0]),\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(response, _unknown_fields_),\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(response, _extensions_),\n          response_default_oneof_instance_,\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(response, _oneof_case_[0]),\n          ::google::protobuf::DescriptorPool::generated_pool(),\n          ::google::protobuf::MessageFactory::generated_factory(),\n          sizeof(response));\n  response_block_headers_descriptor_ = response_descriptor_->nested_type(0);\n  static const int response_block_headers_offsets_[3] = {\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(response_block_headers, next_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(response_block_headers, top_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(response_block_headers, headers_),\n  };\n  response_block_headers_reflection_ =\n      new ::google::protobuf::internal::GeneratedMessageReflection(\n          response_block_headers_descriptor_,\n          response_block_headers::default_instance_,\n          response_block_headers_offsets_,\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(response_block_headers, _has_bits_[0]),\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(response_block_headers, _unknown_fields_),\n          -1,\n          ::google::protobuf::DescriptorPool::generated_pool(),\n          ::google::protobuf::MessageFactory::generated_factory(),\n          sizeof(response_block_headers));\n  response_transactions_descriptor_ = response_descriptor_->nested_type(1);\n  static const int response_transactions_offsets_[5] = {\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(response_transactions, next_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(response_transactions, top_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(response_transactions, hashes_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(response_transactions, transactions_),\n      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(response_transactions, utxos_),\n  };\n  response_transactions_reflection_ =\n      new ::google::protobuf::internal::GeneratedMessageReflection(\n          response_transactions_descriptor_,\n          response_transactions::default_instance_,\n          response_transactions_offsets_,\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(response_transactions, _has_bits_[0]),\n          GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(response_transactions, _unknown_fields_),\n          -1,\n          ::google::protobuf::DescriptorPool::generated_pool(),\n          ::google::protobuf::MessageFactory::generated_factory(),\n          sizeof(response_transactions));\n  filters_descriptor_ = file->enum_type(0);\n  tx_results_descriptor_ = file->enum_type(1);\n  locations_descriptor_ = file->enum_type(2);\n}\n\nnamespace\n{\n\nGOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);\ninline void protobuf_AssignDescriptorsOnce()\n{\n  ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,\n                                     &protobuf_AssignDesc_bitcoin_2fprotocol_2finterface_2eproto);\n}\n\nvoid protobuf_RegisterTypes(const ::std::string &)\n{\n  protobuf_AssignDescriptorsOnce();\n  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n      block_header_descriptor_, &block_header::default_instance());\n  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n      point_descriptor_, &point::default_instance());\n  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n      tx_input_descriptor_, &tx_input::default_instance());\n  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n      tx_output_descriptor_, &tx_output::default_instance());\n  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n      tx_descriptor_, &tx::default_instance());\n  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n      block_descriptor_, &block::default_instance());\n  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n      filter_descriptor_, &filter::default_instance());\n  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n      block_id_descriptor_, &block_id::default_instance());\n  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n      block_location_descriptor_, &block_location::default_instance());\n  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n      tx_hash_result_descriptor_, &tx_hash_result::default_instance());\n  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n      tx_result_descriptor_, &tx_result::default_instance());\n  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n      output_descriptor_, &output::default_instance());\n  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n      utxo_result_descriptor_, &utxo_result::default_instance());\n  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n      block_headers_request_descriptor_, &block_headers_request::default_instance());\n  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n      transactions_request_descriptor_, &transactions_request::default_instance());\n  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n      request_descriptor_, &request::default_instance());\n  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n      response_descriptor_, &response::default_instance());\n  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n      response_block_headers_descriptor_, &response_block_headers::default_instance());\n  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n      response_transactions_descriptor_, &response_transactions::default_instance());\n}\n\n} // namespace\n\nvoid protobuf_ShutdownFile_bitcoin_2fprotocol_2finterface_2eproto()\n{\n  delete block_header::default_instance_;\n  delete block_header_reflection_;\n  delete point::default_instance_;\n  delete point_reflection_;\n  delete tx_input::default_instance_;\n  delete tx_input_reflection_;\n  delete tx_output::default_instance_;\n  delete tx_output_reflection_;\n  delete tx::default_instance_;\n  delete tx_reflection_;\n  delete block::default_instance_;\n  delete block_reflection_;\n  delete filter::default_instance_;\n  delete filter_reflection_;\n  delete block_id::default_instance_;\n  delete block_id_reflection_;\n  delete block_location::default_instance_;\n  delete block_location_reflection_;\n  delete tx_hash_result::default_instance_;\n  delete tx_hash_result_reflection_;\n  delete tx_result::default_instance_;\n  delete tx_result_reflection_;\n  delete output::default_instance_;\n  delete output_reflection_;\n  delete utxo_result::default_instance_;\n  delete utxo_result_reflection_;\n  delete block_headers_request::default_instance_;\n  delete block_headers_request_reflection_;\n  delete transactions_request::default_instance_;\n  delete transactions_request_reflection_;\n  delete request::default_instance_;\n  delete request_default_oneof_instance_;\n  delete request_reflection_;\n  delete response::default_instance_;\n  delete response_default_oneof_instance_;\n  delete response_reflection_;\n  delete response_block_headers::default_instance_;\n  delete response_block_headers_reflection_;\n  delete response_transactions::default_instance_;\n  delete response_transactions_reflection_;\n}\n\nvoid protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto()\n{\n  static bool already_here = false;\n  if (already_here)\n    return;\n  already_here = true;\n  GOOGLE_PROTOBUF_VERIFY_VERSION;\n\n  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(\n      \"\\n bitcoin/protocol/interface.proto\\022\\023libb\"\n      \"itcoin.protocol\\\"\\223\\001\\n\\014block_header\\022\\017\\n\\007vers\"\n      \"ion\\030\\001 \\002(\\r\\022\\033\\n\\023previous_block_hash\\030\\002 \\002(\\014\\022\\023\"\n      \"\\n\\013merkle_root\\030\\003 \\002(\\014\\022\\021\\n\\ttimestamp\\030\\004 \\002(\\r\\022\\014\"\n      \"\\n\\004bits\\030\\005 \\002(\\r\\022\\r\\n\\005nonce\\030\\006 \\002(\\r\\022\\020\\n\\010tx_count\\030\"\n      \"\\007 \\002(\\004\\\"$\\n\\005point\\022\\014\\n\\004hash\\030\\001 \\002(\\014\\022\\r\\n\\005index\\030\\002 \"\n      \"\\002(\\r\\\"a\\n\\010tx_input\\0223\\n\\017previous_output\\030\\001 \\002(\\013\"\n      \"2\\032.libbitcoin.protocol.point\\022\\016\\n\\006script\\030\\002\"\n      \" \\002(\\014\\022\\020\\n\\010sequence\\030\\003 \\002(\\r\\\"*\\n\\ttx_output\\022\\r\\n\\005v\"\n      \"alue\\030\\001 \\002(\\004\\022\\016\\n\\006script\\030\\002 \\002(\\014\\\"\\207\\001\\n\\002tx\\022\\017\\n\\007ver\"\n      \"sion\\030\\001 \\002(\\r\\022\\020\\n\\010locktime\\030\\002 \\002(\\r\\022-\\n\\006inputs\\030\\003\"\n      \" \\003(\\0132\\035.libbitcoin.protocol.tx_input\\022/\\n\\007o\"\n      \"utputs\\030\\004 \\003(\\0132\\036.libbitcoin.protocol.tx_ou\"\n      \"tput\\\"w\\n\\005block\\0221\\n\\006header\\030\\001 \\002(\\0132!.libbitco\"\n      \"in.protocol.block_header\\022-\\n\\014transactions\"\n      \"\\030\\002 \\003(\\0132\\027.libbitcoin.protocol.tx\\022\\014\\n\\004tree\\030\"\n      \"\\003 \\003(\\014\\\"Y\\n\\006filter\\0221\\n\\013filter_type\\030\\001 \\002(\\0162\\034.l\"\n      \"ibbitcoin.protocol.filters\\022\\014\\n\\004bits\\030\\002 \\001(\\r\"\n      \"\\022\\016\\n\\006prefix\\030\\003 \\002(\\014\\\"(\\n\\010block_id\\022\\016\\n\\006height\\030\\001\"\n      \" \\001(\\r\\022\\014\\n\\004hash\\030\\002 \\001(\\014\\\"`\\n\\016block_location\\022/\\n\\010\"\n      \"identity\\030\\001 \\001(\\0132\\035.libbitcoin.protocol.blo\"\n      \"ck_id\\022\\r\\n\\005index\\030\\002 \\001(\\004\\022\\016\\n\\006branch\\030\\003 \\003(\\014\\\"U\\n\\016\"\n      \"tx_hash_result\\022\\014\\n\\004hash\\030\\001 \\002(\\014\\0225\\n\\010location\"\n      \"\\030\\002 \\002(\\0132#.libbitcoin.protocol.block_locat\"\n      \"ion\\\"p\\n\\ttx_result\\022,\\n\\013transaction\\030\\001 \\002(\\0132\\027.\"\n      \"libbitcoin.protocol.tx\\0225\\n\\010location\\030\\002 \\002(\\013\"\n      \"2#.libbitcoin.protocol.block_location\\\"9\\n\"\n      \"\\006output\\022\\r\\n\\005index\\030\\001 \\002(\\r\\022\\020\\n\\010satoshis\\030\\002 \\002(\\004\"\n      \"\\022\\016\\n\\006script\\030\\003 \\002(\\014\\\"\\203\\001\\n\\013utxo_result\\022\\017\\n\\007tx_h\"\n      \"ash\\030\\001 \\002(\\014\\0225\\n\\010location\\030\\002 \\002(\\0132#.libbitcoin\"\n      \".protocol.block_location\\022,\\n\\007outputs\\030\\003 \\003(\"\n      \"\\0132\\033.libbitcoin.protocol.output\\\"_\\n\\025block_\"\n      \"headers_request\\022,\\n\\005start\\030\\001 \\001(\\0132\\035.libbitc\"\n      \"oin.protocol.block_id\\022\\030\\n\\020results_per_pag\"\n      \"e\\030\\002 \\001(\\r\\\"\\217\\002\\n\\024transactions_request\\022,\\n\\005star\"\n      \"t\\030\\001 \\001(\\0132\\035.libbitcoin.protocol.block_id\\022\\030\"\n      \"\\n\\020results_per_page\\030\\002 \\001(\\r\\022*\\n\\005query\\030\\003 \\003(\\0132\"\n      \"\\033.libbitcoin.protocol.filter\\022F\\n\\013result_t\"\n      \"ype\\030\\004 \\001(\\0162(.libbitcoin.protocol.transact\"\n      \"ion_results:\\007TX_HASH\\022;\\n\\rlocation_type\\030\\005 \"\n      \"\\001(\\0162\\036.libbitcoin.protocol.locations:\\004NON\"\n      \"E\\\"\\222\\003\\n\\007request\\022\\n\\n\\002id\\030\\001 \\002(\\r\\022G\\n\\021get_block_h\"\n      \"eaders\\030\\002 \\001(\\0132*.libbitcoin.protocol.block\"\n      \"_headers_requestH\\000\\022E\\n\\020get_transactions\\030\\003\"\n      \" \\001(\\0132).libbitcoin.protocol.transactions_\"\n      \"requestH\\000\\0223\\n\\020post_transaction\\030\\004 \\001(\\0132\\027.li\"\n      \"bbitcoin.protocol.txH\\000\\0227\\n\\024validate_trans\"\n      \"action\\030\\005 \\001(\\0132\\027.libbitcoin.protocol.txH\\000\\022\"\n      \"0\\n\\npost_block\\030\\006 \\001(\\0132\\032.libbitcoin.protoco\"\n      \"l.blockH\\000\\0224\\n\\016validate_block\\030\\007 \\001(\\0132\\032.libb\"\n      \"itcoin.protocol.blockH\\000*\\005\\010d\\020\\310\\001B\\016\\n\\014reques\"\n      \"t_type\\\"\\233\\006\\n\\010response\\022\\n\\n\\002id\\030\\001 \\002(\\r\\022\\016\\n\\006statu\"\n      \"s\\030\\002 \\001(\\021\\022Q\\n\\032get_block_headers_response\\030\\003 \"\n      \"\\001(\\0132+.libbitcoin.protocol.response.block\"\n      \"_headersH\\000\\022O\\n\\031get_transactions_response\\030\"\n      \"\\004 \\001(\\0132*.libbitcoin.protocol.response.tra\"\n      \"nsactionsH\\000\\022$\\n\\032post_transaction_succeede\"\n      \"d\\030\\005 \\001(\\010H\\000\\022(\\n\\036validate_tx_engine_succee\"\n      \"ded\\030\\006 \\001(\\010H\\000\\022\\036\\n\\024post_block_succeeded\\030\\007 \\001(\"\n      \"\\010H\\000\\022\\\"\\n\\030validate_block_succeeded\\030\\010 \\001(\\010H\\000\\032\"\n      \"\\234\\001\\n\\rblock_headers\\022+\\n\\004next\\030\\001 \\001(\\0132\\035.libbit\"\n      \"coin.protocol.block_id\\022*\\n\\003top\\030\\002 \\001(\\0132\\035.li\"\n      \"bbitcoin.protocol.block_id\\0222\\n\\007headers\\030\\003 \"\n      \"\\003(\\0132!.libbitcoin.protocol.block_header\\032\\203\"\n      \"\\002\\n\\014transactions\\022+\\n\\004next\\030\\001 \\001(\\0132\\035.libbitco\"\n      \"in.protocol.block_id\\022*\\n\\003top\\030\\002 \\001(\\0132\\035.libb\"\n      \"itcoin.protocol.block_id\\0223\\n\\006hashes\\030\\003 \\003(\\013\"\n      \"2#.libbitcoin.protocol.tx_hash_result\\0224\\n\"\n      \"\\014transactions\\030\\004 \\003(\\0132\\036.libbitcoin.protoco\"\n      \"l.tx_result\\022/\\n\\005utxos\\030\\005 \\003(\\0132 .libbitcoin.\"\n      \"protocol.utxo_result*\\005\\010d\\020\\310\\001B\\017\\n\\rresponse_\"\n      \"type*4\\n\\007filters\\022\\013\\n\\007ADDRESS\\020\\001\\022\\017\\n\\013TRANSACT\"\n      \"ION\\020\\002\\022\\013\\n\\007STEALTH\\020\\003*B\\n\\023tx_result\"\n      \"s\\022\\013\\n\\007TX_HASH\\020\\001\\022\\r\\n\\tTX_RESULT\\020\\002\\022\\017\\n\\013UTXO_RE\"\n      \"SULT\\020\\003*,\\n\\tlocations\\022\\010\\n\\004NONE\\020\\000\\022\\t\\n\\005BLOCK\\020\\001\"\n      \"\\022\\n\\n\\006MERKLE\\020\\002\",\n      3012);\n  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(\n      \"bitcoin/protocol/interface.proto\", &protobuf_RegisterTypes);\n  block_header::default_instance_ = new block_header();\n  point::default_instance_ = new point();\n  tx_input::default_instance_ = new tx_input();\n  tx_output::default_instance_ = new tx_output();\n  tx::default_instance_ = new tx();\n  block::default_instance_ = new block();\n  filter::default_instance_ = new filter();\n  block_id::default_instance_ = new block_id();\n  block_location::default_instance_ = new block_location();\n  tx_hash_result::default_instance_ = new tx_hash_result();\n  tx_result::default_instance_ = new tx_result();\n  output::default_instance_ = new output();\n  utxo_result::default_instance_ = new utxo_result();\n  block_headers_request::default_instance_ = new block_headers_request();\n  transactions_request::default_instance_ = new transactions_request();\n  request::default_instance_ = new request();\n  request_default_oneof_instance_ = new requestOneofInstance;\n  response::default_instance_ = new response();\n  response_default_oneof_instance_ = new responseOneofInstance;\n  response_block_headers::default_instance_ = new response_block_headers();\n  response_transactions::default_instance_ = new response_transactions();\n  block_header::default_instance_->InitAsDefaultInstance();\n  point::default_instance_->InitAsDefaultInstance();\n  tx_input::default_instance_->InitAsDefaultInstance();\n  tx_output::default_instance_->InitAsDefaultInstance();\n  tx::default_instance_->InitAsDefaultInstance();\n  block::default_instance_->InitAsDefaultInstance();\n  filter::default_instance_->InitAsDefaultInstance();\n  block_id::default_instance_->InitAsDefaultInstance();\n  block_location::default_instance_->InitAsDefaultInstance();\n  tx_hash_result::default_instance_->InitAsDefaultInstance();\n  tx_result::default_instance_->InitAsDefaultInstance();\n  output::default_instance_->InitAsDefaultInstance();\n  utxo_result::default_instance_->InitAsDefaultInstance();\n  block_headers_request::default_instance_->InitAsDefaultInstance();\n  transactions_request::default_instance_->InitAsDefaultInstance();\n  request::default_instance_->InitAsDefaultInstance();\n  response::default_instance_->InitAsDefaultInstance();\n  response_block_headers::default_instance_->InitAsDefaultInstance();\n  response_transactions::default_instance_->InitAsDefaultInstance();\n  ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_bitcoin_2fprotocol_2finterface_2eproto);\n}\n\n// Force AddDescriptors() to be called at static initialization time.\nstruct StaticDescriptorInitializer_bitcoin_2fprotocol_2finterface_2eproto\n{\n  StaticDescriptorInitializer_bitcoin_2fprotocol_2finterface_2eproto()\n  {\n    protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  }\n} static_descriptor_initializer_bitcoin_2fprotocol_2finterface_2eproto_;\nconst ::google::protobuf::EnumDescriptor *filters_descriptor()\n{\n  protobuf_AssignDescriptorsOnce();\n  return filters_descriptor_;\n}\nbool filters_IsValid(int value)\n{\n  switch (value)\n  {\n  case 1:\n  case 2:\n  case 3:\n    return true;\n  default:\n    return false;\n  }\n}\n\nconst ::google::protobuf::EnumDescriptor *tx_results_descriptor()\n{\n  protobuf_AssignDescriptorsOnce();\n  return tx_results_descriptor_;\n}\nbool tx_results_IsValid(int value)\n{\n  switch (value)\n  {\n  case 1:\n  case 2:\n  case 3:\n    return true;\n  default:\n    return false;\n  }\n}\n\nconst ::google::protobuf::EnumDescriptor *locations_descriptor()\n{\n  protobuf_AssignDescriptorsOnce();\n  return locations_descriptor_;\n}\nbool locations_IsValid(int value)\n{\n  switch (value)\n  {\n  case 0:\n  case 1:\n  case 2:\n    return true;\n  default:\n    return false;\n  }\n}\n\n// ===================================================================\n\n#ifndef _MSC_VER\nconst int block_header::kVersionFieldNumber;\nconst int block_header::kPreviousBlockHashFieldNumber;\nconst int block_header::kMerkleRootFieldNumber;\nconst int block_header::kTimestampFieldNumber;\nconst int block_header::kBitsFieldNumber;\nconst int block_header::kNonceFieldNumber;\nconst int block_header::kTxCountFieldNumber;\n#endif // !_MSC_VER\n\nblock_header::block_header()\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  // @@protoc_insertion_point(constructor:libbitcoin.protocol.block_header)\n}\n\nvoid block_header::InitAsDefaultInstance()\n{\n}\n\nblock_header::block_header(const block_header &from)\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  MergeFrom(from);\n  // @@protoc_insertion_point(copy_constructor:libbitcoin.protocol.block_header)\n}\n\nvoid block_header::SharedCtor()\n{\n  ::google::protobuf::internal::GetEmptyString();\n  _cached_size_ = 0;\n  version_ = 0u;\n  previous_block_hash_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n  merkle_root_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n  timestamp_ = 0u;\n  bits_ = 0u;\n  nonce_ = 0u;\n  tx_count_ = GOOGLE_ULONGLONG(0);\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n}\n\nblock_header::~block_header()\n{\n  // @@protoc_insertion_point(destructor:libbitcoin.protocol.block_header)\n  SharedDtor();\n}\n\nvoid block_header::SharedDtor()\n{\n  if (previous_block_hash_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    delete previous_block_hash_;\n  }\n  if (merkle_root_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    delete merkle_root_;\n  }\n  if (this != default_instance_)\n  {\n  }\n}\n\nvoid block_header::SetCachedSize(int size) const\n{\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n}\nconst ::google::protobuf::Descriptor *block_header::descriptor()\n{\n  protobuf_AssignDescriptorsOnce();\n  return block_header_descriptor_;\n}\n\nconst block_header &block_header::default_instance()\n{\n  if (default_instance_ == NULL)\n    protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  return *default_instance_;\n}\n\nblock_header *block_header::default_instance_ = NULL;\n\nblock_header *block_header::New() const\n{\n  return new block_header;\n}\n\nvoid block_header::Clear()\n{\n#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char *>(                       \\\n                                 &reinterpret_cast<block_header *>(16)->f) - \\\n                             reinterpret_cast<char *>(16))\n\n#define ZR_(first, last)                                  \\\n  do                                                      \\\n  {                                                       \\\n    size_t f = OFFSET_OF_FIELD_(first);                   \\\n    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \\\n    ::memset(&first, 0, n);                               \\\n  } while (0)\n\n  if (_has_bits_[0 / 32] & 127)\n  {\n    ZR_(version_, timestamp_);\n    ZR_(bits_, tx_count_);\n    if (has_previous_block_hash())\n    {\n      if (previous_block_hash_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n      {\n        previous_block_hash_->clear();\n      }\n    }\n    if (has_merkle_root())\n    {\n      if (merkle_root_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n      {\n        merkle_root_->clear();\n      }\n    }\n  }\n\n#undef OFFSET_OF_FIELD_\n#undef ZR_\n\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n  mutable_unknown_fields()->Clear();\n}\n\nbool block_header::MergePartialFromCodedStream(\n    ::google::protobuf::io::CodedInputStream *input)\n{\n#define DO_(EXPRESSION) \\\n  if (!(EXPRESSION))    \\\n  goto failure\n  ::google::protobuf::uint32 tag;\n  // @@protoc_insertion_point(parse_start:libbitcoin.protocol.block_header)\n  for (;;)\n  {\n    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);\n    tag = p.first;\n    if (!p.second)\n      goto handle_unusual;\n    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag))\n    {\n    // required uint32 version = 1;\n    case 1:\n    {\n      if (tag == 8)\n      {\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(\n            input, &version_)));\n        set_has_version();\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(18))\n        goto parse_previous_block_hash;\n      break;\n    }\n\n    // required bytes previous_block_hash = 2;\n    case 2:\n    {\n      if (tag == 18)\n      {\n      parse_previous_block_hash:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(\n            input, this->mutable_previous_block_hash()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(26))\n        goto parse_merkle_root;\n      break;\n    }\n\n    // required bytes merkle_root = 3;\n    case 3:\n    {\n      if (tag == 26)\n      {\n      parse_merkle_root:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(\n            input, this->mutable_merkle_root()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(32))\n        goto parse_timestamp;\n      break;\n    }\n\n    // required uint32 timestamp = 4;\n    case 4:\n    {\n      if (tag == 32)\n      {\n      parse_timestamp:\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(\n            input, &timestamp_)));\n        set_has_timestamp();\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(40))\n        goto parse_bits;\n      break;\n    }\n\n    // required uint32 bits = 5;\n    case 5:\n    {\n      if (tag == 40)\n      {\n      parse_bits:\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(\n            input, &bits_)));\n        set_has_bits();\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(48))\n        goto parse_nonce;\n      break;\n    }\n\n    // required uint32 nonce = 6;\n    case 6:\n    {\n      if (tag == 48)\n      {\n      parse_nonce:\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(\n            input, &nonce_)));\n        set_has_nonce();\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(56))\n        goto parse_tx_count;\n      break;\n    }\n\n    // required uint64 tx_count = 7;\n    case 7:\n    {\n      if (tag == 56)\n      {\n      parse_tx_count:\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(\n            input, &tx_count_)));\n        set_has_tx_count();\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectAtEnd())\n        goto success;\n      break;\n    }\n\n    default:\n    {\n    handle_unusual:\n      if (tag == 0 ||\n          ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n              ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP)\n      {\n        goto success;\n      }\n      DO_(::google::protobuf::internal::WireFormat::SkipField(\n          input, tag, mutable_unknown_fields()));\n      break;\n    }\n    }\n  }\nsuccess:\n  // @@protoc_insertion_point(parse_success:libbitcoin.protocol.block_header)\n  return true;\nfailure:\n  // @@protoc_insertion_point(parse_failure:libbitcoin.protocol.block_header)\n  return false;\n#undef DO_\n}\n\nvoid block_header::SerializeWithCachedSizes(\n    ::google::protobuf::io::CodedOutputStream *output) const\n{\n  // @@protoc_insertion_point(serialize_start:libbitcoin.protocol.block_header)\n  // required uint32 version = 1;\n  if (has_version())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->version(), output);\n  }\n\n  // required bytes previous_block_hash = 2;\n  if (has_previous_block_hash())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(\n        2, this->previous_block_hash(), output);\n  }\n\n  // required bytes merkle_root = 3;\n  if (has_merkle_root())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(\n        3, this->merkle_root(), output);\n  }\n\n  // required uint32 timestamp = 4;\n  if (has_timestamp())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteUInt32(4, this->timestamp(), output);\n  }\n\n  // required uint32 bits = 5;\n  if (has_bits())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteUInt32(5, this->bits(), output);\n  }\n\n  // required uint32 nonce = 6;\n  if (has_nonce())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteUInt32(6, this->nonce(), output);\n  }\n\n  // required uint64 tx_count = 7;\n  if (has_tx_count())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteUInt64(7, this->tx_count(), output);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n        unknown_fields(), output);\n  }\n  // @@protoc_insertion_point(serialize_end:libbitcoin.protocol.block_header)\n}\n\n::google::protobuf::uint8 *block_header::SerializeWithCachedSizesToArray(\n    ::google::protobuf::uint8 *target) const\n{\n  // @@protoc_insertion_point(serialize_to_array_start:libbitcoin.protocol.block_header)\n  // required uint32 version = 1;\n  if (has_version())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->version(), target);\n  }\n\n  // required bytes previous_block_hash = 2;\n  if (has_previous_block_hash())\n  {\n    target =\n        ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(\n            2, this->previous_block_hash(), target);\n  }\n\n  // required bytes merkle_root = 3;\n  if (has_merkle_root())\n  {\n    target =\n        ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(\n            3, this->merkle_root(), target);\n  }\n\n  // required uint32 timestamp = 4;\n  if (has_timestamp())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(4, this->timestamp(), target);\n  }\n\n  // required uint32 bits = 5;\n  if (has_bits())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(5, this->bits(), target);\n  }\n\n  // required uint32 nonce = 6;\n  if (has_nonce())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(6, this->nonce(), target);\n  }\n\n  // required uint64 tx_count = 7;\n  if (has_tx_count())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(7, this->tx_count(), target);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n        unknown_fields(), target);\n  }\n  // @@protoc_insertion_point(serialize_to_array_end:libbitcoin.protocol.block_header)\n  return target;\n}\n\nint block_header::ByteSize() const\n{\n  int total_size = 0;\n\n  if (_has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    // required uint32 version = 1;\n    if (has_version())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::UInt32Size(\n                        this->version());\n    }\n\n    // required bytes previous_block_hash = 2;\n    if (has_previous_block_hash())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::BytesSize(\n                        this->previous_block_hash());\n    }\n\n    // required bytes merkle_root = 3;\n    if (has_merkle_root())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::BytesSize(\n                        this->merkle_root());\n    }\n\n    // required uint32 timestamp = 4;\n    if (has_timestamp())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::UInt32Size(\n                        this->timestamp());\n    }\n\n    // required uint32 bits = 5;\n    if (has_bits())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::UInt32Size(\n                        this->bits());\n    }\n\n    // required uint32 nonce = 6;\n    if (has_nonce())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::UInt32Size(\n                        this->nonce());\n    }\n\n    // required uint64 tx_count = 7;\n    if (has_tx_count())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::UInt64Size(\n                        this->tx_count());\n    }\n  }\n  if (!unknown_fields().empty())\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n            unknown_fields());\n  }\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = total_size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n  return total_size;\n}\n\nvoid block_header::MergeFrom(const ::google::protobuf::Message &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  const block_header *source =\n      ::google::protobuf::internal::dynamic_cast_if_available<const block_header *>(\n          &from);\n  if (source == NULL)\n  {\n    ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n  }\n  else\n  {\n    MergeFrom(*source);\n  }\n}\n\nvoid block_header::MergeFrom(const block_header &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    if (from.has_version())\n    {\n      set_version(from.version());\n    }\n    if (from.has_previous_block_hash())\n    {\n      set_previous_block_hash(from.previous_block_hash());\n    }\n    if (from.has_merkle_root())\n    {\n      set_merkle_root(from.merkle_root());\n    }\n    if (from.has_timestamp())\n    {\n      set_timestamp(from.timestamp());\n    }\n    if (from.has_bits())\n    {\n      set_bits(from.bits());\n    }\n    if (from.has_nonce())\n    {\n      set_nonce(from.nonce());\n    }\n    if (from.has_tx_count())\n    {\n      set_tx_count(from.tx_count());\n    }\n  }\n  mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n}\n\nvoid block_header::CopyFrom(const ::google::protobuf::Message &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nvoid block_header::CopyFrom(const block_header &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nbool block_header::IsInitialized() const\n{\n  if ((_has_bits_[0] & 0x0000007f) != 0x0000007f)\n    return false;\n\n  return true;\n}\n\nvoid block_header::Swap(block_header *other)\n{\n  if (other != this)\n  {\n    std::swap(version_, other->version_);\n    std::swap(previous_block_hash_, other->previous_block_hash_);\n    std::swap(merkle_root_, other->merkle_root_);\n    std::swap(timestamp_, other->timestamp_);\n    std::swap(bits_, other->bits_);\n    std::swap(nonce_, other->nonce_);\n    std::swap(tx_count_, other->tx_count_);\n    std::swap(_has_bits_[0], other->_has_bits_[0]);\n    _unknown_fields_.Swap(&other->_unknown_fields_);\n    std::swap(_cached_size_, other->_cached_size_);\n  }\n}\n\n::google::protobuf::Metadata block_header::GetMetadata() const\n{\n  protobuf_AssignDescriptorsOnce();\n  ::google::protobuf::Metadata metadata;\n  metadata.descriptor = block_header_descriptor_;\n  metadata.reflection = block_header_reflection_;\n  return metadata;\n}\n\n// ===================================================================\n\n#ifndef _MSC_VER\nconst int point::kHashFieldNumber;\nconst int point::kIndexFieldNumber;\n#endif // !_MSC_VER\n\npoint::point()\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  // @@protoc_insertion_point(constructor:libbitcoin.protocol.point)\n}\n\nvoid point::InitAsDefaultInstance()\n{\n}\n\npoint::point(const point &from)\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  MergeFrom(from);\n  // @@protoc_insertion_point(copy_constructor:libbitcoin.protocol.point)\n}\n\nvoid point::SharedCtor()\n{\n  ::google::protobuf::internal::GetEmptyString();\n  _cached_size_ = 0;\n  hash_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n  index_ = 0u;\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n}\n\npoint::~point()\n{\n  // @@protoc_insertion_point(destructor:libbitcoin.protocol.point)\n  SharedDtor();\n}\n\nvoid point::SharedDtor()\n{\n  if (hash_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    delete hash_;\n  }\n  if (this != default_instance_)\n  {\n  }\n}\n\nvoid point::SetCachedSize(int size) const\n{\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n}\nconst ::google::protobuf::Descriptor *point::descriptor()\n{\n  protobuf_AssignDescriptorsOnce();\n  return point_descriptor_;\n}\n\nconst point &point::default_instance()\n{\n  if (default_instance_ == NULL)\n    protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  return *default_instance_;\n}\n\npoint *point::default_instance_ = NULL;\n\npoint *point::New() const\n{\n  return new point;\n}\n\nvoid point::Clear()\n{\n  if (_has_bits_[0 / 32] & 3)\n  {\n    if (has_hash())\n    {\n      if (hash_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n      {\n        hash_->clear();\n      }\n    }\n    index_ = 0u;\n  }\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n  mutable_unknown_fields()->Clear();\n}\n\nbool point::MergePartialFromCodedStream(\n    ::google::protobuf::io::CodedInputStream *input)\n{\n#define DO_(EXPRESSION) \\\n  if (!(EXPRESSION))    \\\n  goto failure\n  ::google::protobuf::uint32 tag;\n  // @@protoc_insertion_point(parse_start:libbitcoin.protocol.point)\n  for (;;)\n  {\n    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);\n    tag = p.first;\n    if (!p.second)\n      goto handle_unusual;\n    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag))\n    {\n    // required bytes hash = 1;\n    case 1:\n    {\n      if (tag == 10)\n      {\n        DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(\n            input, this->mutable_hash()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(16))\n        goto parse_index;\n      break;\n    }\n\n    // required uint32 index = 2;\n    case 2:\n    {\n      if (tag == 16)\n      {\n      parse_index:\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(\n            input, &index_)));\n        set_has_index();\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectAtEnd())\n        goto success;\n      break;\n    }\n\n    default:\n    {\n    handle_unusual:\n      if (tag == 0 ||\n          ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n              ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP)\n      {\n        goto success;\n      }\n      DO_(::google::protobuf::internal::WireFormat::SkipField(\n          input, tag, mutable_unknown_fields()));\n      break;\n    }\n    }\n  }\nsuccess:\n  // @@protoc_insertion_point(parse_success:libbitcoin.protocol.point)\n  return true;\nfailure:\n  // @@protoc_insertion_point(parse_failure:libbitcoin.protocol.point)\n  return false;\n#undef DO_\n}\n\nvoid point::SerializeWithCachedSizes(\n    ::google::protobuf::io::CodedOutputStream *output) const\n{\n  // @@protoc_insertion_point(serialize_start:libbitcoin.protocol.point)\n  // required bytes hash = 1;\n  if (has_hash())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(\n        1, this->hash(), output);\n  }\n\n  // required uint32 index = 2;\n  if (has_index())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->index(), output);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n        unknown_fields(), output);\n  }\n  // @@protoc_insertion_point(serialize_end:libbitcoin.protocol.point)\n}\n\n::google::protobuf::uint8 *point::SerializeWithCachedSizesToArray(\n    ::google::protobuf::uint8 *target) const\n{\n  // @@protoc_insertion_point(serialize_to_array_start:libbitcoin.protocol.point)\n  // required bytes hash = 1;\n  if (has_hash())\n  {\n    target =\n        ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(\n            1, this->hash(), target);\n  }\n\n  // required uint32 index = 2;\n  if (has_index())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->index(), target);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n        unknown_fields(), target);\n  }\n  // @@protoc_insertion_point(serialize_to_array_end:libbitcoin.protocol.point)\n  return target;\n}\n\nint point::ByteSize() const\n{\n  int total_size = 0;\n\n  if (_has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    // required bytes hash = 1;\n    if (has_hash())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::BytesSize(\n                        this->hash());\n    }\n\n    // required uint32 index = 2;\n    if (has_index())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::UInt32Size(\n                        this->index());\n    }\n  }\n  if (!unknown_fields().empty())\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n            unknown_fields());\n  }\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = total_size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n  return total_size;\n}\n\nvoid point::MergeFrom(const ::google::protobuf::Message &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  const point *source =\n      ::google::protobuf::internal::dynamic_cast_if_available<const point *>(\n          &from);\n  if (source == NULL)\n  {\n    ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n  }\n  else\n  {\n    MergeFrom(*source);\n  }\n}\n\nvoid point::MergeFrom(const point &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    if (from.has_hash())\n    {\n      set_hash(from.hash());\n    }\n    if (from.has_index())\n    {\n      set_index(from.index());\n    }\n  }\n  mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n}\n\nvoid point::CopyFrom(const ::google::protobuf::Message &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nvoid point::CopyFrom(const point &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nbool point::IsInitialized() const\n{\n  if ((_has_bits_[0] & 0x00000003) != 0x00000003)\n    return false;\n\n  return true;\n}\n\nvoid point::Swap(point *other)\n{\n  if (other != this)\n  {\n    std::swap(hash_, other->hash_);\n    std::swap(index_, other->index_);\n    std::swap(_has_bits_[0], other->_has_bits_[0]);\n    _unknown_fields_.Swap(&other->_unknown_fields_);\n    std::swap(_cached_size_, other->_cached_size_);\n  }\n}\n\n::google::protobuf::Metadata point::GetMetadata() const\n{\n  protobuf_AssignDescriptorsOnce();\n  ::google::protobuf::Metadata metadata;\n  metadata.descriptor = point_descriptor_;\n  metadata.reflection = point_reflection_;\n  return metadata;\n}\n\n// ===================================================================\n\n#ifndef _MSC_VER\nconst int tx_input::kPreviousOutputFieldNumber;\nconst int tx_input::kScriptFieldNumber;\nconst int tx_input::kSequenceFieldNumber;\n#endif // !_MSC_VER\n\ntx_input::tx_input()\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  // @@protoc_insertion_point(constructor:libbitcoin.protocol.tx_input)\n}\n\nvoid tx_input::InitAsDefaultInstance()\n{\n  previous_output_ = const_cast<::libbitcoin::protocol::point *>(&::libbitcoin::protocol::point::default_instance());\n}\n\ntx_input::tx_input(const tx_input &from)\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  MergeFrom(from);\n  // @@protoc_insertion_point(copy_constructor:libbitcoin.protocol.tx_input)\n}\n\nvoid tx_input::SharedCtor()\n{\n  ::google::protobuf::internal::GetEmptyString();\n  _cached_size_ = 0;\n  previous_output_ = NULL;\n  script_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n  sequence_ = 0u;\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n}\n\ntx_input::~tx_input()\n{\n  // @@protoc_insertion_point(destructor:libbitcoin.protocol.tx_input)\n  SharedDtor();\n}\n\nvoid tx_input::SharedDtor()\n{\n  if (script_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    delete script_;\n  }\n  if (this != default_instance_)\n  {\n    delete previous_output_;\n  }\n}\n\nvoid tx_input::SetCachedSize(int size) const\n{\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n}\nconst ::google::protobuf::Descriptor *tx_input::descriptor()\n{\n  protobuf_AssignDescriptorsOnce();\n  return tx_input_descriptor_;\n}\n\nconst tx_input &tx_input::default_instance()\n{\n  if (default_instance_ == NULL)\n    protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  return *default_instance_;\n}\n\ntx_input *tx_input::default_instance_ = NULL;\n\ntx_input *tx_input::New() const\n{\n  return new tx_input;\n}\n\nvoid tx_input::Clear()\n{\n  if (_has_bits_[0 / 32] & 7)\n  {\n    if (has_previous_output())\n    {\n      if (previous_output_ != NULL)\n        previous_output_->::libbitcoin::protocol::point::Clear();\n    }\n    if (has_script())\n    {\n      if (script_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n      {\n        script_->clear();\n      }\n    }\n    sequence_ = 0u;\n  }\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n  mutable_unknown_fields()->Clear();\n}\n\nbool tx_input::MergePartialFromCodedStream(\n    ::google::protobuf::io::CodedInputStream *input)\n{\n#define DO_(EXPRESSION) \\\n  if (!(EXPRESSION))    \\\n  goto failure\n  ::google::protobuf::uint32 tag;\n  // @@protoc_insertion_point(parse_start:libbitcoin.protocol.tx_input)\n  for (;;)\n  {\n    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);\n    tag = p.first;\n    if (!p.second)\n      goto handle_unusual;\n    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag))\n    {\n    // required .libbitcoin.protocol.point previous_output = 1;\n    case 1:\n    {\n      if (tag == 10)\n      {\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, mutable_previous_output()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(18))\n        goto parse_script;\n      break;\n    }\n\n    // required bytes script = 2;\n    case 2:\n    {\n      if (tag == 18)\n      {\n      parse_script:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(\n            input, this->mutable_script()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(24))\n        goto parse_sequence;\n      break;\n    }\n\n    // required uint32 sequence = 3;\n    case 3:\n    {\n      if (tag == 24)\n      {\n      parse_sequence:\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(\n            input, &sequence_)));\n        set_has_sequence();\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectAtEnd())\n        goto success;\n      break;\n    }\n\n    default:\n    {\n    handle_unusual:\n      if (tag == 0 ||\n          ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n              ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP)\n      {\n        goto success;\n      }\n      DO_(::google::protobuf::internal::WireFormat::SkipField(\n          input, tag, mutable_unknown_fields()));\n      break;\n    }\n    }\n  }\nsuccess:\n  // @@protoc_insertion_point(parse_success:libbitcoin.protocol.tx_input)\n  return true;\nfailure:\n  // @@protoc_insertion_point(parse_failure:libbitcoin.protocol.tx_input)\n  return false;\n#undef DO_\n}\n\nvoid tx_input::SerializeWithCachedSizes(\n    ::google::protobuf::io::CodedOutputStream *output) const\n{\n  // @@protoc_insertion_point(serialize_start:libbitcoin.protocol.tx_input)\n  // required .libbitcoin.protocol.point previous_output = 1;\n  if (has_previous_output())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        1, this->previous_output(), output);\n  }\n\n  // required bytes script = 2;\n  if (has_script())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(\n        2, this->script(), output);\n  }\n\n  // required uint32 sequence = 3;\n  if (has_sequence())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->sequence(), output);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n        unknown_fields(), output);\n  }\n  // @@protoc_insertion_point(serialize_end:libbitcoin.protocol.tx_input)\n}\n\n::google::protobuf::uint8 *tx_input::SerializeWithCachedSizesToArray(\n    ::google::protobuf::uint8 *target) const\n{\n  // @@protoc_insertion_point(serialize_to_array_start:libbitcoin.protocol.tx_input)\n  // required .libbitcoin.protocol.point previous_output = 1;\n  if (has_previous_output())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            1, this->previous_output(), target);\n  }\n\n  // required bytes script = 2;\n  if (has_script())\n  {\n    target =\n        ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(\n            2, this->script(), target);\n  }\n\n  // required uint32 sequence = 3;\n  if (has_sequence())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(3, this->sequence(), target);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n        unknown_fields(), target);\n  }\n  // @@protoc_insertion_point(serialize_to_array_end:libbitcoin.protocol.tx_input)\n  return target;\n}\n\nint tx_input::ByteSize() const\n{\n  int total_size = 0;\n\n  if (_has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    // required .libbitcoin.protocol.point previous_output = 1;\n    if (has_previous_output())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n                        this->previous_output());\n    }\n\n    // required bytes script = 2;\n    if (has_script())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::BytesSize(\n                        this->script());\n    }\n\n    // required uint32 sequence = 3;\n    if (has_sequence())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::UInt32Size(\n                        this->sequence());\n    }\n  }\n  if (!unknown_fields().empty())\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n            unknown_fields());\n  }\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = total_size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n  return total_size;\n}\n\nvoid tx_input::MergeFrom(const ::google::protobuf::Message &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  const tx_input *source =\n      ::google::protobuf::internal::dynamic_cast_if_available<const tx_input *>(\n          &from);\n  if (source == NULL)\n  {\n    ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n  }\n  else\n  {\n    MergeFrom(*source);\n  }\n}\n\nvoid tx_input::MergeFrom(const tx_input &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    if (from.has_previous_output())\n    {\n      mutable_previous_output()->::libbitcoin::protocol::point::MergeFrom(from.previous_output());\n    }\n    if (from.has_script())\n    {\n      set_script(from.script());\n    }\n    if (from.has_sequence())\n    {\n      set_sequence(from.sequence());\n    }\n  }\n  mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n}\n\nvoid tx_input::CopyFrom(const ::google::protobuf::Message &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nvoid tx_input::CopyFrom(const tx_input &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nbool tx_input::IsInitialized() const\n{\n  if ((_has_bits_[0] & 0x00000007) != 0x00000007)\n    return false;\n\n  if (has_previous_output())\n  {\n    if (!this->previous_output().IsInitialized())\n      return false;\n  }\n  return true;\n}\n\nvoid tx_input::Swap(tx_input *other)\n{\n  if (other != this)\n  {\n    std::swap(previous_output_, other->previous_output_);\n    std::swap(script_, other->script_);\n    std::swap(sequence_, other->sequence_);\n    std::swap(_has_bits_[0], other->_has_bits_[0]);\n    _unknown_fields_.Swap(&other->_unknown_fields_);\n    std::swap(_cached_size_, other->_cached_size_);\n  }\n}\n\n::google::protobuf::Metadata tx_input::GetMetadata() const\n{\n  protobuf_AssignDescriptorsOnce();\n  ::google::protobuf::Metadata metadata;\n  metadata.descriptor = tx_input_descriptor_;\n  metadata.reflection = tx_input_reflection_;\n  return metadata;\n}\n\n// ===================================================================\n\n#ifndef _MSC_VER\nconst int tx_output::kValueFieldNumber;\nconst int tx_output::kScriptFieldNumber;\n#endif // !_MSC_VER\n\ntx_output::tx_output()\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  // @@protoc_insertion_point(constructor:libbitcoin.protocol.tx_output)\n}\n\nvoid tx_output::InitAsDefaultInstance()\n{\n}\n\ntx_output::tx_output(const tx_output &from)\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  MergeFrom(from);\n  // @@protoc_insertion_point(copy_constructor:libbitcoin.protocol.tx_output)\n}\n\nvoid tx_output::SharedCtor()\n{\n  ::google::protobuf::internal::GetEmptyString();\n  _cached_size_ = 0;\n  value_ = GOOGLE_ULONGLONG(0);\n  script_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n}\n\ntx_output::~tx_output()\n{\n  // @@protoc_insertion_point(destructor:libbitcoin.protocol.tx_output)\n  SharedDtor();\n}\n\nvoid tx_output::SharedDtor()\n{\n  if (script_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    delete script_;\n  }\n  if (this != default_instance_)\n  {\n  }\n}\n\nvoid tx_output::SetCachedSize(int size) const\n{\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n}\nconst ::google::protobuf::Descriptor *tx_output::descriptor()\n{\n  protobuf_AssignDescriptorsOnce();\n  return tx_output_descriptor_;\n}\n\nconst tx_output &tx_output::default_instance()\n{\n  if (default_instance_ == NULL)\n    protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  return *default_instance_;\n}\n\ntx_output *tx_output::default_instance_ = NULL;\n\ntx_output *tx_output::New() const\n{\n  return new tx_output;\n}\n\nvoid tx_output::Clear()\n{\n  if (_has_bits_[0 / 32] & 3)\n  {\n    value_ = GOOGLE_ULONGLONG(0);\n    if (has_script())\n    {\n      if (script_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n      {\n        script_->clear();\n      }\n    }\n  }\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n  mutable_unknown_fields()->Clear();\n}\n\nbool tx_output::MergePartialFromCodedStream(\n    ::google::protobuf::io::CodedInputStream *input)\n{\n#define DO_(EXPRESSION) \\\n  if (!(EXPRESSION))    \\\n  goto failure\n  ::google::protobuf::uint32 tag;\n  // @@protoc_insertion_point(parse_start:libbitcoin.protocol.tx_output)\n  for (;;)\n  {\n    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);\n    tag = p.first;\n    if (!p.second)\n      goto handle_unusual;\n    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag))\n    {\n    // required uint64 value = 1;\n    case 1:\n    {\n      if (tag == 8)\n      {\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(\n            input, &value_)));\n        set_has_value();\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(18))\n        goto parse_script;\n      break;\n    }\n\n    // required bytes script = 2;\n    case 2:\n    {\n      if (tag == 18)\n      {\n      parse_script:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(\n            input, this->mutable_script()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectAtEnd())\n        goto success;\n      break;\n    }\n\n    default:\n    {\n    handle_unusual:\n      if (tag == 0 ||\n          ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n              ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP)\n      {\n        goto success;\n      }\n      DO_(::google::protobuf::internal::WireFormat::SkipField(\n          input, tag, mutable_unknown_fields()));\n      break;\n    }\n    }\n  }\nsuccess:\n  // @@protoc_insertion_point(parse_success:libbitcoin.protocol.tx_output)\n  return true;\nfailure:\n  // @@protoc_insertion_point(parse_failure:libbitcoin.protocol.tx_output)\n  return false;\n#undef DO_\n}\n\nvoid tx_output::SerializeWithCachedSizes(\n    ::google::protobuf::io::CodedOutputStream *output) const\n{\n  // @@protoc_insertion_point(serialize_start:libbitcoin.protocol.tx_output)\n  // required uint64 value = 1;\n  if (has_value())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->value(), output);\n  }\n\n  // required bytes script = 2;\n  if (has_script())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(\n        2, this->script(), output);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n        unknown_fields(), output);\n  }\n  // @@protoc_insertion_point(serialize_end:libbitcoin.protocol.tx_output)\n}\n\n::google::protobuf::uint8 *tx_output::SerializeWithCachedSizesToArray(\n    ::google::protobuf::uint8 *target) const\n{\n  // @@protoc_insertion_point(serialize_to_array_start:libbitcoin.protocol.tx_output)\n  // required uint64 value = 1;\n  if (has_value())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->value(), target);\n  }\n\n  // required bytes script = 2;\n  if (has_script())\n  {\n    target =\n        ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(\n            2, this->script(), target);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n        unknown_fields(), target);\n  }\n  // @@protoc_insertion_point(serialize_to_array_end:libbitcoin.protocol.tx_output)\n  return target;\n}\n\nint tx_output::ByteSize() const\n{\n  int total_size = 0;\n\n  if (_has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    // required uint64 value = 1;\n    if (has_value())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::UInt64Size(\n                        this->value());\n    }\n\n    // required bytes script = 2;\n    if (has_script())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::BytesSize(\n                        this->script());\n    }\n  }\n  if (!unknown_fields().empty())\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n            unknown_fields());\n  }\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = total_size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n  return total_size;\n}\n\nvoid tx_output::MergeFrom(const ::google::protobuf::Message &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  const tx_output *source =\n      ::google::protobuf::internal::dynamic_cast_if_available<const tx_output *>(\n          &from);\n  if (source == NULL)\n  {\n    ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n  }\n  else\n  {\n    MergeFrom(*source);\n  }\n}\n\nvoid tx_output::MergeFrom(const tx_output &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    if (from.has_value())\n    {\n      set_value(from.value());\n    }\n    if (from.has_script())\n    {\n      set_script(from.script());\n    }\n  }\n  mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n}\n\nvoid tx_output::CopyFrom(const ::google::protobuf::Message &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nvoid tx_output::CopyFrom(const tx_output &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nbool tx_output::IsInitialized() const\n{\n  if ((_has_bits_[0] & 0x00000003) != 0x00000003)\n    return false;\n\n  return true;\n}\n\nvoid tx_output::Swap(tx_output *other)\n{\n  if (other != this)\n  {\n    std::swap(value_, other->value_);\n    std::swap(script_, other->script_);\n    std::swap(_has_bits_[0], other->_has_bits_[0]);\n    _unknown_fields_.Swap(&other->_unknown_fields_);\n    std::swap(_cached_size_, other->_cached_size_);\n  }\n}\n\n::google::protobuf::Metadata tx_output::GetMetadata() const\n{\n  protobuf_AssignDescriptorsOnce();\n  ::google::protobuf::Metadata metadata;\n  metadata.descriptor = tx_output_descriptor_;\n  metadata.reflection = tx_output_reflection_;\n  return metadata;\n}\n\n// ===================================================================\n\n#ifndef _MSC_VER\nconst int tx::kVersionFieldNumber;\nconst int tx::kLocktimeFieldNumber;\nconst int tx::kInputsFieldNumber;\nconst int tx::kOutputsFieldNumber;\n#endif // !_MSC_VER\n\ntx::tx()\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  // @@protoc_insertion_point(constructor:libbitcoin.protocol.tx)\n}\n\nvoid tx::InitAsDefaultInstance()\n{\n}\n\ntx::tx(const tx &from)\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  MergeFrom(from);\n  // @@protoc_insertion_point(copy_constructor:libbitcoin.protocol.tx)\n}\n\nvoid tx::SharedCtor()\n{\n  _cached_size_ = 0;\n  version_ = 0u;\n  locktime_ = 0u;\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n}\n\ntx::~tx()\n{\n  // @@protoc_insertion_point(destructor:libbitcoin.protocol.tx)\n  SharedDtor();\n}\n\nvoid tx::SharedDtor()\n{\n  if (this != default_instance_)\n  {\n  }\n}\n\nvoid tx::SetCachedSize(int size) const\n{\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n}\nconst ::google::protobuf::Descriptor *tx::descriptor()\n{\n  protobuf_AssignDescriptorsOnce();\n  return tx_descriptor_;\n}\n\nconst tx &tx::default_instance()\n{\n  if (default_instance_ == NULL)\n    protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  return *default_instance_;\n}\n\ntx *tx::default_instance_ = NULL;\n\ntx *tx::New() const\n{\n  return new tx;\n}\n\nvoid tx::Clear()\n{\n#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char *>(             \\\n                                 &reinterpret_cast<tx *>(16)->f) - \\\n                             reinterpret_cast<char *>(16))\n\n#define ZR_(first, last)                                  \\\n  do                                                      \\\n  {                                                       \\\n    size_t f = OFFSET_OF_FIELD_(first);                   \\\n    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \\\n    ::memset(&first, 0, n);                               \\\n  } while (0)\n\n  ZR_(version_, locktime_);\n\n#undef OFFSET_OF_FIELD_\n#undef ZR_\n\n  inputs_.Clear();\n  outputs_.Clear();\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n  mutable_unknown_fields()->Clear();\n}\n\nbool tx::MergePartialFromCodedStream(\n    ::google::protobuf::io::CodedInputStream *input)\n{\n#define DO_(EXPRESSION) \\\n  if (!(EXPRESSION))    \\\n  goto failure\n  ::google::protobuf::uint32 tag;\n  // @@protoc_insertion_point(parse_start:libbitcoin.protocol.tx)\n  for (;;)\n  {\n    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);\n    tag = p.first;\n    if (!p.second)\n      goto handle_unusual;\n    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag))\n    {\n    // required uint32 version = 1;\n    case 1:\n    {\n      if (tag == 8)\n      {\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(\n            input, &version_)));\n        set_has_version();\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(16))\n        goto parse_locktime;\n      break;\n    }\n\n    // required uint32 locktime = 2;\n    case 2:\n    {\n      if (tag == 16)\n      {\n      parse_locktime:\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(\n            input, &locktime_)));\n        set_has_locktime();\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(26))\n        goto parse_inputs;\n      break;\n    }\n\n    // repeated .libbitcoin.protocol.tx_input inputs = 3;\n    case 3:\n    {\n      if (tag == 26)\n      {\n      parse_inputs:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, add_inputs()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(26))\n        goto parse_inputs;\n      if (input->ExpectTag(34))\n        goto parse_outputs;\n      break;\n    }\n\n    // repeated .libbitcoin.protocol.tx_output outputs = 4;\n    case 4:\n    {\n      if (tag == 34)\n      {\n      parse_outputs:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, add_outputs()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(34))\n        goto parse_outputs;\n      if (input->ExpectAtEnd())\n        goto success;\n      break;\n    }\n\n    default:\n    {\n    handle_unusual:\n      if (tag == 0 ||\n          ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n              ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP)\n      {\n        goto success;\n      }\n      DO_(::google::protobuf::internal::WireFormat::SkipField(\n          input, tag, mutable_unknown_fields()));\n      break;\n    }\n    }\n  }\nsuccess:\n  // @@protoc_insertion_point(parse_success:libbitcoin.protocol.tx)\n  return true;\nfailure:\n  // @@protoc_insertion_point(parse_failure:libbitcoin.protocol.tx)\n  return false;\n#undef DO_\n}\n\nvoid tx::SerializeWithCachedSizes(\n    ::google::protobuf::io::CodedOutputStream *output) const\n{\n  // @@protoc_insertion_point(serialize_start:libbitcoin.protocol.tx)\n  // required uint32 version = 1;\n  if (has_version())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->version(), output);\n  }\n\n  // required uint32 locktime = 2;\n  if (has_locktime())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->locktime(), output);\n  }\n\n  // repeated .libbitcoin.protocol.tx_input inputs = 3;\n  for (int i = 0; i < this->inputs_size(); i++)\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        3, this->inputs(i), output);\n  }\n\n  // repeated .libbitcoin.protocol.tx_output outputs = 4;\n  for (int i = 0; i < this->outputs_size(); i++)\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        4, this->outputs(i), output);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n        unknown_fields(), output);\n  }\n  // @@protoc_insertion_point(serialize_end:libbitcoin.protocol.tx)\n}\n\n::google::protobuf::uint8 *tx::SerializeWithCachedSizesToArray(\n    ::google::protobuf::uint8 *target) const\n{\n  // @@protoc_insertion_point(serialize_to_array_start:libbitcoin.protocol.tx)\n  // required uint32 version = 1;\n  if (has_version())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->version(), target);\n  }\n\n  // required uint32 locktime = 2;\n  if (has_locktime())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->locktime(), target);\n  }\n\n  // repeated .libbitcoin.protocol.tx_input inputs = 3;\n  for (int i = 0; i < this->inputs_size(); i++)\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            3, this->inputs(i), target);\n  }\n\n  // repeated .libbitcoin.protocol.tx_output outputs = 4;\n  for (int i = 0; i < this->outputs_size(); i++)\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            4, this->outputs(i), target);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n        unknown_fields(), target);\n  }\n  // @@protoc_insertion_point(serialize_to_array_end:libbitcoin.protocol.tx)\n  return target;\n}\n\nint tx::ByteSize() const\n{\n  int total_size = 0;\n\n  if (_has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    // required uint32 version = 1;\n    if (has_version())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::UInt32Size(\n                        this->version());\n    }\n\n    // required uint32 locktime = 2;\n    if (has_locktime())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::UInt32Size(\n                        this->locktime());\n    }\n  }\n  // repeated .libbitcoin.protocol.tx_input inputs = 3;\n  total_size += 1 * this->inputs_size();\n  for (int i = 0; i < this->inputs_size(); i++)\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n            this->inputs(i));\n  }\n\n  // repeated .libbitcoin.protocol.tx_output outputs = 4;\n  total_size += 1 * this->outputs_size();\n  for (int i = 0; i < this->outputs_size(); i++)\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n            this->outputs(i));\n  }\n\n  if (!unknown_fields().empty())\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n            unknown_fields());\n  }\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = total_size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n  return total_size;\n}\n\nvoid tx::MergeFrom(const ::google::protobuf::Message &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  const tx *source =\n      ::google::protobuf::internal::dynamic_cast_if_available<const tx *>(\n          &from);\n  if (source == NULL)\n  {\n    ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n  }\n  else\n  {\n    MergeFrom(*source);\n  }\n}\n\nvoid tx::MergeFrom(const tx &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  inputs_.MergeFrom(from.inputs_);\n  outputs_.MergeFrom(from.outputs_);\n  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    if (from.has_version())\n    {\n      set_version(from.version());\n    }\n    if (from.has_locktime())\n    {\n      set_locktime(from.locktime());\n    }\n  }\n  mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n}\n\nvoid tx::CopyFrom(const ::google::protobuf::Message &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nvoid tx::CopyFrom(const tx &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nbool tx::IsInitialized() const\n{\n  if ((_has_bits_[0] & 0x00000003) != 0x00000003)\n    return false;\n\n  if (!::google::protobuf::internal::AllAreInitialized(this->inputs()))\n    return false;\n  if (!::google::protobuf::internal::AllAreInitialized(this->outputs()))\n    return false;\n  return true;\n}\n\nvoid tx::Swap(tx *other)\n{\n  if (other != this)\n  {\n    std::swap(version_, other->version_);\n    std::swap(locktime_, other->locktime_);\n    inputs_.Swap(&other->inputs_);\n    outputs_.Swap(&other->outputs_);\n    std::swap(_has_bits_[0], other->_has_bits_[0]);\n    _unknown_fields_.Swap(&other->_unknown_fields_);\n    std::swap(_cached_size_, other->_cached_size_);\n  }\n}\n\n::google::protobuf::Metadata tx::GetMetadata() const\n{\n  protobuf_AssignDescriptorsOnce();\n  ::google::protobuf::Metadata metadata;\n  metadata.descriptor = tx_descriptor_;\n  metadata.reflection = tx_reflection_;\n  return metadata;\n}\n\n// ===================================================================\n\n#ifndef _MSC_VER\nconst int block::kHeaderFieldNumber;\nconst int block::kTransactionsFieldNumber;\nconst int block::kTreeFieldNumber;\n#endif // !_MSC_VER\n\nblock::block()\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  // @@protoc_insertion_point(constructor:libbitcoin.protocol.block)\n}\n\nvoid block::InitAsDefaultInstance()\n{\n  header_ = const_cast<::libbitcoin::protocol::block_header *>(&::libbitcoin::protocol::block_header::default_instance());\n}\n\nblock::block(const block &from)\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  MergeFrom(from);\n  // @@protoc_insertion_point(copy_constructor:libbitcoin.protocol.block)\n}\n\nvoid block::SharedCtor()\n{\n  ::google::protobuf::internal::GetEmptyString();\n  _cached_size_ = 0;\n  header_ = NULL;\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n}\n\nblock::~block()\n{\n  // @@protoc_insertion_point(destructor:libbitcoin.protocol.block)\n  SharedDtor();\n}\n\nvoid block::SharedDtor()\n{\n  if (this != default_instance_)\n  {\n    delete header_;\n  }\n}\n\nvoid block::SetCachedSize(int size) const\n{\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n}\nconst ::google::protobuf::Descriptor *block::descriptor()\n{\n  protobuf_AssignDescriptorsOnce();\n  return block_descriptor_;\n}\n\nconst block &block::default_instance()\n{\n  if (default_instance_ == NULL)\n    protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  return *default_instance_;\n}\n\nblock *block::default_instance_ = NULL;\n\nblock *block::New() const\n{\n  return new block;\n}\n\nvoid block::Clear()\n{\n  if (has_header())\n  {\n    if (header_ != NULL)\n      header_->::libbitcoin::protocol::block_header::Clear();\n  }\n  transactions_.Clear();\n  tree_.Clear();\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n  mutable_unknown_fields()->Clear();\n}\n\nbool block::MergePartialFromCodedStream(\n    ::google::protobuf::io::CodedInputStream *input)\n{\n#define DO_(EXPRESSION) \\\n  if (!(EXPRESSION))    \\\n  goto failure\n  ::google::protobuf::uint32 tag;\n  // @@protoc_insertion_point(parse_start:libbitcoin.protocol.block)\n  for (;;)\n  {\n    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);\n    tag = p.first;\n    if (!p.second)\n      goto handle_unusual;\n    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag))\n    {\n    // required .libbitcoin.protocol.block_header header = 1;\n    case 1:\n    {\n      if (tag == 10)\n      {\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, mutable_header()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(18))\n        goto parse_transactions;\n      break;\n    }\n\n    // repeated .libbitcoin.protocol.tx transactions = 2;\n    case 2:\n    {\n      if (tag == 18)\n      {\n      parse_transactions:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, add_transactions()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(18))\n        goto parse_transactions;\n      if (input->ExpectTag(26))\n        goto parse_tree;\n      break;\n    }\n\n    // repeated bytes tree = 3;\n    case 3:\n    {\n      if (tag == 26)\n      {\n      parse_tree:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(\n            input, this->add_tree()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(26))\n        goto parse_tree;\n      if (input->ExpectAtEnd())\n        goto success;\n      break;\n    }\n\n    default:\n    {\n    handle_unusual:\n      if (tag == 0 ||\n          ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n              ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP)\n      {\n        goto success;\n      }\n      DO_(::google::protobuf::internal::WireFormat::SkipField(\n          input, tag, mutable_unknown_fields()));\n      break;\n    }\n    }\n  }\nsuccess:\n  // @@protoc_insertion_point(parse_success:libbitcoin.protocol.block)\n  return true;\nfailure:\n  // @@protoc_insertion_point(parse_failure:libbitcoin.protocol.block)\n  return false;\n#undef DO_\n}\n\nvoid block::SerializeWithCachedSizes(\n    ::google::protobuf::io::CodedOutputStream *output) const\n{\n  // @@protoc_insertion_point(serialize_start:libbitcoin.protocol.block)\n  // required .libbitcoin.protocol.block_header header = 1;\n  if (has_header())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        1, this->header(), output);\n  }\n\n  // repeated .libbitcoin.protocol.tx transactions = 2;\n  for (int i = 0; i < this->transactions_size(); i++)\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        2, this->transactions(i), output);\n  }\n\n  // repeated bytes tree = 3;\n  for (int i = 0; i < this->tree_size(); i++)\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteBytes(\n        3, this->tree(i), output);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n        unknown_fields(), output);\n  }\n  // @@protoc_insertion_point(serialize_end:libbitcoin.protocol.block)\n}\n\n::google::protobuf::uint8 *block::SerializeWithCachedSizesToArray(\n    ::google::protobuf::uint8 *target) const\n{\n  // @@protoc_insertion_point(serialize_to_array_start:libbitcoin.protocol.block)\n  // required .libbitcoin.protocol.block_header header = 1;\n  if (has_header())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            1, this->header(), target);\n  }\n\n  // repeated .libbitcoin.protocol.tx transactions = 2;\n  for (int i = 0; i < this->transactions_size(); i++)\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            2, this->transactions(i), target);\n  }\n\n  // repeated bytes tree = 3;\n  for (int i = 0; i < this->tree_size(); i++)\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteBytesToArray(3, this->tree(i), target);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n        unknown_fields(), target);\n  }\n  // @@protoc_insertion_point(serialize_to_array_end:libbitcoin.protocol.block)\n  return target;\n}\n\nint block::ByteSize() const\n{\n  int total_size = 0;\n\n  if (_has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    // required .libbitcoin.protocol.block_header header = 1;\n    if (has_header())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n                        this->header());\n    }\n  }\n  // repeated .libbitcoin.protocol.tx transactions = 2;\n  total_size += 1 * this->transactions_size();\n  for (int i = 0; i < this->transactions_size(); i++)\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n            this->transactions(i));\n  }\n\n  // repeated bytes tree = 3;\n  total_size += 1 * this->tree_size();\n  for (int i = 0; i < this->tree_size(); i++)\n  {\n    total_size += ::google::protobuf::internal::WireFormatLite::BytesSize(\n        this->tree(i));\n  }\n\n  if (!unknown_fields().empty())\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n            unknown_fields());\n  }\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = total_size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n  return total_size;\n}\n\nvoid block::MergeFrom(const ::google::protobuf::Message &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  const block *source =\n      ::google::protobuf::internal::dynamic_cast_if_available<const block *>(\n          &from);\n  if (source == NULL)\n  {\n    ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n  }\n  else\n  {\n    MergeFrom(*source);\n  }\n}\n\nvoid block::MergeFrom(const block &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  transactions_.MergeFrom(from.transactions_);\n  tree_.MergeFrom(from.tree_);\n  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    if (from.has_header())\n    {\n      mutable_header()->::libbitcoin::protocol::block_header::MergeFrom(from.header());\n    }\n  }\n  mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n}\n\nvoid block::CopyFrom(const ::google::protobuf::Message &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nvoid block::CopyFrom(const block &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nbool block::IsInitialized() const\n{\n  if ((_has_bits_[0] & 0x00000001) != 0x00000001)\n    return false;\n\n  if (has_header())\n  {\n    if (!this->header().IsInitialized())\n      return false;\n  }\n  if (!::google::protobuf::internal::AllAreInitialized(this->transactions()))\n    return false;\n  return true;\n}\n\nvoid block::Swap(block *other)\n{\n  if (other != this)\n  {\n    std::swap(header_, other->header_);\n    transactions_.Swap(&other->transactions_);\n    tree_.Swap(&other->tree_);\n    std::swap(_has_bits_[0], other->_has_bits_[0]);\n    _unknown_fields_.Swap(&other->_unknown_fields_);\n    std::swap(_cached_size_, other->_cached_size_);\n  }\n}\n\n::google::protobuf::Metadata block::GetMetadata() const\n{\n  protobuf_AssignDescriptorsOnce();\n  ::google::protobuf::Metadata metadata;\n  metadata.descriptor = block_descriptor_;\n  metadata.reflection = block_reflection_;\n  return metadata;\n}\n\n// ===================================================================\n\n#ifndef _MSC_VER\nconst int filter::kFilterTypeFieldNumber;\nconst int filter::kBitsFieldNumber;\nconst int filter::kPrefixFieldNumber;\n#endif // !_MSC_VER\n\nfilter::filter()\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  // @@protoc_insertion_point(constructor:libbitcoin.protocol.filter)\n}\n\nvoid filter::InitAsDefaultInstance()\n{\n}\n\nfilter::filter(const filter &from)\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  MergeFrom(from);\n  // @@protoc_insertion_point(copy_constructor:libbitcoin.protocol.filter)\n}\n\nvoid filter::SharedCtor()\n{\n  ::google::protobuf::internal::GetEmptyString();\n  _cached_size_ = 0;\n  filter_type_ = 1;\n  bits_ = 0u;\n  prefix_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n}\n\nfilter::~filter()\n{\n  // @@protoc_insertion_point(destructor:libbitcoin.protocol.filter)\n  SharedDtor();\n}\n\nvoid filter::SharedDtor()\n{\n  if (prefix_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    delete prefix_;\n  }\n  if (this != default_instance_)\n  {\n  }\n}\n\nvoid filter::SetCachedSize(int size) const\n{\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n}\nconst ::google::protobuf::Descriptor *filter::descriptor()\n{\n  protobuf_AssignDescriptorsOnce();\n  return filter_descriptor_;\n}\n\nconst filter &filter::default_instance()\n{\n  if (default_instance_ == NULL)\n    protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  return *default_instance_;\n}\n\nfilter *filter::default_instance_ = NULL;\n\nfilter *filter::New() const\n{\n  return new filter;\n}\n\nvoid filter::Clear()\n{\n  if (_has_bits_[0 / 32] & 7)\n  {\n    filter_type_ = 1;\n    bits_ = 0u;\n    if (has_prefix())\n    {\n      if (prefix_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n      {\n        prefix_->clear();\n      }\n    }\n  }\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n  mutable_unknown_fields()->Clear();\n}\n\nbool filter::MergePartialFromCodedStream(\n    ::google::protobuf::io::CodedInputStream *input)\n{\n#define DO_(EXPRESSION) \\\n  if (!(EXPRESSION))    \\\n  goto failure\n  ::google::protobuf::uint32 tag;\n  // @@protoc_insertion_point(parse_start:libbitcoin.protocol.filter)\n  for (;;)\n  {\n    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);\n    tag = p.first;\n    if (!p.second)\n      goto handle_unusual;\n    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag))\n    {\n    // required .libbitcoin.protocol.filters filter_type = 1;\n    case 1:\n    {\n      if (tag == 8)\n      {\n        int value;\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n            input, &value)));\n        if (::libbitcoin::protocol::filters_IsValid(value))\n        {\n          set_filter_type(static_cast<::libbitcoin::protocol::filters>(value));\n        }\n        else\n        {\n          mutable_unknown_fields()->AddVarint(1, value);\n        }\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(16))\n        goto parse_bits;\n      break;\n    }\n\n    // optional uint32 bits = 2;\n    case 2:\n    {\n      if (tag == 16)\n      {\n      parse_bits:\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(\n            input, &bits_)));\n        set_has_bits();\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(26))\n        goto parse_prefix;\n      break;\n    }\n\n    // required bytes prefix = 3;\n    case 3:\n    {\n      if (tag == 26)\n      {\n      parse_prefix:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(\n            input, this->mutable_prefix()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectAtEnd())\n        goto success;\n      break;\n    }\n\n    default:\n    {\n    handle_unusual:\n      if (tag == 0 ||\n          ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n              ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP)\n      {\n        goto success;\n      }\n      DO_(::google::protobuf::internal::WireFormat::SkipField(\n          input, tag, mutable_unknown_fields()));\n      break;\n    }\n    }\n  }\nsuccess:\n  // @@protoc_insertion_point(parse_success:libbitcoin.protocol.filter)\n  return true;\nfailure:\n  // @@protoc_insertion_point(parse_failure:libbitcoin.protocol.filter)\n  return false;\n#undef DO_\n}\n\nvoid filter::SerializeWithCachedSizes(\n    ::google::protobuf::io::CodedOutputStream *output) const\n{\n  // @@protoc_insertion_point(serialize_start:libbitcoin.protocol.filter)\n  // required .libbitcoin.protocol.filters filter_type = 1;\n  if (has_filter_type())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteEnum(\n        1, this->filter_type(), output);\n  }\n\n  // optional uint32 bits = 2;\n  if (has_bits())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->bits(), output);\n  }\n\n  // required bytes prefix = 3;\n  if (has_prefix())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(\n        3, this->prefix(), output);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n        unknown_fields(), output);\n  }\n  // @@protoc_insertion_point(serialize_end:libbitcoin.protocol.filter)\n}\n\n::google::protobuf::uint8 *filter::SerializeWithCachedSizesToArray(\n    ::google::protobuf::uint8 *target) const\n{\n  // @@protoc_insertion_point(serialize_to_array_start:libbitcoin.protocol.filter)\n  // required .libbitcoin.protocol.filters filter_type = 1;\n  if (has_filter_type())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(\n        1, this->filter_type(), target);\n  }\n\n  // optional uint32 bits = 2;\n  if (has_bits())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->bits(), target);\n  }\n\n  // required bytes prefix = 3;\n  if (has_prefix())\n  {\n    target =\n        ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(\n            3, this->prefix(), target);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n        unknown_fields(), target);\n  }\n  // @@protoc_insertion_point(serialize_to_array_end:libbitcoin.protocol.filter)\n  return target;\n}\n\nint filter::ByteSize() const\n{\n  int total_size = 0;\n\n  if (_has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    // required .libbitcoin.protocol.filters filter_type = 1;\n    if (has_filter_type())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::EnumSize(this->filter_type());\n    }\n\n    // optional uint32 bits = 2;\n    if (has_bits())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::UInt32Size(\n                        this->bits());\n    }\n\n    // required bytes prefix = 3;\n    if (has_prefix())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::BytesSize(\n                        this->prefix());\n    }\n  }\n  if (!unknown_fields().empty())\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n            unknown_fields());\n  }\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = total_size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n  return total_size;\n}\n\nvoid filter::MergeFrom(const ::google::protobuf::Message &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  const filter *source =\n      ::google::protobuf::internal::dynamic_cast_if_available<const filter *>(\n          &from);\n  if (source == NULL)\n  {\n    ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n  }\n  else\n  {\n    MergeFrom(*source);\n  }\n}\n\nvoid filter::MergeFrom(const filter &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    if (from.has_filter_type())\n    {\n      set_filter_type(from.filter_type());\n    }\n    if (from.has_bits())\n    {\n      set_bits(from.bits());\n    }\n    if (from.has_prefix())\n    {\n      set_prefix(from.prefix());\n    }\n  }\n  mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n}\n\nvoid filter::CopyFrom(const ::google::protobuf::Message &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nvoid filter::CopyFrom(const filter &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nbool filter::IsInitialized() const\n{\n  if ((_has_bits_[0] & 0x00000005) != 0x00000005)\n    return false;\n\n  return true;\n}\n\nvoid filter::Swap(filter *other)\n{\n  if (other != this)\n  {\n    std::swap(filter_type_, other->filter_type_);\n    std::swap(bits_, other->bits_);\n    std::swap(prefix_, other->prefix_);\n    std::swap(_has_bits_[0], other->_has_bits_[0]);\n    _unknown_fields_.Swap(&other->_unknown_fields_);\n    std::swap(_cached_size_, other->_cached_size_);\n  }\n}\n\n::google::protobuf::Metadata filter::GetMetadata() const\n{\n  protobuf_AssignDescriptorsOnce();\n  ::google::protobuf::Metadata metadata;\n  metadata.descriptor = filter_descriptor_;\n  metadata.reflection = filter_reflection_;\n  return metadata;\n}\n\n// ===================================================================\n\n#ifndef _MSC_VER\nconst int block_id::kHeightFieldNumber;\nconst int block_id::kHashFieldNumber;\n#endif // !_MSC_VER\n\nblock_id::block_id()\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  // @@protoc_insertion_point(constructor:libbitcoin.protocol.block_id)\n}\n\nvoid block_id::InitAsDefaultInstance()\n{\n}\n\nblock_id::block_id(const block_id &from)\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  MergeFrom(from);\n  // @@protoc_insertion_point(copy_constructor:libbitcoin.protocol.block_id)\n}\n\nvoid block_id::SharedCtor()\n{\n  ::google::protobuf::internal::GetEmptyString();\n  _cached_size_ = 0;\n  height_ = 0u;\n  hash_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n}\n\nblock_id::~block_id()\n{\n  // @@protoc_insertion_point(destructor:libbitcoin.protocol.block_id)\n  SharedDtor();\n}\n\nvoid block_id::SharedDtor()\n{\n  if (hash_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    delete hash_;\n  }\n  if (this != default_instance_)\n  {\n  }\n}\n\nvoid block_id::SetCachedSize(int size) const\n{\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n}\nconst ::google::protobuf::Descriptor *block_id::descriptor()\n{\n  protobuf_AssignDescriptorsOnce();\n  return block_id_descriptor_;\n}\n\nconst block_id &block_id::default_instance()\n{\n  if (default_instance_ == NULL)\n    protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  return *default_instance_;\n}\n\nblock_id *block_id::default_instance_ = NULL;\n\nblock_id *block_id::New() const\n{\n  return new block_id;\n}\n\nvoid block_id::Clear()\n{\n  if (_has_bits_[0 / 32] & 3)\n  {\n    height_ = 0u;\n    if (has_hash())\n    {\n      if (hash_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n      {\n        hash_->clear();\n      }\n    }\n  }\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n  mutable_unknown_fields()->Clear();\n}\n\nbool block_id::MergePartialFromCodedStream(\n    ::google::protobuf::io::CodedInputStream *input)\n{\n#define DO_(EXPRESSION) \\\n  if (!(EXPRESSION))    \\\n  goto failure\n  ::google::protobuf::uint32 tag;\n  // @@protoc_insertion_point(parse_start:libbitcoin.protocol.block_id)\n  for (;;)\n  {\n    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);\n    tag = p.first;\n    if (!p.second)\n      goto handle_unusual;\n    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag))\n    {\n    // optional uint32 height = 1;\n    case 1:\n    {\n      if (tag == 8)\n      {\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(\n            input, &height_)));\n        set_has_height();\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(18))\n        goto parse_hash;\n      break;\n    }\n\n    // optional bytes hash = 2;\n    case 2:\n    {\n      if (tag == 18)\n      {\n      parse_hash:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(\n            input, this->mutable_hash()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectAtEnd())\n        goto success;\n      break;\n    }\n\n    default:\n    {\n    handle_unusual:\n      if (tag == 0 ||\n          ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n              ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP)\n      {\n        goto success;\n      }\n      DO_(::google::protobuf::internal::WireFormat::SkipField(\n          input, tag, mutable_unknown_fields()));\n      break;\n    }\n    }\n  }\nsuccess:\n  // @@protoc_insertion_point(parse_success:libbitcoin.protocol.block_id)\n  return true;\nfailure:\n  // @@protoc_insertion_point(parse_failure:libbitcoin.protocol.block_id)\n  return false;\n#undef DO_\n}\n\nvoid block_id::SerializeWithCachedSizes(\n    ::google::protobuf::io::CodedOutputStream *output) const\n{\n  // @@protoc_insertion_point(serialize_start:libbitcoin.protocol.block_id)\n  // optional uint32 height = 1;\n  if (has_height())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->height(), output);\n  }\n\n  // optional bytes hash = 2;\n  if (has_hash())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(\n        2, this->hash(), output);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n        unknown_fields(), output);\n  }\n  // @@protoc_insertion_point(serialize_end:libbitcoin.protocol.block_id)\n}\n\n::google::protobuf::uint8 *block_id::SerializeWithCachedSizesToArray(\n    ::google::protobuf::uint8 *target) const\n{\n  // @@protoc_insertion_point(serialize_to_array_start:libbitcoin.protocol.block_id)\n  // optional uint32 height = 1;\n  if (has_height())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->height(), target);\n  }\n\n  // optional bytes hash = 2;\n  if (has_hash())\n  {\n    target =\n        ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(\n            2, this->hash(), target);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n        unknown_fields(), target);\n  }\n  // @@protoc_insertion_point(serialize_to_array_end:libbitcoin.protocol.block_id)\n  return target;\n}\n\nint block_id::ByteSize() const\n{\n  int total_size = 0;\n\n  if (_has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    // optional uint32 height = 1;\n    if (has_height())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::UInt32Size(\n                        this->height());\n    }\n\n    // optional bytes hash = 2;\n    if (has_hash())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::BytesSize(\n                        this->hash());\n    }\n  }\n  if (!unknown_fields().empty())\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n            unknown_fields());\n  }\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = total_size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n  return total_size;\n}\n\nvoid block_id::MergeFrom(const ::google::protobuf::Message &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  const block_id *source =\n      ::google::protobuf::internal::dynamic_cast_if_available<const block_id *>(\n          &from);\n  if (source == NULL)\n  {\n    ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n  }\n  else\n  {\n    MergeFrom(*source);\n  }\n}\n\nvoid block_id::MergeFrom(const block_id &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    if (from.has_height())\n    {\n      set_height(from.height());\n    }\n    if (from.has_hash())\n    {\n      set_hash(from.hash());\n    }\n  }\n  mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n}\n\nvoid block_id::CopyFrom(const ::google::protobuf::Message &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nvoid block_id::CopyFrom(const block_id &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nbool block_id::IsInitialized() const\n{\n\n  return true;\n}\n\nvoid block_id::Swap(block_id *other)\n{\n  if (other != this)\n  {\n    std::swap(height_, other->height_);\n    std::swap(hash_, other->hash_);\n    std::swap(_has_bits_[0], other->_has_bits_[0]);\n    _unknown_fields_.Swap(&other->_unknown_fields_);\n    std::swap(_cached_size_, other->_cached_size_);\n  }\n}\n\n::google::protobuf::Metadata block_id::GetMetadata() const\n{\n  protobuf_AssignDescriptorsOnce();\n  ::google::protobuf::Metadata metadata;\n  metadata.descriptor = block_id_descriptor_;\n  metadata.reflection = block_id_reflection_;\n  return metadata;\n}\n\n// ===================================================================\n\n#ifndef _MSC_VER\nconst int block_location::kIdentityFieldNumber;\nconst int block_location::kIndexFieldNumber;\nconst int block_location::kBranchFieldNumber;\n#endif // !_MSC_VER\n\nblock_location::block_location()\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  // @@protoc_insertion_point(constructor:libbitcoin.protocol.block_location)\n}\n\nvoid block_location::InitAsDefaultInstance()\n{\n  identity_ = const_cast<::libbitcoin::protocol::block_id *>(&::libbitcoin::protocol::block_id::default_instance());\n}\n\nblock_location::block_location(const block_location &from)\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  MergeFrom(from);\n  // @@protoc_insertion_point(copy_constructor:libbitcoin.protocol.block_location)\n}\n\nvoid block_location::SharedCtor()\n{\n  ::google::protobuf::internal::GetEmptyString();\n  _cached_size_ = 0;\n  identity_ = NULL;\n  index_ = GOOGLE_ULONGLONG(0);\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n}\n\nblock_location::~block_location()\n{\n  // @@protoc_insertion_point(destructor:libbitcoin.protocol.block_location)\n  SharedDtor();\n}\n\nvoid block_location::SharedDtor()\n{\n  if (this != default_instance_)\n  {\n    delete identity_;\n  }\n}\n\nvoid block_location::SetCachedSize(int size) const\n{\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n}\nconst ::google::protobuf::Descriptor *block_location::descriptor()\n{\n  protobuf_AssignDescriptorsOnce();\n  return block_location_descriptor_;\n}\n\nconst block_location &block_location::default_instance()\n{\n  if (default_instance_ == NULL)\n    protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  return *default_instance_;\n}\n\nblock_location *block_location::default_instance_ = NULL;\n\nblock_location *block_location::New() const\n{\n  return new block_location;\n}\n\nvoid block_location::Clear()\n{\n  if (_has_bits_[0 / 32] & 3)\n  {\n    if (has_identity())\n    {\n      if (identity_ != NULL)\n        identity_->::libbitcoin::protocol::block_id::Clear();\n    }\n    index_ = GOOGLE_ULONGLONG(0);\n  }\n  branch_.Clear();\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n  mutable_unknown_fields()->Clear();\n}\n\nbool block_location::MergePartialFromCodedStream(\n    ::google::protobuf::io::CodedInputStream *input)\n{\n#define DO_(EXPRESSION) \\\n  if (!(EXPRESSION))    \\\n  goto failure\n  ::google::protobuf::uint32 tag;\n  // @@protoc_insertion_point(parse_start:libbitcoin.protocol.block_location)\n  for (;;)\n  {\n    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);\n    tag = p.first;\n    if (!p.second)\n      goto handle_unusual;\n    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag))\n    {\n    // optional .libbitcoin.protocol.block_id identity = 1;\n    case 1:\n    {\n      if (tag == 10)\n      {\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, mutable_identity()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(16))\n        goto parse_index;\n      break;\n    }\n\n    // optional uint64 index = 2;\n    case 2:\n    {\n      if (tag == 16)\n      {\n      parse_index:\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(\n            input, &index_)));\n        set_has_index();\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(26))\n        goto parse_branch;\n      break;\n    }\n\n    // repeated bytes branch = 3;\n    case 3:\n    {\n      if (tag == 26)\n      {\n      parse_branch:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(\n            input, this->add_branch()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(26))\n        goto parse_branch;\n      if (input->ExpectAtEnd())\n        goto success;\n      break;\n    }\n\n    default:\n    {\n    handle_unusual:\n      if (tag == 0 ||\n          ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n              ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP)\n      {\n        goto success;\n      }\n      DO_(::google::protobuf::internal::WireFormat::SkipField(\n          input, tag, mutable_unknown_fields()));\n      break;\n    }\n    }\n  }\nsuccess:\n  // @@protoc_insertion_point(parse_success:libbitcoin.protocol.block_location)\n  return true;\nfailure:\n  // @@protoc_insertion_point(parse_failure:libbitcoin.protocol.block_location)\n  return false;\n#undef DO_\n}\n\nvoid block_location::SerializeWithCachedSizes(\n    ::google::protobuf::io::CodedOutputStream *output) const\n{\n  // @@protoc_insertion_point(serialize_start:libbitcoin.protocol.block_location)\n  // optional .libbitcoin.protocol.block_id identity = 1;\n  if (has_identity())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        1, this->identity(), output);\n  }\n\n  // optional uint64 index = 2;\n  if (has_index())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->index(), output);\n  }\n\n  // repeated bytes branch = 3;\n  for (int i = 0; i < this->branch_size(); i++)\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteBytes(\n        3, this->branch(i), output);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n        unknown_fields(), output);\n  }\n  // @@protoc_insertion_point(serialize_end:libbitcoin.protocol.block_location)\n}\n\n::google::protobuf::uint8 *block_location::SerializeWithCachedSizesToArray(\n    ::google::protobuf::uint8 *target) const\n{\n  // @@protoc_insertion_point(serialize_to_array_start:libbitcoin.protocol.block_location)\n  // optional .libbitcoin.protocol.block_id identity = 1;\n  if (has_identity())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            1, this->identity(), target);\n  }\n\n  // optional uint64 index = 2;\n  if (has_index())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(2, this->index(), target);\n  }\n\n  // repeated bytes branch = 3;\n  for (int i = 0; i < this->branch_size(); i++)\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteBytesToArray(3, this->branch(i), target);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n        unknown_fields(), target);\n  }\n  // @@protoc_insertion_point(serialize_to_array_end:libbitcoin.protocol.block_location)\n  return target;\n}\n\nint block_location::ByteSize() const\n{\n  int total_size = 0;\n\n  if (_has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    // optional .libbitcoin.protocol.block_id identity = 1;\n    if (has_identity())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n                        this->identity());\n    }\n\n    // optional uint64 index = 2;\n    if (has_index())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::UInt64Size(\n                        this->index());\n    }\n  }\n  // repeated bytes branch = 3;\n  total_size += 1 * this->branch_size();\n  for (int i = 0; i < this->branch_size(); i++)\n  {\n    total_size += ::google::protobuf::internal::WireFormatLite::BytesSize(\n        this->branch(i));\n  }\n\n  if (!unknown_fields().empty())\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n            unknown_fields());\n  }\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = total_size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n  return total_size;\n}\n\nvoid block_location::MergeFrom(const ::google::protobuf::Message &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  const block_location *source =\n      ::google::protobuf::internal::dynamic_cast_if_available<const block_location *>(\n          &from);\n  if (source == NULL)\n  {\n    ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n  }\n  else\n  {\n    MergeFrom(*source);\n  }\n}\n\nvoid block_location::MergeFrom(const block_location &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  branch_.MergeFrom(from.branch_);\n  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    if (from.has_identity())\n    {\n      mutable_identity()->::libbitcoin::protocol::block_id::MergeFrom(from.identity());\n    }\n    if (from.has_index())\n    {\n      set_index(from.index());\n    }\n  }\n  mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n}\n\nvoid block_location::CopyFrom(const ::google::protobuf::Message &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nvoid block_location::CopyFrom(const block_location &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nbool block_location::IsInitialized() const\n{\n\n  return true;\n}\n\nvoid block_location::Swap(block_location *other)\n{\n  if (other != this)\n  {\n    std::swap(identity_, other->identity_);\n    std::swap(index_, other->index_);\n    branch_.Swap(&other->branch_);\n    std::swap(_has_bits_[0], other->_has_bits_[0]);\n    _unknown_fields_.Swap(&other->_unknown_fields_);\n    std::swap(_cached_size_, other->_cached_size_);\n  }\n}\n\n::google::protobuf::Metadata block_location::GetMetadata() const\n{\n  protobuf_AssignDescriptorsOnce();\n  ::google::protobuf::Metadata metadata;\n  metadata.descriptor = block_location_descriptor_;\n  metadata.reflection = block_location_reflection_;\n  return metadata;\n}\n\n// ===================================================================\n\n#ifndef _MSC_VER\nconst int tx_hash_result::kHashFieldNumber;\nconst int tx_hash_result::kLocationFieldNumber;\n#endif // !_MSC_VER\n\ntx_hash_result::tx_hash_result()\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  // @@protoc_insertion_point(constructor:libbitcoin.protocol.tx_hash_result)\n}\n\nvoid tx_hash_result::InitAsDefaultInstance()\n{\n  location_ = const_cast<::libbitcoin::protocol::block_location *>(&::libbitcoin::protocol::block_location::default_instance());\n}\n\ntx_hash_result::tx_hash_result(const tx_hash_result &from)\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  MergeFrom(from);\n  // @@protoc_insertion_point(copy_constructor:libbitcoin.protocol.tx_hash_result)\n}\n\nvoid tx_hash_result::SharedCtor()\n{\n  ::google::protobuf::internal::GetEmptyString();\n  _cached_size_ = 0;\n  hash_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n  location_ = NULL;\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n}\n\ntx_hash_result::~tx_hash_result()\n{\n  // @@protoc_insertion_point(destructor:libbitcoin.protocol.tx_hash_result)\n  SharedDtor();\n}\n\nvoid tx_hash_result::SharedDtor()\n{\n  if (hash_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    delete hash_;\n  }\n  if (this != default_instance_)\n  {\n    delete location_;\n  }\n}\n\nvoid tx_hash_result::SetCachedSize(int size) const\n{\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n}\nconst ::google::protobuf::Descriptor *tx_hash_result::descriptor()\n{\n  protobuf_AssignDescriptorsOnce();\n  return tx_hash_result_descriptor_;\n}\n\nconst tx_hash_result &tx_hash_result::default_instance()\n{\n  if (default_instance_ == NULL)\n    protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  return *default_instance_;\n}\n\ntx_hash_result *tx_hash_result::default_instance_ = NULL;\n\ntx_hash_result *tx_hash_result::New() const\n{\n  return new tx_hash_result;\n}\n\nvoid tx_hash_result::Clear()\n{\n  if (_has_bits_[0 / 32] & 3)\n  {\n    if (has_hash())\n    {\n      if (hash_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n      {\n        hash_->clear();\n      }\n    }\n    if (has_location())\n    {\n      if (location_ != NULL)\n        location_->::libbitcoin::protocol::block_location::Clear();\n    }\n  }\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n  mutable_unknown_fields()->Clear();\n}\n\nbool tx_hash_result::MergePartialFromCodedStream(\n    ::google::protobuf::io::CodedInputStream *input)\n{\n#define DO_(EXPRESSION) \\\n  if (!(EXPRESSION))    \\\n  goto failure\n  ::google::protobuf::uint32 tag;\n  // @@protoc_insertion_point(parse_start:libbitcoin.protocol.tx_hash_result)\n  for (;;)\n  {\n    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);\n    tag = p.first;\n    if (!p.second)\n      goto handle_unusual;\n    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag))\n    {\n    // required bytes hash = 1;\n    case 1:\n    {\n      if (tag == 10)\n      {\n        DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(\n            input, this->mutable_hash()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(18))\n        goto parse_location;\n      break;\n    }\n\n    // required .libbitcoin.protocol.block_location location = 2;\n    case 2:\n    {\n      if (tag == 18)\n      {\n      parse_location:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, mutable_location()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectAtEnd())\n        goto success;\n      break;\n    }\n\n    default:\n    {\n    handle_unusual:\n      if (tag == 0 ||\n          ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n              ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP)\n      {\n        goto success;\n      }\n      DO_(::google::protobuf::internal::WireFormat::SkipField(\n          input, tag, mutable_unknown_fields()));\n      break;\n    }\n    }\n  }\nsuccess:\n  // @@protoc_insertion_point(parse_success:libbitcoin.protocol.tx_hash_result)\n  return true;\nfailure:\n  // @@protoc_insertion_point(parse_failure:libbitcoin.protocol.tx_hash_result)\n  return false;\n#undef DO_\n}\n\nvoid tx_hash_result::SerializeWithCachedSizes(\n    ::google::protobuf::io::CodedOutputStream *output) const\n{\n  // @@protoc_insertion_point(serialize_start:libbitcoin.protocol.tx_hash_result)\n  // required bytes hash = 1;\n  if (has_hash())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(\n        1, this->hash(), output);\n  }\n\n  // required .libbitcoin.protocol.block_location location = 2;\n  if (has_location())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        2, this->location(), output);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n        unknown_fields(), output);\n  }\n  // @@protoc_insertion_point(serialize_end:libbitcoin.protocol.tx_hash_result)\n}\n\n::google::protobuf::uint8 *tx_hash_result::SerializeWithCachedSizesToArray(\n    ::google::protobuf::uint8 *target) const\n{\n  // @@protoc_insertion_point(serialize_to_array_start:libbitcoin.protocol.tx_hash_result)\n  // required bytes hash = 1;\n  if (has_hash())\n  {\n    target =\n        ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(\n            1, this->hash(), target);\n  }\n\n  // required .libbitcoin.protocol.block_location location = 2;\n  if (has_location())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            2, this->location(), target);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n        unknown_fields(), target);\n  }\n  // @@protoc_insertion_point(serialize_to_array_end:libbitcoin.protocol.tx_hash_result)\n  return target;\n}\n\nint tx_hash_result::ByteSize() const\n{\n  int total_size = 0;\n\n  if (_has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    // required bytes hash = 1;\n    if (has_hash())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::BytesSize(\n                        this->hash());\n    }\n\n    // required .libbitcoin.protocol.block_location location = 2;\n    if (has_location())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n                        this->location());\n    }\n  }\n  if (!unknown_fields().empty())\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n            unknown_fields());\n  }\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = total_size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n  return total_size;\n}\n\nvoid tx_hash_result::MergeFrom(const ::google::protobuf::Message &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  const tx_hash_result *source =\n      ::google::protobuf::internal::dynamic_cast_if_available<const tx_hash_result *>(\n          &from);\n  if (source == NULL)\n  {\n    ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n  }\n  else\n  {\n    MergeFrom(*source);\n  }\n}\n\nvoid tx_hash_result::MergeFrom(const tx_hash_result &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    if (from.has_hash())\n    {\n      set_hash(from.hash());\n    }\n    if (from.has_location())\n    {\n      mutable_location()->::libbitcoin::protocol::block_location::MergeFrom(from.location());\n    }\n  }\n  mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n}\n\nvoid tx_hash_result::CopyFrom(const ::google::protobuf::Message &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nvoid tx_hash_result::CopyFrom(const tx_hash_result &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nbool tx_hash_result::IsInitialized() const\n{\n  if ((_has_bits_[0] & 0x00000003) != 0x00000003)\n    return false;\n\n  return true;\n}\n\nvoid tx_hash_result::Swap(tx_hash_result *other)\n{\n  if (other != this)\n  {\n    std::swap(hash_, other->hash_);\n    std::swap(location_, other->location_);\n    std::swap(_has_bits_[0], other->_has_bits_[0]);\n    _unknown_fields_.Swap(&other->_unknown_fields_);\n    std::swap(_cached_size_, other->_cached_size_);\n  }\n}\n\n::google::protobuf::Metadata tx_hash_result::GetMetadata() const\n{\n  protobuf_AssignDescriptorsOnce();\n  ::google::protobuf::Metadata metadata;\n  metadata.descriptor = tx_hash_result_descriptor_;\n  metadata.reflection = tx_hash_result_reflection_;\n  return metadata;\n}\n\n// ===================================================================\n\n#ifndef _MSC_VER\nconst int tx_result::kTransactionFieldNumber;\nconst int tx_result::kLocationFieldNumber;\n#endif // !_MSC_VER\n\ntx_result::tx_result()\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  // @@protoc_insertion_point(constructor:libbitcoin.protocol.tx_result)\n}\n\nvoid tx_result::InitAsDefaultInstance()\n{\n  transaction_ = const_cast<::libbitcoin::protocol::tx *>(&::libbitcoin::protocol::tx::default_instance());\n  location_ = const_cast<::libbitcoin::protocol::block_location *>(&::libbitcoin::protocol::block_location::default_instance());\n}\n\ntx_result::tx_result(const tx_result &from)\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  MergeFrom(from);\n  // @@protoc_insertion_point(copy_constructor:libbitcoin.protocol.tx_result)\n}\n\nvoid tx_result::SharedCtor()\n{\n  _cached_size_ = 0;\n  transaction_ = NULL;\n  location_ = NULL;\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n}\n\ntx_result::~tx_result()\n{\n  // @@protoc_insertion_point(destructor:libbitcoin.protocol.tx_result)\n  SharedDtor();\n}\n\nvoid tx_result::SharedDtor()\n{\n  if (this != default_instance_)\n  {\n    delete transaction_;\n    delete location_;\n  }\n}\n\nvoid tx_result::SetCachedSize(int size) const\n{\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n}\nconst ::google::protobuf::Descriptor *tx_result::descriptor()\n{\n  protobuf_AssignDescriptorsOnce();\n  return tx_result_descriptor_;\n}\n\nconst tx_result &tx_result::default_instance()\n{\n  if (default_instance_ == NULL)\n    protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  return *default_instance_;\n}\n\ntx_result *tx_result::default_instance_ = NULL;\n\ntx_result *tx_result::New() const\n{\n  return new tx_result;\n}\n\nvoid tx_result::Clear()\n{\n  if (_has_bits_[0 / 32] & 3)\n  {\n    if (has_transaction())\n    {\n      if (transaction_ != NULL)\n        transaction_->::libbitcoin::protocol::tx::Clear();\n    }\n    if (has_location())\n    {\n      if (location_ != NULL)\n        location_->::libbitcoin::protocol::block_location::Clear();\n    }\n  }\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n  mutable_unknown_fields()->Clear();\n}\n\nbool tx_result::MergePartialFromCodedStream(\n    ::google::protobuf::io::CodedInputStream *input)\n{\n#define DO_(EXPRESSION) \\\n  if (!(EXPRESSION))    \\\n  goto failure\n  ::google::protobuf::uint32 tag;\n  // @@protoc_insertion_point(parse_start:libbitcoin.protocol.tx_result)\n  for (;;)\n  {\n    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);\n    tag = p.first;\n    if (!p.second)\n      goto handle_unusual;\n    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag))\n    {\n    // required .libbitcoin.protocol.tx transaction = 1;\n    case 1:\n    {\n      if (tag == 10)\n      {\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, mutable_transaction()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(18))\n        goto parse_location;\n      break;\n    }\n\n    // required .libbitcoin.protocol.block_location location = 2;\n    case 2:\n    {\n      if (tag == 18)\n      {\n      parse_location:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, mutable_location()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectAtEnd())\n        goto success;\n      break;\n    }\n\n    default:\n    {\n    handle_unusual:\n      if (tag == 0 ||\n          ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n              ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP)\n      {\n        goto success;\n      }\n      DO_(::google::protobuf::internal::WireFormat::SkipField(\n          input, tag, mutable_unknown_fields()));\n      break;\n    }\n    }\n  }\nsuccess:\n  // @@protoc_insertion_point(parse_success:libbitcoin.protocol.tx_result)\n  return true;\nfailure:\n  // @@protoc_insertion_point(parse_failure:libbitcoin.protocol.tx_result)\n  return false;\n#undef DO_\n}\n\nvoid tx_result::SerializeWithCachedSizes(\n    ::google::protobuf::io::CodedOutputStream *output) const\n{\n  // @@protoc_insertion_point(serialize_start:libbitcoin.protocol.tx_result)\n  // required .libbitcoin.protocol.tx transaction = 1;\n  if (has_transaction())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        1, this->transaction(), output);\n  }\n\n  // required .libbitcoin.protocol.block_location location = 2;\n  if (has_location())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        2, this->location(), output);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n        unknown_fields(), output);\n  }\n  // @@protoc_insertion_point(serialize_end:libbitcoin.protocol.tx_result)\n}\n\n::google::protobuf::uint8 *tx_result::SerializeWithCachedSizesToArray(\n    ::google::protobuf::uint8 *target) const\n{\n  // @@protoc_insertion_point(serialize_to_array_start:libbitcoin.protocol.tx_result)\n  // required .libbitcoin.protocol.tx transaction = 1;\n  if (has_transaction())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            1, this->transaction(), target);\n  }\n\n  // required .libbitcoin.protocol.block_location location = 2;\n  if (has_location())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            2, this->location(), target);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n        unknown_fields(), target);\n  }\n  // @@protoc_insertion_point(serialize_to_array_end:libbitcoin.protocol.tx_result)\n  return target;\n}\n\nint tx_result::ByteSize() const\n{\n  int total_size = 0;\n\n  if (_has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    // required .libbitcoin.protocol.tx transaction = 1;\n    if (has_transaction())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n                        this->transaction());\n    }\n\n    // required .libbitcoin.protocol.block_location location = 2;\n    if (has_location())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n                        this->location());\n    }\n  }\n  if (!unknown_fields().empty())\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n            unknown_fields());\n  }\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = total_size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n  return total_size;\n}\n\nvoid tx_result::MergeFrom(const ::google::protobuf::Message &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  const tx_result *source =\n      ::google::protobuf::internal::dynamic_cast_if_available<const tx_result *>(\n          &from);\n  if (source == NULL)\n  {\n    ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n  }\n  else\n  {\n    MergeFrom(*source);\n  }\n}\n\nvoid tx_result::MergeFrom(const tx_result &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    if (from.has_transaction())\n    {\n      mutable_transaction()->::libbitcoin::protocol::tx::MergeFrom(from.transaction());\n    }\n    if (from.has_location())\n    {\n      mutable_location()->::libbitcoin::protocol::block_location::MergeFrom(from.location());\n    }\n  }\n  mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n}\n\nvoid tx_result::CopyFrom(const ::google::protobuf::Message &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nvoid tx_result::CopyFrom(const tx_result &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nbool tx_result::IsInitialized() const\n{\n  if ((_has_bits_[0] & 0x00000003) != 0x00000003)\n    return false;\n\n  if (has_transaction())\n  {\n    if (!this->transaction().IsInitialized())\n      return false;\n  }\n  return true;\n}\n\nvoid tx_result::Swap(tx_result *other)\n{\n  if (other != this)\n  {\n    std::swap(transaction_, other->transaction_);\n    std::swap(location_, other->location_);\n    std::swap(_has_bits_[0], other->_has_bits_[0]);\n    _unknown_fields_.Swap(&other->_unknown_fields_);\n    std::swap(_cached_size_, other->_cached_size_);\n  }\n}\n\n::google::protobuf::Metadata tx_result::GetMetadata() const\n{\n  protobuf_AssignDescriptorsOnce();\n  ::google::protobuf::Metadata metadata;\n  metadata.descriptor = tx_result_descriptor_;\n  metadata.reflection = tx_result_reflection_;\n  return metadata;\n}\n\n// ===================================================================\n\n#ifndef _MSC_VER\nconst int output::kIndexFieldNumber;\nconst int output::kSatoshisFieldNumber;\nconst int output::kScriptFieldNumber;\n#endif // !_MSC_VER\n\noutput::output()\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  // @@protoc_insertion_point(constructor:libbitcoin.protocol.output)\n}\n\nvoid output::InitAsDefaultInstance()\n{\n}\n\noutput::output(const output &from)\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  MergeFrom(from);\n  // @@protoc_insertion_point(copy_constructor:libbitcoin.protocol.output)\n}\n\nvoid output::SharedCtor()\n{\n  ::google::protobuf::internal::GetEmptyString();\n  _cached_size_ = 0;\n  index_ = 0u;\n  satoshis_ = GOOGLE_ULONGLONG(0);\n  script_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n}\n\noutput::~output()\n{\n  // @@protoc_insertion_point(destructor:libbitcoin.protocol.output)\n  SharedDtor();\n}\n\nvoid output::SharedDtor()\n{\n  if (script_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    delete script_;\n  }\n  if (this != default_instance_)\n  {\n  }\n}\n\nvoid output::SetCachedSize(int size) const\n{\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n}\nconst ::google::protobuf::Descriptor *output::descriptor()\n{\n  protobuf_AssignDescriptorsOnce();\n  return output_descriptor_;\n}\n\nconst output &output::default_instance()\n{\n  if (default_instance_ == NULL)\n    protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  return *default_instance_;\n}\n\noutput *output::default_instance_ = NULL;\n\noutput *output::New() const\n{\n  return new output;\n}\n\nvoid output::Clear()\n{\n  if (_has_bits_[0 / 32] & 7)\n  {\n    index_ = 0u;\n    satoshis_ = GOOGLE_ULONGLONG(0);\n    if (has_script())\n    {\n      if (script_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n      {\n        script_->clear();\n      }\n    }\n  }\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n  mutable_unknown_fields()->Clear();\n}\n\nbool output::MergePartialFromCodedStream(\n    ::google::protobuf::io::CodedInputStream *input)\n{\n#define DO_(EXPRESSION) \\\n  if (!(EXPRESSION))    \\\n  goto failure\n  ::google::protobuf::uint32 tag;\n  // @@protoc_insertion_point(parse_start:libbitcoin.protocol.output)\n  for (;;)\n  {\n    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);\n    tag = p.first;\n    if (!p.second)\n      goto handle_unusual;\n    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag))\n    {\n    // required uint32 index = 1;\n    case 1:\n    {\n      if (tag == 8)\n      {\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(\n            input, &index_)));\n        set_has_index();\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(16))\n        goto parse_satoshis;\n      break;\n    }\n\n    // required uint64 satoshis = 2;\n    case 2:\n    {\n      if (tag == 16)\n      {\n      parse_satoshis:\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(\n            input, &satoshis_)));\n        set_has_satoshis();\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(26))\n        goto parse_script;\n      break;\n    }\n\n    // required bytes script = 3;\n    case 3:\n    {\n      if (tag == 26)\n      {\n      parse_script:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(\n            input, this->mutable_script()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectAtEnd())\n        goto success;\n      break;\n    }\n\n    default:\n    {\n    handle_unusual:\n      if (tag == 0 ||\n          ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n              ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP)\n      {\n        goto success;\n      }\n      DO_(::google::protobuf::internal::WireFormat::SkipField(\n          input, tag, mutable_unknown_fields()));\n      break;\n    }\n    }\n  }\nsuccess:\n  // @@protoc_insertion_point(parse_success:libbitcoin.protocol.output)\n  return true;\nfailure:\n  // @@protoc_insertion_point(parse_failure:libbitcoin.protocol.output)\n  return false;\n#undef DO_\n}\n\nvoid output::SerializeWithCachedSizes(\n    ::google::protobuf::io::CodedOutputStream *output) const\n{\n  // @@protoc_insertion_point(serialize_start:libbitcoin.protocol.output)\n  // required uint32 index = 1;\n  if (has_index())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->index(), output);\n  }\n\n  // required uint64 satoshis = 2;\n  if (has_satoshis())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->satoshis(), output);\n  }\n\n  // required bytes script = 3;\n  if (has_script())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(\n        3, this->script(), output);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n        unknown_fields(), output);\n  }\n  // @@protoc_insertion_point(serialize_end:libbitcoin.protocol.output)\n}\n\n::google::protobuf::uint8 *output::SerializeWithCachedSizesToArray(\n    ::google::protobuf::uint8 *target) const\n{\n  // @@protoc_insertion_point(serialize_to_array_start:libbitcoin.protocol.output)\n  // required uint32 index = 1;\n  if (has_index())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->index(), target);\n  }\n\n  // required uint64 satoshis = 2;\n  if (has_satoshis())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(2, this->satoshis(), target);\n  }\n\n  // required bytes script = 3;\n  if (has_script())\n  {\n    target =\n        ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(\n            3, this->script(), target);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n        unknown_fields(), target);\n  }\n  // @@protoc_insertion_point(serialize_to_array_end:libbitcoin.protocol.output)\n  return target;\n}\n\nint output::ByteSize() const\n{\n  int total_size = 0;\n\n  if (_has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    // required uint32 index = 1;\n    if (has_index())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::UInt32Size(\n                        this->index());\n    }\n\n    // required uint64 satoshis = 2;\n    if (has_satoshis())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::UInt64Size(\n                        this->satoshis());\n    }\n\n    // required bytes script = 3;\n    if (has_script())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::BytesSize(\n                        this->script());\n    }\n  }\n  if (!unknown_fields().empty())\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n            unknown_fields());\n  }\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = total_size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n  return total_size;\n}\n\nvoid output::MergeFrom(const ::google::protobuf::Message &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  const output *source =\n      ::google::protobuf::internal::dynamic_cast_if_available<const output *>(\n          &from);\n  if (source == NULL)\n  {\n    ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n  }\n  else\n  {\n    MergeFrom(*source);\n  }\n}\n\nvoid output::MergeFrom(const output &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    if (from.has_index())\n    {\n      set_index(from.index());\n    }\n    if (from.has_satoshis())\n    {\n      set_satoshis(from.satoshis());\n    }\n    if (from.has_script())\n    {\n      set_script(from.script());\n    }\n  }\n  mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n}\n\nvoid output::CopyFrom(const ::google::protobuf::Message &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nvoid output::CopyFrom(const output &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nbool output::IsInitialized() const\n{\n  if ((_has_bits_[0] & 0x00000007) != 0x00000007)\n    return false;\n\n  return true;\n}\n\nvoid output::Swap(output *other)\n{\n  if (other != this)\n  {\n    std::swap(index_, other->index_);\n    std::swap(satoshis_, other->satoshis_);\n    std::swap(script_, other->script_);\n    std::swap(_has_bits_[0], other->_has_bits_[0]);\n    _unknown_fields_.Swap(&other->_unknown_fields_);\n    std::swap(_cached_size_, other->_cached_size_);\n  }\n}\n\n::google::protobuf::Metadata output::GetMetadata() const\n{\n  protobuf_AssignDescriptorsOnce();\n  ::google::protobuf::Metadata metadata;\n  metadata.descriptor = output_descriptor_;\n  metadata.reflection = output_reflection_;\n  return metadata;\n}\n\n// ===================================================================\n\n#ifndef _MSC_VER\nconst int utxo_result::kTxHashFieldNumber;\nconst int utxo_result::kLocationFieldNumber;\nconst int utxo_result::kOutputsFieldNumber;\n#endif // !_MSC_VER\n\nutxo_result::utxo_result()\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  // @@protoc_insertion_point(constructor:libbitcoin.protocol.utxo_result)\n}\n\nvoid utxo_result::InitAsDefaultInstance()\n{\n  location_ = const_cast<::libbitcoin::protocol::block_location *>(&::libbitcoin::protocol::block_location::default_instance());\n}\n\nutxo_result::utxo_result(const utxo_result &from)\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  MergeFrom(from);\n  // @@protoc_insertion_point(copy_constructor:libbitcoin.protocol.utxo_result)\n}\n\nvoid utxo_result::SharedCtor()\n{\n  ::google::protobuf::internal::GetEmptyString();\n  _cached_size_ = 0;\n  tx_hash_ = const_cast<::std::string *>(&::google::protobuf::internal::GetEmptyStringAlreadyInited());\n  location_ = NULL;\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n}\n\nutxo_result::~utxo_result()\n{\n  // @@protoc_insertion_point(destructor:libbitcoin.protocol.utxo_result)\n  SharedDtor();\n}\n\nvoid utxo_result::SharedDtor()\n{\n  if (tx_hash_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n  {\n    delete tx_hash_;\n  }\n  if (this != default_instance_)\n  {\n    delete location_;\n  }\n}\n\nvoid utxo_result::SetCachedSize(int size) const\n{\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n}\nconst ::google::protobuf::Descriptor *utxo_result::descriptor()\n{\n  protobuf_AssignDescriptorsOnce();\n  return utxo_result_descriptor_;\n}\n\nconst utxo_result &utxo_result::default_instance()\n{\n  if (default_instance_ == NULL)\n    protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  return *default_instance_;\n}\n\nutxo_result *utxo_result::default_instance_ = NULL;\n\nutxo_result *utxo_result::New() const\n{\n  return new utxo_result;\n}\n\nvoid utxo_result::Clear()\n{\n  if (_has_bits_[0 / 32] & 3)\n  {\n    if (has_tx_hash())\n    {\n      if (tx_hash_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited())\n      {\n        tx_hash_->clear();\n      }\n    }\n    if (has_location())\n    {\n      if (location_ != NULL)\n        location_->::libbitcoin::protocol::block_location::Clear();\n    }\n  }\n  outputs_.Clear();\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n  mutable_unknown_fields()->Clear();\n}\n\nbool utxo_result::MergePartialFromCodedStream(\n    ::google::protobuf::io::CodedInputStream *input)\n{\n#define DO_(EXPRESSION) \\\n  if (!(EXPRESSION))    \\\n  goto failure\n  ::google::protobuf::uint32 tag;\n  // @@protoc_insertion_point(parse_start:libbitcoin.protocol.utxo_result)\n  for (;;)\n  {\n    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);\n    tag = p.first;\n    if (!p.second)\n      goto handle_unusual;\n    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag))\n    {\n    // required bytes tx_hash = 1;\n    case 1:\n    {\n      if (tag == 10)\n      {\n        DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(\n            input, this->mutable_tx_hash()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(18))\n        goto parse_location;\n      break;\n    }\n\n    // required .libbitcoin.protocol.block_location location = 2;\n    case 2:\n    {\n      if (tag == 18)\n      {\n      parse_location:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, mutable_location()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(26))\n        goto parse_outputs;\n      break;\n    }\n\n    // repeated .libbitcoin.protocol.output outputs = 3;\n    case 3:\n    {\n      if (tag == 26)\n      {\n      parse_outputs:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, add_outputs()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(26))\n        goto parse_outputs;\n      if (input->ExpectAtEnd())\n        goto success;\n      break;\n    }\n\n    default:\n    {\n    handle_unusual:\n      if (tag == 0 ||\n          ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n              ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP)\n      {\n        goto success;\n      }\n      DO_(::google::protobuf::internal::WireFormat::SkipField(\n          input, tag, mutable_unknown_fields()));\n      break;\n    }\n    }\n  }\nsuccess:\n  // @@protoc_insertion_point(parse_success:libbitcoin.protocol.utxo_result)\n  return true;\nfailure:\n  // @@protoc_insertion_point(parse_failure:libbitcoin.protocol.utxo_result)\n  return false;\n#undef DO_\n}\n\nvoid utxo_result::SerializeWithCachedSizes(\n    ::google::protobuf::io::CodedOutputStream *output) const\n{\n  // @@protoc_insertion_point(serialize_start:libbitcoin.protocol.utxo_result)\n  // required bytes tx_hash = 1;\n  if (has_tx_hash())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased(\n        1, this->tx_hash(), output);\n  }\n\n  // required .libbitcoin.protocol.block_location location = 2;\n  if (has_location())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        2, this->location(), output);\n  }\n\n  // repeated .libbitcoin.protocol.output outputs = 3;\n  for (int i = 0; i < this->outputs_size(); i++)\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        3, this->outputs(i), output);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n        unknown_fields(), output);\n  }\n  // @@protoc_insertion_point(serialize_end:libbitcoin.protocol.utxo_result)\n}\n\n::google::protobuf::uint8 *utxo_result::SerializeWithCachedSizesToArray(\n    ::google::protobuf::uint8 *target) const\n{\n  // @@protoc_insertion_point(serialize_to_array_start:libbitcoin.protocol.utxo_result)\n  // required bytes tx_hash = 1;\n  if (has_tx_hash())\n  {\n    target =\n        ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(\n            1, this->tx_hash(), target);\n  }\n\n  // required .libbitcoin.protocol.block_location location = 2;\n  if (has_location())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            2, this->location(), target);\n  }\n\n  // repeated .libbitcoin.protocol.output outputs = 3;\n  for (int i = 0; i < this->outputs_size(); i++)\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            3, this->outputs(i), target);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n        unknown_fields(), target);\n  }\n  // @@protoc_insertion_point(serialize_to_array_end:libbitcoin.protocol.utxo_result)\n  return target;\n}\n\nint utxo_result::ByteSize() const\n{\n  int total_size = 0;\n\n  if (_has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    // required bytes tx_hash = 1;\n    if (has_tx_hash())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::BytesSize(\n                        this->tx_hash());\n    }\n\n    // required .libbitcoin.protocol.block_location location = 2;\n    if (has_location())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n                        this->location());\n    }\n  }\n  // repeated .libbitcoin.protocol.output outputs = 3;\n  total_size += 1 * this->outputs_size();\n  for (int i = 0; i < this->outputs_size(); i++)\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n            this->outputs(i));\n  }\n\n  if (!unknown_fields().empty())\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n            unknown_fields());\n  }\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = total_size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n  return total_size;\n}\n\nvoid utxo_result::MergeFrom(const ::google::protobuf::Message &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  const utxo_result *source =\n      ::google::protobuf::internal::dynamic_cast_if_available<const utxo_result *>(\n          &from);\n  if (source == NULL)\n  {\n    ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n  }\n  else\n  {\n    MergeFrom(*source);\n  }\n}\n\nvoid utxo_result::MergeFrom(const utxo_result &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  outputs_.MergeFrom(from.outputs_);\n  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    if (from.has_tx_hash())\n    {\n      set_tx_hash(from.tx_hash());\n    }\n    if (from.has_location())\n    {\n      mutable_location()->::libbitcoin::protocol::block_location::MergeFrom(from.location());\n    }\n  }\n  mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n}\n\nvoid utxo_result::CopyFrom(const ::google::protobuf::Message &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nvoid utxo_result::CopyFrom(const utxo_result &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nbool utxo_result::IsInitialized() const\n{\n  if ((_has_bits_[0] & 0x00000003) != 0x00000003)\n    return false;\n\n  if (!::google::protobuf::internal::AllAreInitialized(this->outputs()))\n    return false;\n  return true;\n}\n\nvoid utxo_result::Swap(utxo_result *other)\n{\n  if (other != this)\n  {\n    std::swap(tx_hash_, other->tx_hash_);\n    std::swap(location_, other->location_);\n    outputs_.Swap(&other->outputs_);\n    std::swap(_has_bits_[0], other->_has_bits_[0]);\n    _unknown_fields_.Swap(&other->_unknown_fields_);\n    std::swap(_cached_size_, other->_cached_size_);\n  }\n}\n\n::google::protobuf::Metadata utxo_result::GetMetadata() const\n{\n  protobuf_AssignDescriptorsOnce();\n  ::google::protobuf::Metadata metadata;\n  metadata.descriptor = utxo_result_descriptor_;\n  metadata.reflection = utxo_result_reflection_;\n  return metadata;\n}\n\n// ===================================================================\n\n#ifndef _MSC_VER\nconst int block_headers_request::kStartFieldNumber;\nconst int block_headers_request::kResultsPerPageFieldNumber;\n#endif // !_MSC_VER\n\nblock_headers_request::block_headers_request()\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  // @@protoc_insertion_point(constructor:libbitcoin.protocol.block_headers_request)\n}\n\nvoid block_headers_request::InitAsDefaultInstance()\n{\n  start_ = const_cast<::libbitcoin::protocol::block_id *>(&::libbitcoin::protocol::block_id::default_instance());\n}\n\nblock_headers_request::block_headers_request(const block_headers_request &from)\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  MergeFrom(from);\n  // @@protoc_insertion_point(copy_constructor:libbitcoin.protocol.block_headers_request)\n}\n\nvoid block_headers_request::SharedCtor()\n{\n  _cached_size_ = 0;\n  start_ = NULL;\n  results_per_page_ = 0u;\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n}\n\nblock_headers_request::~block_headers_request()\n{\n  // @@protoc_insertion_point(destructor:libbitcoin.protocol.block_headers_request)\n  SharedDtor();\n}\n\nvoid block_headers_request::SharedDtor()\n{\n  if (this != default_instance_)\n  {\n    delete start_;\n  }\n}\n\nvoid block_headers_request::SetCachedSize(int size) const\n{\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n}\nconst ::google::protobuf::Descriptor *block_headers_request::descriptor()\n{\n  protobuf_AssignDescriptorsOnce();\n  return block_headers_request_descriptor_;\n}\n\nconst block_headers_request &block_headers_request::default_instance()\n{\n  if (default_instance_ == NULL)\n    protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  return *default_instance_;\n}\n\nblock_headers_request *block_headers_request::default_instance_ = NULL;\n\nblock_headers_request *block_headers_request::New() const\n{\n  return new block_headers_request;\n}\n\nvoid block_headers_request::Clear()\n{\n  if (_has_bits_[0 / 32] & 3)\n  {\n    if (has_start())\n    {\n      if (start_ != NULL)\n        start_->::libbitcoin::protocol::block_id::Clear();\n    }\n    results_per_page_ = 0u;\n  }\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n  mutable_unknown_fields()->Clear();\n}\n\nbool block_headers_request::MergePartialFromCodedStream(\n    ::google::protobuf::io::CodedInputStream *input)\n{\n#define DO_(EXPRESSION) \\\n  if (!(EXPRESSION))    \\\n  goto failure\n  ::google::protobuf::uint32 tag;\n  // @@protoc_insertion_point(parse_start:libbitcoin.protocol.block_headers_request)\n  for (;;)\n  {\n    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);\n    tag = p.first;\n    if (!p.second)\n      goto handle_unusual;\n    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag))\n    {\n    // optional .libbitcoin.protocol.block_id start = 1;\n    case 1:\n    {\n      if (tag == 10)\n      {\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, mutable_start()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(16))\n        goto parse_results_per_page;\n      break;\n    }\n\n    // optional uint32 results_per_page = 2;\n    case 2:\n    {\n      if (tag == 16)\n      {\n      parse_results_per_page:\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(\n            input, &results_per_page_)));\n        set_has_results_per_page();\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectAtEnd())\n        goto success;\n      break;\n    }\n\n    default:\n    {\n    handle_unusual:\n      if (tag == 0 ||\n          ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n              ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP)\n      {\n        goto success;\n      }\n      DO_(::google::protobuf::internal::WireFormat::SkipField(\n          input, tag, mutable_unknown_fields()));\n      break;\n    }\n    }\n  }\nsuccess:\n  // @@protoc_insertion_point(parse_success:libbitcoin.protocol.block_headers_request)\n  return true;\nfailure:\n  // @@protoc_insertion_point(parse_failure:libbitcoin.protocol.block_headers_request)\n  return false;\n#undef DO_\n}\n\nvoid block_headers_request::SerializeWithCachedSizes(\n    ::google::protobuf::io::CodedOutputStream *output) const\n{\n  // @@protoc_insertion_point(serialize_start:libbitcoin.protocol.block_headers_request)\n  // optional .libbitcoin.protocol.block_id start = 1;\n  if (has_start())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        1, this->start(), output);\n  }\n\n  // optional uint32 results_per_page = 2;\n  if (has_results_per_page())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->results_per_page(), output);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n        unknown_fields(), output);\n  }\n  // @@protoc_insertion_point(serialize_end:libbitcoin.protocol.block_headers_request)\n}\n\n::google::protobuf::uint8 *block_headers_request::SerializeWithCachedSizesToArray(\n    ::google::protobuf::uint8 *target) const\n{\n  // @@protoc_insertion_point(serialize_to_array_start:libbitcoin.protocol.block_headers_request)\n  // optional .libbitcoin.protocol.block_id start = 1;\n  if (has_start())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            1, this->start(), target);\n  }\n\n  // optional uint32 results_per_page = 2;\n  if (has_results_per_page())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->results_per_page(), target);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n        unknown_fields(), target);\n  }\n  // @@protoc_insertion_point(serialize_to_array_end:libbitcoin.protocol.block_headers_request)\n  return target;\n}\n\nint block_headers_request::ByteSize() const\n{\n  int total_size = 0;\n\n  if (_has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    // optional .libbitcoin.protocol.block_id start = 1;\n    if (has_start())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n                        this->start());\n    }\n\n    // optional uint32 results_per_page = 2;\n    if (has_results_per_page())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::UInt32Size(\n                        this->results_per_page());\n    }\n  }\n  if (!unknown_fields().empty())\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n            unknown_fields());\n  }\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = total_size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n  return total_size;\n}\n\nvoid block_headers_request::MergeFrom(const ::google::protobuf::Message &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  const block_headers_request *source =\n      ::google::protobuf::internal::dynamic_cast_if_available<const block_headers_request *>(\n          &from);\n  if (source == NULL)\n  {\n    ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n  }\n  else\n  {\n    MergeFrom(*source);\n  }\n}\n\nvoid block_headers_request::MergeFrom(const block_headers_request &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    if (from.has_start())\n    {\n      mutable_start()->::libbitcoin::protocol::block_id::MergeFrom(from.start());\n    }\n    if (from.has_results_per_page())\n    {\n      set_results_per_page(from.results_per_page());\n    }\n  }\n  mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n}\n\nvoid block_headers_request::CopyFrom(const ::google::protobuf::Message &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nvoid block_headers_request::CopyFrom(const block_headers_request &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nbool block_headers_request::IsInitialized() const\n{\n\n  return true;\n}\n\nvoid block_headers_request::Swap(block_headers_request *other)\n{\n  if (other != this)\n  {\n    std::swap(start_, other->start_);\n    std::swap(results_per_page_, other->results_per_page_);\n    std::swap(_has_bits_[0], other->_has_bits_[0]);\n    _unknown_fields_.Swap(&other->_unknown_fields_);\n    std::swap(_cached_size_, other->_cached_size_);\n  }\n}\n\n::google::protobuf::Metadata block_headers_request::GetMetadata() const\n{\n  protobuf_AssignDescriptorsOnce();\n  ::google::protobuf::Metadata metadata;\n  metadata.descriptor = block_headers_request_descriptor_;\n  metadata.reflection = block_headers_request_reflection_;\n  return metadata;\n}\n\n// ===================================================================\n\n#ifndef _MSC_VER\nconst int transactions_request::kStartFieldNumber;\nconst int transactions_request::kResultsPerPageFieldNumber;\nconst int transactions_request::kQueryFieldNumber;\nconst int transactions_request::kResultTypeFieldNumber;\nconst int transactions_request::kLocationTypeFieldNumber;\n#endif // !_MSC_VER\n\ntransactions_request::transactions_request()\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  // @@protoc_insertion_point(constructor:libbitcoin.protocol.transactions_request)\n}\n\nvoid transactions_request::InitAsDefaultInstance()\n{\n  start_ = const_cast<::libbitcoin::protocol::block_id *>(&::libbitcoin::protocol::block_id::default_instance());\n}\n\ntransactions_request::transactions_request(const transactions_request &from)\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  MergeFrom(from);\n  // @@protoc_insertion_point(copy_constructor:libbitcoin.protocol.transactions_request)\n}\n\nvoid transactions_request::SharedCtor()\n{\n  _cached_size_ = 0;\n  start_ = NULL;\n  results_per_page_ = 0u;\n  result_type_ = 1;\n  location_type_ = 0;\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n}\n\ntransactions_request::~transactions_request()\n{\n  // @@protoc_insertion_point(destructor:libbitcoin.protocol.transactions_request)\n  SharedDtor();\n}\n\nvoid transactions_request::SharedDtor()\n{\n  if (this != default_instance_)\n  {\n    delete start_;\n  }\n}\n\nvoid transactions_request::SetCachedSize(int size) const\n{\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n}\nconst ::google::protobuf::Descriptor *transactions_request::descriptor()\n{\n  protobuf_AssignDescriptorsOnce();\n  return transactions_request_descriptor_;\n}\n\nconst transactions_request &transactions_request::default_instance()\n{\n  if (default_instance_ == NULL)\n    protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  return *default_instance_;\n}\n\ntransactions_request *transactions_request::default_instance_ = NULL;\n\ntransactions_request *transactions_request::New() const\n{\n  return new transactions_request;\n}\n\nvoid transactions_request::Clear()\n{\n  if (_has_bits_[0 / 32] & 27)\n  {\n    if (has_start())\n    {\n      if (start_ != NULL)\n        start_->::libbitcoin::protocol::block_id::Clear();\n    }\n    results_per_page_ = 0u;\n    result_type_ = 1;\n    location_type_ = 0;\n  }\n  query_.Clear();\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n  mutable_unknown_fields()->Clear();\n}\n\nbool transactions_request::MergePartialFromCodedStream(\n    ::google::protobuf::io::CodedInputStream *input)\n{\n#define DO_(EXPRESSION) \\\n  if (!(EXPRESSION))    \\\n  goto failure\n  ::google::protobuf::uint32 tag;\n  // @@protoc_insertion_point(parse_start:libbitcoin.protocol.transactions_request)\n  for (;;)\n  {\n    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);\n    tag = p.first;\n    if (!p.second)\n      goto handle_unusual;\n    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag))\n    {\n    // optional .libbitcoin.protocol.block_id start = 1;\n    case 1:\n    {\n      if (tag == 10)\n      {\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, mutable_start()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(16))\n        goto parse_results_per_page;\n      break;\n    }\n\n    // optional uint32 results_per_page = 2;\n    case 2:\n    {\n      if (tag == 16)\n      {\n      parse_results_per_page:\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(\n            input, &results_per_page_)));\n        set_has_results_per_page();\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(26))\n        goto parse_query;\n      break;\n    }\n\n    // repeated .libbitcoin.protocol.filter query = 3;\n    case 3:\n    {\n      if (tag == 26)\n      {\n      parse_query:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, add_query()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(26))\n        goto parse_query;\n      if (input->ExpectTag(32))\n        goto parse_result_type;\n      break;\n    }\n\n    // optional .libbitcoin.protocol.tx_results result_type = 4 [default = TX_HASH];\n    case 4:\n    {\n      if (tag == 32)\n      {\n      parse_result_type:\n        int value;\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n            input, &value)));\n        if (::libbitcoin::protocol::tx_results_IsValid(value))\n        {\n          set_result_type(static_cast<::libbitcoin::protocol::tx_results>(value));\n        }\n        else\n        {\n          mutable_unknown_fields()->AddVarint(4, value);\n        }\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(40))\n        goto parse_location_type;\n      break;\n    }\n\n    // optional .libbitcoin.protocol.locations location_type = 5 [default = NONE];\n    case 5:\n    {\n      if (tag == 40)\n      {\n      parse_location_type:\n        int value;\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n            input, &value)));\n        if (::libbitcoin::protocol::locations_IsValid(value))\n        {\n          set_location_type(static_cast<::libbitcoin::protocol::locations>(value));\n        }\n        else\n        {\n          mutable_unknown_fields()->AddVarint(5, value);\n        }\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectAtEnd())\n        goto success;\n      break;\n    }\n\n    default:\n    {\n    handle_unusual:\n      if (tag == 0 ||\n          ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n              ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP)\n      {\n        goto success;\n      }\n      DO_(::google::protobuf::internal::WireFormat::SkipField(\n          input, tag, mutable_unknown_fields()));\n      break;\n    }\n    }\n  }\nsuccess:\n  // @@protoc_insertion_point(parse_success:libbitcoin.protocol.transactions_request)\n  return true;\nfailure:\n  // @@protoc_insertion_point(parse_failure:libbitcoin.protocol.transactions_request)\n  return false;\n#undef DO_\n}\n\nvoid transactions_request::SerializeWithCachedSizes(\n    ::google::protobuf::io::CodedOutputStream *output) const\n{\n  // @@protoc_insertion_point(serialize_start:libbitcoin.protocol.transactions_request)\n  // optional .libbitcoin.protocol.block_id start = 1;\n  if (has_start())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        1, this->start(), output);\n  }\n\n  // optional uint32 results_per_page = 2;\n  if (has_results_per_page())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->results_per_page(), output);\n  }\n\n  // repeated .libbitcoin.protocol.filter query = 3;\n  for (int i = 0; i < this->query_size(); i++)\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        3, this->query(i), output);\n  }\n\n  // optional .libbitcoin.protocol.tx_results result_type = 4 [default = TX_HASH];\n  if (has_result_type())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteEnum(\n        4, this->result_type(), output);\n  }\n\n  // optional .libbitcoin.protocol.locations location_type = 5 [default = NONE];\n  if (has_location_type())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteEnum(\n        5, this->location_type(), output);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n        unknown_fields(), output);\n  }\n  // @@protoc_insertion_point(serialize_end:libbitcoin.protocol.transactions_request)\n}\n\n::google::protobuf::uint8 *transactions_request::SerializeWithCachedSizesToArray(\n    ::google::protobuf::uint8 *target) const\n{\n  // @@protoc_insertion_point(serialize_to_array_start:libbitcoin.protocol.transactions_request)\n  // optional .libbitcoin.protocol.block_id start = 1;\n  if (has_start())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            1, this->start(), target);\n  }\n\n  // optional uint32 results_per_page = 2;\n  if (has_results_per_page())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(2, this->results_per_page(), target);\n  }\n\n  // repeated .libbitcoin.protocol.filter query = 3;\n  for (int i = 0; i < this->query_size(); i++)\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            3, this->query(i), target);\n  }\n\n  // optional .libbitcoin.protocol.tx_results result_type = 4 [default = TX_HASH];\n  if (has_result_type())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(\n        4, this->result_type(), target);\n  }\n\n  // optional .libbitcoin.protocol.locations location_type = 5 [default = NONE];\n  if (has_location_type())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(\n        5, this->location_type(), target);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n        unknown_fields(), target);\n  }\n  // @@protoc_insertion_point(serialize_to_array_end:libbitcoin.protocol.transactions_request)\n  return target;\n}\n\nint transactions_request::ByteSize() const\n{\n  int total_size = 0;\n\n  if (_has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    // optional .libbitcoin.protocol.block_id start = 1;\n    if (has_start())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n                        this->start());\n    }\n\n    // optional uint32 results_per_page = 2;\n    if (has_results_per_page())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::UInt32Size(\n                        this->results_per_page());\n    }\n\n    // optional .libbitcoin.protocol.tx_results result_type = 4 [default = TX_HASH];\n    if (has_result_type())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::EnumSize(this->result_type());\n    }\n\n    // optional .libbitcoin.protocol.locations location_type = 5 [default = NONE];\n    if (has_location_type())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::EnumSize(this->location_type());\n    }\n  }\n  // repeated .libbitcoin.protocol.filter query = 3;\n  total_size += 1 * this->query_size();\n  for (int i = 0; i < this->query_size(); i++)\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n            this->query(i));\n  }\n\n  if (!unknown_fields().empty())\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n            unknown_fields());\n  }\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = total_size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n  return total_size;\n}\n\nvoid transactions_request::MergeFrom(const ::google::protobuf::Message &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  const transactions_request *source =\n      ::google::protobuf::internal::dynamic_cast_if_available<const transactions_request *>(\n          &from);\n  if (source == NULL)\n  {\n    ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n  }\n  else\n  {\n    MergeFrom(*source);\n  }\n}\n\nvoid transactions_request::MergeFrom(const transactions_request &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  query_.MergeFrom(from.query_);\n  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    if (from.has_start())\n    {\n      mutable_start()->::libbitcoin::protocol::block_id::MergeFrom(from.start());\n    }\n    if (from.has_results_per_page())\n    {\n      set_results_per_page(from.results_per_page());\n    }\n    if (from.has_result_type())\n    {\n      set_result_type(from.result_type());\n    }\n    if (from.has_location_type())\n    {\n      set_location_type(from.location_type());\n    }\n  }\n  mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n}\n\nvoid transactions_request::CopyFrom(const ::google::protobuf::Message &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nvoid transactions_request::CopyFrom(const transactions_request &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nbool transactions_request::IsInitialized() const\n{\n\n  if (!::google::protobuf::internal::AllAreInitialized(this->query()))\n    return false;\n  return true;\n}\n\nvoid transactions_request::Swap(transactions_request *other)\n{\n  if (other != this)\n  {\n    std::swap(start_, other->start_);\n    std::swap(results_per_page_, other->results_per_page_);\n    query_.Swap(&other->query_);\n    std::swap(result_type_, other->result_type_);\n    std::swap(location_type_, other->location_type_);\n    std::swap(_has_bits_[0], other->_has_bits_[0]);\n    _unknown_fields_.Swap(&other->_unknown_fields_);\n    std::swap(_cached_size_, other->_cached_size_);\n  }\n}\n\n::google::protobuf::Metadata transactions_request::GetMetadata() const\n{\n  protobuf_AssignDescriptorsOnce();\n  ::google::protobuf::Metadata metadata;\n  metadata.descriptor = transactions_request_descriptor_;\n  metadata.reflection = transactions_request_reflection_;\n  return metadata;\n}\n\n// ===================================================================\n\n#ifndef _MSC_VER\nconst int request::kIdFieldNumber;\nconst int request::kGetBlockHeadersFieldNumber;\nconst int request::kGetTransactionsFieldNumber;\nconst int request::kPostTransactionFieldNumber;\nconst int request::kValidateTransactionFieldNumber;\nconst int request::kPostBlockFieldNumber;\nconst int request::kValidateBlockFieldNumber;\n#endif // !_MSC_VER\n\nrequest::request()\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  // @@protoc_insertion_point(constructor:libbitcoin.protocol.request)\n}\n\nvoid request::InitAsDefaultInstance()\n{\n  request_default_oneof_instance_->get_block_headers_ = const_cast<::libbitcoin::protocol::block_headers_request *>(&::libbitcoin::protocol::block_headers_request::default_instance());\n  request_default_oneof_instance_->get_transactions_ = const_cast<::libbitcoin::protocol::transactions_request *>(&::libbitcoin::protocol::transactions_request::default_instance());\n  request_default_oneof_instance_->post_transaction_ = const_cast<::libbitcoin::protocol::tx *>(&::libbitcoin::protocol::tx::default_instance());\n  request_default_oneof_instance_->validate_tx_engine_ = const_cast<::libbitcoin::protocol::tx *>(&::libbitcoin::protocol::tx::default_instance());\n  request_default_oneof_instance_->post_block_ = const_cast<::libbitcoin::protocol::block *>(&::libbitcoin::protocol::block::default_instance());\n  request_default_oneof_instance_->validate_block_ = const_cast<::libbitcoin::protocol::block *>(&::libbitcoin::protocol::block::default_instance());\n}\n\nrequest::request(const request &from)\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  MergeFrom(from);\n  // @@protoc_insertion_point(copy_constructor:libbitcoin.protocol.request)\n}\n\nvoid request::SharedCtor()\n{\n  _cached_size_ = 0;\n  id_ = 0u;\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n  clear_has_request_type();\n}\n\nrequest::~request()\n{\n  // @@protoc_insertion_point(destructor:libbitcoin.protocol.request)\n  SharedDtor();\n}\n\nvoid request::SharedDtor()\n{\n  if (has_request_type())\n  {\n    clear_request_type();\n  }\n  if (this != default_instance_)\n  {\n  }\n}\n\nvoid request::SetCachedSize(int size) const\n{\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n}\nconst ::google::protobuf::Descriptor *request::descriptor()\n{\n  protobuf_AssignDescriptorsOnce();\n  return request_descriptor_;\n}\n\nconst request &request::default_instance()\n{\n  if (default_instance_ == NULL)\n    protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  return *default_instance_;\n}\n\nrequest *request::default_instance_ = NULL;\n\nrequest *request::New() const\n{\n  return new request;\n}\n\nvoid request::clear_request_type()\n{\n  switch (request_type_case())\n  {\n  case kGetBlockHeaders:\n  {\n    delete request_type_.get_block_headers_;\n    break;\n  }\n  case kGetTransactions:\n  {\n    delete request_type_.get_transactions_;\n    break;\n  }\n  case kPostTransaction:\n  {\n    delete request_type_.post_transaction_;\n    break;\n  }\n  case kValidateTransaction:\n  {\n    delete request_type_.validate_tx_engine_;\n    break;\n  }\n  case kPostBlock:\n  {\n    delete request_type_.post_block_;\n    break;\n  }\n  case kValidateBlock:\n  {\n    delete request_type_.validate_block_;\n    break;\n  }\n  case REQUEST_TYPE_NOT_SET:\n  {\n    break;\n  }\n  }\n  _oneof_case_[0] = REQUEST_TYPE_NOT_SET;\n}\n\nvoid request::Clear()\n{\n  _extensions_.Clear();\n  id_ = 0u;\n  clear_request_type();\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n  mutable_unknown_fields()->Clear();\n}\n\nbool request::MergePartialFromCodedStream(\n    ::google::protobuf::io::CodedInputStream *input)\n{\n#define DO_(EXPRESSION) \\\n  if (!(EXPRESSION))    \\\n  goto failure\n  ::google::protobuf::uint32 tag;\n  // @@protoc_insertion_point(parse_start:libbitcoin.protocol.request)\n  for (;;)\n  {\n    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);\n    tag = p.first;\n    if (!p.second)\n      goto handle_unusual;\n    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag))\n    {\n    // required uint32 id = 1;\n    case 1:\n    {\n      if (tag == 8)\n      {\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(\n            input, &id_)));\n        set_has_id();\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(18))\n        goto parse_get_block_headers;\n      break;\n    }\n\n    // optional .libbitcoin.protocol.block_headers_request get_block_headers = 2;\n    case 2:\n    {\n      if (tag == 18)\n      {\n      parse_get_block_headers:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, mutable_get_block_headers()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(26))\n        goto parse_get_transactions;\n      break;\n    }\n\n    // optional .libbitcoin.protocol.transactions_request get_transactions = 3;\n    case 3:\n    {\n      if (tag == 26)\n      {\n      parse_get_transactions:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, mutable_get_transactions()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(34))\n        goto parse_post_transaction;\n      break;\n    }\n\n    // optional .libbitcoin.protocol.tx post_transaction = 4;\n    case 4:\n    {\n      if (tag == 34)\n      {\n      parse_post_transaction:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, mutable_post_transaction()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(42))\n        goto parse_validate_tx_engine;\n      break;\n    }\n\n    // optional .libbitcoin.protocol.tx validate_tx_engine = 5;\n    case 5:\n    {\n      if (tag == 42)\n      {\n      parse_validate_tx_engine:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, mutable_validate_tx_engine()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(50))\n        goto parse_post_block;\n      break;\n    }\n\n    // optional .libbitcoin.protocol.block post_block = 6;\n    case 6:\n    {\n      if (tag == 50)\n      {\n      parse_post_block:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, mutable_post_block()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(58))\n        goto parse_validate_block;\n      break;\n    }\n\n    // optional .libbitcoin.protocol.block validate_block = 7;\n    case 7:\n    {\n      if (tag == 58)\n      {\n      parse_validate_block:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, mutable_validate_block()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectAtEnd())\n        goto success;\n      break;\n    }\n\n    default:\n    {\n    handle_unusual:\n      if (tag == 0 ||\n          ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n              ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP)\n      {\n        goto success;\n      }\n      if ((800u <= tag && tag < 1600u))\n      {\n        DO_(_extensions_.ParseField(tag, input, default_instance_,\n                                    mutable_unknown_fields()));\n        continue;\n      }\n      DO_(::google::protobuf::internal::WireFormat::SkipField(\n          input, tag, mutable_unknown_fields()));\n      break;\n    }\n    }\n  }\nsuccess:\n  // @@protoc_insertion_point(parse_success:libbitcoin.protocol.request)\n  return true;\nfailure:\n  // @@protoc_insertion_point(parse_failure:libbitcoin.protocol.request)\n  return false;\n#undef DO_\n}\n\nvoid request::SerializeWithCachedSizes(\n    ::google::protobuf::io::CodedOutputStream *output) const\n{\n  // @@protoc_insertion_point(serialize_start:libbitcoin.protocol.request)\n  // required uint32 id = 1;\n  if (has_id())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->id(), output);\n  }\n\n  // optional .libbitcoin.protocol.block_headers_request get_block_headers = 2;\n  if (has_get_block_headers())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        2, this->get_block_headers(), output);\n  }\n\n  // optional .libbitcoin.protocol.transactions_request get_transactions = 3;\n  if (has_get_transactions())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        3, this->get_transactions(), output);\n  }\n\n  // optional .libbitcoin.protocol.tx post_transaction = 4;\n  if (has_post_transaction())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        4, this->post_transaction(), output);\n  }\n\n  // optional .libbitcoin.protocol.tx validate_tx_engine = 5;\n  if (has_validate_tx_engine())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        5, this->validate_tx_engine(), output);\n  }\n\n  // optional .libbitcoin.protocol.block post_block = 6;\n  if (has_post_block())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        6, this->post_block(), output);\n  }\n\n  // optional .libbitcoin.protocol.block validate_block = 7;\n  if (has_validate_block())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        7, this->validate_block(), output);\n  }\n\n  // Extension range [100, 200)\n  _extensions_.SerializeWithCachedSizes(\n      100, 200, output);\n\n  if (!unknown_fields().empty())\n  {\n    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n        unknown_fields(), output);\n  }\n  // @@protoc_insertion_point(serialize_end:libbitcoin.protocol.request)\n}\n\n::google::protobuf::uint8 *request::SerializeWithCachedSizesToArray(\n    ::google::protobuf::uint8 *target) const\n{\n  // @@protoc_insertion_point(serialize_to_array_start:libbitcoin.protocol.request)\n  // required uint32 id = 1;\n  if (has_id())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->id(), target);\n  }\n\n  // optional .libbitcoin.protocol.block_headers_request get_block_headers = 2;\n  if (has_get_block_headers())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            2, this->get_block_headers(), target);\n  }\n\n  // optional .libbitcoin.protocol.transactions_request get_transactions = 3;\n  if (has_get_transactions())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            3, this->get_transactions(), target);\n  }\n\n  // optional .libbitcoin.protocol.tx post_transaction = 4;\n  if (has_post_transaction())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            4, this->post_transaction(), target);\n  }\n\n  // optional .libbitcoin.protocol.tx validate_tx_engine = 5;\n  if (has_validate_tx_engine())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            5, this->validate_tx_engine(), target);\n  }\n\n  // optional .libbitcoin.protocol.block post_block = 6;\n  if (has_post_block())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            6, this->post_block(), target);\n  }\n\n  // optional .libbitcoin.protocol.block validate_block = 7;\n  if (has_validate_block())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            7, this->validate_block(), target);\n  }\n\n  // Extension range [100, 200)\n  target = _extensions_.SerializeWithCachedSizesToArray(\n      100, 200, target);\n\n  if (!unknown_fields().empty())\n  {\n    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n        unknown_fields(), target);\n  }\n  // @@protoc_insertion_point(serialize_to_array_end:libbitcoin.protocol.request)\n  return target;\n}\n\nint request::ByteSize() const\n{\n  int total_size = 0;\n\n  if (_has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    // required uint32 id = 1;\n    if (has_id())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::UInt32Size(\n                        this->id());\n    }\n  }\n  switch (request_type_case())\n  {\n  // optional .libbitcoin.protocol.block_headers_request get_block_headers = 2;\n  case kGetBlockHeaders:\n  {\n    total_size += 1 +\n                  ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n                      this->get_block_headers());\n    break;\n  }\n  // optional .libbitcoin.protocol.transactions_request get_transactions = 3;\n  case kGetTransactions:\n  {\n    total_size += 1 +\n                  ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n                      this->get_transactions());\n    break;\n  }\n  // optional .libbitcoin.protocol.tx post_transaction = 4;\n  case kPostTransaction:\n  {\n    total_size += 1 +\n                  ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n                      this->post_transaction());\n    break;\n  }\n  // optional .libbitcoin.protocol.tx validate_tx_engine = 5;\n  case kValidateTransaction:\n  {\n    total_size += 1 +\n                  ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n                      this->validate_tx_engine());\n    break;\n  }\n  // optional .libbitcoin.protocol.block post_block = 6;\n  case kPostBlock:\n  {\n    total_size += 1 +\n                  ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n                      this->post_block());\n    break;\n  }\n  // optional .libbitcoin.protocol.block validate_block = 7;\n  case kValidateBlock:\n  {\n    total_size += 1 +\n                  ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n                      this->validate_block());\n    break;\n  }\n  case REQUEST_TYPE_NOT_SET:\n  {\n    break;\n  }\n  }\n  total_size += _extensions_.ByteSize();\n\n  if (!unknown_fields().empty())\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n            unknown_fields());\n  }\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = total_size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n  return total_size;\n}\n\nvoid request::MergeFrom(const ::google::protobuf::Message &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  const request *source =\n      ::google::protobuf::internal::dynamic_cast_if_available<const request *>(\n          &from);\n  if (source == NULL)\n  {\n    ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n  }\n  else\n  {\n    MergeFrom(*source);\n  }\n}\n\nvoid request::MergeFrom(const request &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  switch (from.request_type_case())\n  {\n  case kGetBlockHeaders:\n  {\n    mutable_get_block_headers()->::libbitcoin::protocol::block_headers_request::MergeFrom(from.get_block_headers());\n    break;\n  }\n  case kGetTransactions:\n  {\n    mutable_get_transactions()->::libbitcoin::protocol::transactions_request::MergeFrom(from.get_transactions());\n    break;\n  }\n  case kPostTransaction:\n  {\n    mutable_post_transaction()->::libbitcoin::protocol::tx::MergeFrom(from.post_transaction());\n    break;\n  }\n  case kValidateTransaction:\n  {\n    mutable_validate_tx_engine()->::libbitcoin::protocol::tx::MergeFrom(from.validate_tx_engine());\n    break;\n  }\n  case kPostBlock:\n  {\n    mutable_post_block()->::libbitcoin::protocol::block::MergeFrom(from.post_block());\n    break;\n  }\n  case kValidateBlock:\n  {\n    mutable_validate_block()->::libbitcoin::protocol::block::MergeFrom(from.validate_block());\n    break;\n  }\n  case REQUEST_TYPE_NOT_SET:\n  {\n    break;\n  }\n  }\n  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    if (from.has_id())\n    {\n      set_id(from.id());\n    }\n  }\n  _extensions_.MergeFrom(from._extensions_);\n  mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n}\n\nvoid request::CopyFrom(const ::google::protobuf::Message &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nvoid request::CopyFrom(const request &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nbool request::IsInitialized() const\n{\n  if ((_has_bits_[0] & 0x00000001) != 0x00000001)\n    return false;\n\n  if (has_get_transactions())\n  {\n    if (!this->get_transactions().IsInitialized())\n      return false;\n  }\n  if (has_post_transaction())\n  {\n    if (!this->post_transaction().IsInitialized())\n      return false;\n  }\n  if (has_validate_tx_engine())\n  {\n    if (!this->validate_tx_engine().IsInitialized())\n      return false;\n  }\n  if (has_post_block())\n  {\n    if (!this->post_block().IsInitialized())\n      return false;\n  }\n  if (has_validate_block())\n  {\n    if (!this->validate_block().IsInitialized())\n      return false;\n  }\n\n  if (!_extensions_.IsInitialized())\n    return false;\n  return true;\n}\n\nvoid request::Swap(request *other)\n{\n  if (other != this)\n  {\n    std::swap(id_, other->id_);\n    std::swap(request_type_, other->request_type_);\n    std::swap(_oneof_case_[0], other->_oneof_case_[0]);\n    std::swap(_has_bits_[0], other->_has_bits_[0]);\n    _unknown_fields_.Swap(&other->_unknown_fields_);\n    std::swap(_cached_size_, other->_cached_size_);\n    _extensions_.Swap(&other->_extensions_);\n  }\n}\n\n::google::protobuf::Metadata request::GetMetadata() const\n{\n  protobuf_AssignDescriptorsOnce();\n  ::google::protobuf::Metadata metadata;\n  metadata.descriptor = request_descriptor_;\n  metadata.reflection = request_reflection_;\n  return metadata;\n}\n\n// ===================================================================\n\n#ifndef _MSC_VER\nconst int response_block_headers::kNextFieldNumber;\nconst int response_block_headers::kTopFieldNumber;\nconst int response_block_headers::kHeadersFieldNumber;\n#endif // !_MSC_VER\n\nresponse_block_headers::response_block_headers()\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  // @@protoc_insertion_point(constructor:libbitcoin.protocol.response.block_headers)\n}\n\nvoid response_block_headers::InitAsDefaultInstance()\n{\n  next_ = const_cast<::libbitcoin::protocol::block_id *>(&::libbitcoin::protocol::block_id::default_instance());\n  top_ = const_cast<::libbitcoin::protocol::block_id *>(&::libbitcoin::protocol::block_id::default_instance());\n}\n\nresponse_block_headers::response_block_headers(const response_block_headers &from)\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  MergeFrom(from);\n  // @@protoc_insertion_point(copy_constructor:libbitcoin.protocol.response.block_headers)\n}\n\nvoid response_block_headers::SharedCtor()\n{\n  _cached_size_ = 0;\n  next_ = NULL;\n  top_ = NULL;\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n}\n\nresponse_block_headers::~response_block_headers()\n{\n  // @@protoc_insertion_point(destructor:libbitcoin.protocol.response.block_headers)\n  SharedDtor();\n}\n\nvoid response_block_headers::SharedDtor()\n{\n  if (this != default_instance_)\n  {\n    delete next_;\n    delete top_;\n  }\n}\n\nvoid response_block_headers::SetCachedSize(int size) const\n{\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n}\nconst ::google::protobuf::Descriptor *response_block_headers::descriptor()\n{\n  protobuf_AssignDescriptorsOnce();\n  return response_block_headers_descriptor_;\n}\n\nconst response_block_headers &response_block_headers::default_instance()\n{\n  if (default_instance_ == NULL)\n    protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  return *default_instance_;\n}\n\nresponse_block_headers *response_block_headers::default_instance_ = NULL;\n\nresponse_block_headers *response_block_headers::New() const\n{\n  return new response_block_headers;\n}\n\nvoid response_block_headers::Clear()\n{\n  if (_has_bits_[0 / 32] & 3)\n  {\n    if (has_next())\n    {\n      if (next_ != NULL)\n        next_->::libbitcoin::protocol::block_id::Clear();\n    }\n    if (has_top())\n    {\n      if (top_ != NULL)\n        top_->::libbitcoin::protocol::block_id::Clear();\n    }\n  }\n  headers_.Clear();\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n  mutable_unknown_fields()->Clear();\n}\n\nbool response_block_headers::MergePartialFromCodedStream(\n    ::google::protobuf::io::CodedInputStream *input)\n{\n#define DO_(EXPRESSION) \\\n  if (!(EXPRESSION))    \\\n  goto failure\n  ::google::protobuf::uint32 tag;\n  // @@protoc_insertion_point(parse_start:libbitcoin.protocol.response.block_headers)\n  for (;;)\n  {\n    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);\n    tag = p.first;\n    if (!p.second)\n      goto handle_unusual;\n    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag))\n    {\n    // optional .libbitcoin.protocol.block_id next = 1;\n    case 1:\n    {\n      if (tag == 10)\n      {\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, mutable_next()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(18))\n        goto parse_top;\n      break;\n    }\n\n    // optional .libbitcoin.protocol.block_id top = 2;\n    case 2:\n    {\n      if (tag == 18)\n      {\n      parse_top:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, mutable_top()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(26))\n        goto parse_headers;\n      break;\n    }\n\n    // repeated .libbitcoin.protocol.block_header headers = 3;\n    case 3:\n    {\n      if (tag == 26)\n      {\n      parse_headers:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, add_headers()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(26))\n        goto parse_headers;\n      if (input->ExpectAtEnd())\n        goto success;\n      break;\n    }\n\n    default:\n    {\n    handle_unusual:\n      if (tag == 0 ||\n          ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n              ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP)\n      {\n        goto success;\n      }\n      DO_(::google::protobuf::internal::WireFormat::SkipField(\n          input, tag, mutable_unknown_fields()));\n      break;\n    }\n    }\n  }\nsuccess:\n  // @@protoc_insertion_point(parse_success:libbitcoin.protocol.response.block_headers)\n  return true;\nfailure:\n  // @@protoc_insertion_point(parse_failure:libbitcoin.protocol.response.block_headers)\n  return false;\n#undef DO_\n}\n\nvoid response_block_headers::SerializeWithCachedSizes(\n    ::google::protobuf::io::CodedOutputStream *output) const\n{\n  // @@protoc_insertion_point(serialize_start:libbitcoin.protocol.response.block_headers)\n  // optional .libbitcoin.protocol.block_id next = 1;\n  if (has_next())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        1, this->next(), output);\n  }\n\n  // optional .libbitcoin.protocol.block_id top = 2;\n  if (has_top())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        2, this->top(), output);\n  }\n\n  // repeated .libbitcoin.protocol.block_header headers = 3;\n  for (int i = 0; i < this->headers_size(); i++)\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        3, this->headers(i), output);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n        unknown_fields(), output);\n  }\n  // @@protoc_insertion_point(serialize_end:libbitcoin.protocol.response.block_headers)\n}\n\n::google::protobuf::uint8 *response_block_headers::SerializeWithCachedSizesToArray(\n    ::google::protobuf::uint8 *target) const\n{\n  // @@protoc_insertion_point(serialize_to_array_start:libbitcoin.protocol.response.block_headers)\n  // optional .libbitcoin.protocol.block_id next = 1;\n  if (has_next())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            1, this->next(), target);\n  }\n\n  // optional .libbitcoin.protocol.block_id top = 2;\n  if (has_top())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            2, this->top(), target);\n  }\n\n  // repeated .libbitcoin.protocol.block_header headers = 3;\n  for (int i = 0; i < this->headers_size(); i++)\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            3, this->headers(i), target);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n        unknown_fields(), target);\n  }\n  // @@protoc_insertion_point(serialize_to_array_end:libbitcoin.protocol.response.block_headers)\n  return target;\n}\n\nint response_block_headers::ByteSize() const\n{\n  int total_size = 0;\n\n  if (_has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    // optional .libbitcoin.protocol.block_id next = 1;\n    if (has_next())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n                        this->next());\n    }\n\n    // optional .libbitcoin.protocol.block_id top = 2;\n    if (has_top())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n                        this->top());\n    }\n  }\n  // repeated .libbitcoin.protocol.block_header headers = 3;\n  total_size += 1 * this->headers_size();\n  for (int i = 0; i < this->headers_size(); i++)\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n            this->headers(i));\n  }\n\n  if (!unknown_fields().empty())\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n            unknown_fields());\n  }\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = total_size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n  return total_size;\n}\n\nvoid response_block_headers::MergeFrom(const ::google::protobuf::Message &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  const response_block_headers *source =\n      ::google::protobuf::internal::dynamic_cast_if_available<const response_block_headers *>(\n          &from);\n  if (source == NULL)\n  {\n    ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n  }\n  else\n  {\n    MergeFrom(*source);\n  }\n}\n\nvoid response_block_headers::MergeFrom(const response_block_headers &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  headers_.MergeFrom(from.headers_);\n  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    if (from.has_next())\n    {\n      mutable_next()->::libbitcoin::protocol::block_id::MergeFrom(from.next());\n    }\n    if (from.has_top())\n    {\n      mutable_top()->::libbitcoin::protocol::block_id::MergeFrom(from.top());\n    }\n  }\n  mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n}\n\nvoid response_block_headers::CopyFrom(const ::google::protobuf::Message &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nvoid response_block_headers::CopyFrom(const response_block_headers &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nbool response_block_headers::IsInitialized() const\n{\n\n  if (!::google::protobuf::internal::AllAreInitialized(this->headers()))\n    return false;\n  return true;\n}\n\nvoid response_block_headers::Swap(response_block_headers *other)\n{\n  if (other != this)\n  {\n    std::swap(next_, other->next_);\n    std::swap(top_, other->top_);\n    headers_.Swap(&other->headers_);\n    std::swap(_has_bits_[0], other->_has_bits_[0]);\n    _unknown_fields_.Swap(&other->_unknown_fields_);\n    std::swap(_cached_size_, other->_cached_size_);\n  }\n}\n\n::google::protobuf::Metadata response_block_headers::GetMetadata() const\n{\n  protobuf_AssignDescriptorsOnce();\n  ::google::protobuf::Metadata metadata;\n  metadata.descriptor = response_block_headers_descriptor_;\n  metadata.reflection = response_block_headers_reflection_;\n  return metadata;\n}\n\n// -------------------------------------------------------------------\n\n#ifndef _MSC_VER\nconst int response_transactions::kNextFieldNumber;\nconst int response_transactions::kTopFieldNumber;\nconst int response_transactions::kHashesFieldNumber;\nconst int response_transactions::kTransactionsFieldNumber;\nconst int response_transactions::kUtxosFieldNumber;\n#endif // !_MSC_VER\n\nresponse_transactions::response_transactions()\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  // @@protoc_insertion_point(constructor:libbitcoin.protocol.response.transactions)\n}\n\nvoid response_transactions::InitAsDefaultInstance()\n{\n  next_ = const_cast<::libbitcoin::protocol::block_id *>(&::libbitcoin::protocol::block_id::default_instance());\n  top_ = const_cast<::libbitcoin::protocol::block_id *>(&::libbitcoin::protocol::block_id::default_instance());\n}\n\nresponse_transactions::response_transactions(const response_transactions &from)\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  MergeFrom(from);\n  // @@protoc_insertion_point(copy_constructor:libbitcoin.protocol.response.transactions)\n}\n\nvoid response_transactions::SharedCtor()\n{\n  _cached_size_ = 0;\n  next_ = NULL;\n  top_ = NULL;\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n}\n\nresponse_transactions::~response_transactions()\n{\n  // @@protoc_insertion_point(destructor:libbitcoin.protocol.response.transactions)\n  SharedDtor();\n}\n\nvoid response_transactions::SharedDtor()\n{\n  if (this != default_instance_)\n  {\n    delete next_;\n    delete top_;\n  }\n}\n\nvoid response_transactions::SetCachedSize(int size) const\n{\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n}\nconst ::google::protobuf::Descriptor *response_transactions::descriptor()\n{\n  protobuf_AssignDescriptorsOnce();\n  return response_transactions_descriptor_;\n}\n\nconst response_transactions &response_transactions::default_instance()\n{\n  if (default_instance_ == NULL)\n    protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  return *default_instance_;\n}\n\nresponse_transactions *response_transactions::default_instance_ = NULL;\n\nresponse_transactions *response_transactions::New() const\n{\n  return new response_transactions;\n}\n\nvoid response_transactions::Clear()\n{\n  if (_has_bits_[0 / 32] & 3)\n  {\n    if (has_next())\n    {\n      if (next_ != NULL)\n        next_->::libbitcoin::protocol::block_id::Clear();\n    }\n    if (has_top())\n    {\n      if (top_ != NULL)\n        top_->::libbitcoin::protocol::block_id::Clear();\n    }\n  }\n  hashes_.Clear();\n  transactions_.Clear();\n  utxos_.Clear();\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n  mutable_unknown_fields()->Clear();\n}\n\nbool response_transactions::MergePartialFromCodedStream(\n    ::google::protobuf::io::CodedInputStream *input)\n{\n#define DO_(EXPRESSION) \\\n  if (!(EXPRESSION))    \\\n  goto failure\n  ::google::protobuf::uint32 tag;\n  // @@protoc_insertion_point(parse_start:libbitcoin.protocol.response.transactions)\n  for (;;)\n  {\n    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);\n    tag = p.first;\n    if (!p.second)\n      goto handle_unusual;\n    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag))\n    {\n    // optional .libbitcoin.protocol.block_id next = 1;\n    case 1:\n    {\n      if (tag == 10)\n      {\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, mutable_next()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(18))\n        goto parse_top;\n      break;\n    }\n\n    // optional .libbitcoin.protocol.block_id top = 2;\n    case 2:\n    {\n      if (tag == 18)\n      {\n      parse_top:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, mutable_top()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(26))\n        goto parse_hashes;\n      break;\n    }\n\n    // repeated .libbitcoin.protocol.tx_hash_result hashes = 3;\n    case 3:\n    {\n      if (tag == 26)\n      {\n      parse_hashes:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, add_hashes()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(26))\n        goto parse_hashes;\n      if (input->ExpectTag(34))\n        goto parse_transactions;\n      break;\n    }\n\n    // repeated .libbitcoin.protocol.tx_result transactions = 4;\n    case 4:\n    {\n      if (tag == 34)\n      {\n      parse_transactions:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, add_transactions()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(34))\n        goto parse_transactions;\n      if (input->ExpectTag(42))\n        goto parse_utxos;\n      break;\n    }\n\n    // repeated .libbitcoin.protocol.utxo_result utxos = 5;\n    case 5:\n    {\n      if (tag == 42)\n      {\n      parse_utxos:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, add_utxos()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(42))\n        goto parse_utxos;\n      if (input->ExpectAtEnd())\n        goto success;\n      break;\n    }\n\n    default:\n    {\n    handle_unusual:\n      if (tag == 0 ||\n          ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n              ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP)\n      {\n        goto success;\n      }\n      DO_(::google::protobuf::internal::WireFormat::SkipField(\n          input, tag, mutable_unknown_fields()));\n      break;\n    }\n    }\n  }\nsuccess:\n  // @@protoc_insertion_point(parse_success:libbitcoin.protocol.response.transactions)\n  return true;\nfailure:\n  // @@protoc_insertion_point(parse_failure:libbitcoin.protocol.response.transactions)\n  return false;\n#undef DO_\n}\n\nvoid response_transactions::SerializeWithCachedSizes(\n    ::google::protobuf::io::CodedOutputStream *output) const\n{\n  // @@protoc_insertion_point(serialize_start:libbitcoin.protocol.response.transactions)\n  // optional .libbitcoin.protocol.block_id next = 1;\n  if (has_next())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        1, this->next(), output);\n  }\n\n  // optional .libbitcoin.protocol.block_id top = 2;\n  if (has_top())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        2, this->top(), output);\n  }\n\n  // repeated .libbitcoin.protocol.tx_hash_result hashes = 3;\n  for (int i = 0; i < this->hashes_size(); i++)\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        3, this->hashes(i), output);\n  }\n\n  // repeated .libbitcoin.protocol.tx_result transactions = 4;\n  for (int i = 0; i < this->transactions_size(); i++)\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        4, this->transactions(i), output);\n  }\n\n  // repeated .libbitcoin.protocol.utxo_result utxos = 5;\n  for (int i = 0; i < this->utxos_size(); i++)\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        5, this->utxos(i), output);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n        unknown_fields(), output);\n  }\n  // @@protoc_insertion_point(serialize_end:libbitcoin.protocol.response.transactions)\n}\n\n::google::protobuf::uint8 *response_transactions::SerializeWithCachedSizesToArray(\n    ::google::protobuf::uint8 *target) const\n{\n  // @@protoc_insertion_point(serialize_to_array_start:libbitcoin.protocol.response.transactions)\n  // optional .libbitcoin.protocol.block_id next = 1;\n  if (has_next())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            1, this->next(), target);\n  }\n\n  // optional .libbitcoin.protocol.block_id top = 2;\n  if (has_top())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            2, this->top(), target);\n  }\n\n  // repeated .libbitcoin.protocol.tx_hash_result hashes = 3;\n  for (int i = 0; i < this->hashes_size(); i++)\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            3, this->hashes(i), target);\n  }\n\n  // repeated .libbitcoin.protocol.tx_result transactions = 4;\n  for (int i = 0; i < this->transactions_size(); i++)\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            4, this->transactions(i), target);\n  }\n\n  // repeated .libbitcoin.protocol.utxo_result utxos = 5;\n  for (int i = 0; i < this->utxos_size(); i++)\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            5, this->utxos(i), target);\n  }\n\n  if (!unknown_fields().empty())\n  {\n    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n        unknown_fields(), target);\n  }\n  // @@protoc_insertion_point(serialize_to_array_end:libbitcoin.protocol.response.transactions)\n  return target;\n}\n\nint response_transactions::ByteSize() const\n{\n  int total_size = 0;\n\n  if (_has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    // optional .libbitcoin.protocol.block_id next = 1;\n    if (has_next())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n                        this->next());\n    }\n\n    // optional .libbitcoin.protocol.block_id top = 2;\n    if (has_top())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n                        this->top());\n    }\n  }\n  // repeated .libbitcoin.protocol.tx_hash_result hashes = 3;\n  total_size += 1 * this->hashes_size();\n  for (int i = 0; i < this->hashes_size(); i++)\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n            this->hashes(i));\n  }\n\n  // repeated .libbitcoin.protocol.tx_result transactions = 4;\n  total_size += 1 * this->transactions_size();\n  for (int i = 0; i < this->transactions_size(); i++)\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n            this->transactions(i));\n  }\n\n  // repeated .libbitcoin.protocol.utxo_result utxos = 5;\n  total_size += 1 * this->utxos_size();\n  for (int i = 0; i < this->utxos_size(); i++)\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n            this->utxos(i));\n  }\n\n  if (!unknown_fields().empty())\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n            unknown_fields());\n  }\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = total_size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n  return total_size;\n}\n\nvoid response_transactions::MergeFrom(const ::google::protobuf::Message &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  const response_transactions *source =\n      ::google::protobuf::internal::dynamic_cast_if_available<const response_transactions *>(\n          &from);\n  if (source == NULL)\n  {\n    ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n  }\n  else\n  {\n    MergeFrom(*source);\n  }\n}\n\nvoid response_transactions::MergeFrom(const response_transactions &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  hashes_.MergeFrom(from.hashes_);\n  transactions_.MergeFrom(from.transactions_);\n  utxos_.MergeFrom(from.utxos_);\n  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    if (from.has_next())\n    {\n      mutable_next()->::libbitcoin::protocol::block_id::MergeFrom(from.next());\n    }\n    if (from.has_top())\n    {\n      mutable_top()->::libbitcoin::protocol::block_id::MergeFrom(from.top());\n    }\n  }\n  mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n}\n\nvoid response_transactions::CopyFrom(const ::google::protobuf::Message &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nvoid response_transactions::CopyFrom(const response_transactions &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nbool response_transactions::IsInitialized() const\n{\n\n  if (!::google::protobuf::internal::AllAreInitialized(this->hashes()))\n    return false;\n  if (!::google::protobuf::internal::AllAreInitialized(this->transactions()))\n    return false;\n  if (!::google::protobuf::internal::AllAreInitialized(this->utxos()))\n    return false;\n  return true;\n}\n\nvoid response_transactions::Swap(response_transactions *other)\n{\n  if (other != this)\n  {\n    std::swap(next_, other->next_);\n    std::swap(top_, other->top_);\n    hashes_.Swap(&other->hashes_);\n    transactions_.Swap(&other->transactions_);\n    utxos_.Swap(&other->utxos_);\n    std::swap(_has_bits_[0], other->_has_bits_[0]);\n    _unknown_fields_.Swap(&other->_unknown_fields_);\n    std::swap(_cached_size_, other->_cached_size_);\n  }\n}\n\n::google::protobuf::Metadata response_transactions::GetMetadata() const\n{\n  protobuf_AssignDescriptorsOnce();\n  ::google::protobuf::Metadata metadata;\n  metadata.descriptor = response_transactions_descriptor_;\n  metadata.reflection = response_transactions_reflection_;\n  return metadata;\n}\n\n// -------------------------------------------------------------------\n\n#ifndef _MSC_VER\nconst int response::kIdFieldNumber;\nconst int response::kStatusFieldNumber;\nconst int response::kGetBlockHeadersResponseFieldNumber;\nconst int response::kGetTransactionsResponseFieldNumber;\nconst int response::kPostTransactionSucceededFieldNumber;\nconst int response::kValidateTransactionSucceededFieldNumber;\nconst int response::kPostBlockSucceededFieldNumber;\nconst int response::kValidateBlockSucceededFieldNumber;\n#endif // !_MSC_VER\n\nresponse::response()\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  // @@protoc_insertion_point(constructor:libbitcoin.protocol.response)\n}\n\nvoid response::InitAsDefaultInstance()\n{\n  response_default_oneof_instance_->get_block_headers_response_ = const_cast<::libbitcoin::protocol::response_block_headers *>(&::libbitcoin::protocol::response_block_headers::default_instance());\n  response_default_oneof_instance_->get_transactions_response_ = const_cast<::libbitcoin::protocol::response_transactions *>(&::libbitcoin::protocol::response_transactions::default_instance());\n  response_default_oneof_instance_->post_transaction_succeeded_ = false;\n  response_default_oneof_instance_->validate_tx_engine_succeeded_ = false;\n  response_default_oneof_instance_->post_block_succeeded_ = false;\n  response_default_oneof_instance_->validate_block_succeeded_ = false;\n}\n\nresponse::response(const response &from)\n    : ::google::protobuf::Message()\n{\n  SharedCtor();\n  MergeFrom(from);\n  // @@protoc_insertion_point(copy_constructor:libbitcoin.protocol.response)\n}\n\nvoid response::SharedCtor()\n{\n  _cached_size_ = 0;\n  id_ = 0u;\n  status_ = 0;\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n  clear_has_response_type();\n}\n\nresponse::~response()\n{\n  // @@protoc_insertion_point(destructor:libbitcoin.protocol.response)\n  SharedDtor();\n}\n\nvoid response::SharedDtor()\n{\n  if (has_response_type())\n  {\n    clear_response_type();\n  }\n  if (this != default_instance_)\n  {\n  }\n}\n\nvoid response::SetCachedSize(int size) const\n{\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n}\nconst ::google::protobuf::Descriptor *response::descriptor()\n{\n  protobuf_AssignDescriptorsOnce();\n  return response_descriptor_;\n}\n\nconst response &response::default_instance()\n{\n  if (default_instance_ == NULL)\n    protobuf_AddDesc_bitcoin_2fprotocol_2finterface_2eproto();\n  return *default_instance_;\n}\n\nresponse *response::default_instance_ = NULL;\n\nresponse *response::New() const\n{\n  return new response;\n}\n\nvoid response::clear_response_type()\n{\n  switch (response_type_case())\n  {\n  case kGetBlockHeadersResponse:\n  {\n    delete response_type_.get_block_headers_response_;\n    break;\n  }\n  case kGetTransactionsResponse:\n  {\n    delete response_type_.get_transactions_response_;\n    break;\n  }\n  case kPostTransactionSucceeded:\n  {\n    // No need to clear\n    break;\n  }\n  case kValidateTransactionSucceeded:\n  {\n    // No need to clear\n    break;\n  }\n  case kPostBlockSucceeded:\n  {\n    // No need to clear\n    break;\n  }\n  case kValidateBlockSucceeded:\n  {\n    // No need to clear\n    break;\n  }\n  case RESPONSE_TYPE_NOT_SET:\n  {\n    break;\n  }\n  }\n  _oneof_case_[0] = RESPONSE_TYPE_NOT_SET;\n}\n\nvoid response::Clear()\n{\n  _extensions_.Clear();\n#define OFFSET_OF_FIELD_(f) (reinterpret_cast<char *>(                   \\\n                                 &reinterpret_cast<response *>(16)->f) - \\\n                             reinterpret_cast<char *>(16))\n\n#define ZR_(first, last)                                  \\\n  do                                                      \\\n  {                                                       \\\n    size_t f = OFFSET_OF_FIELD_(first);                   \\\n    size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \\\n    ::memset(&first, 0, n);                               \\\n  } while (0)\n\n  ZR_(id_, status_);\n\n#undef OFFSET_OF_FIELD_\n#undef ZR_\n\n  clear_response_type();\n  ::memset(_has_bits_, 0, sizeof(_has_bits_));\n  mutable_unknown_fields()->Clear();\n}\n\nbool response::MergePartialFromCodedStream(\n    ::google::protobuf::io::CodedInputStream *input)\n{\n#define DO_(EXPRESSION) \\\n  if (!(EXPRESSION))    \\\n  goto failure\n  ::google::protobuf::uint32 tag;\n  // @@protoc_insertion_point(parse_start:libbitcoin.protocol.response)\n  for (;;)\n  {\n    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);\n    tag = p.first;\n    if (!p.second)\n      goto handle_unusual;\n    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag))\n    {\n    // required uint32 id = 1;\n    case 1:\n    {\n      if (tag == 8)\n      {\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>(\n            input, &id_)));\n        set_has_id();\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(16))\n        goto parse_status;\n      break;\n    }\n\n    // optional sint32 status = 2;\n    case 2:\n    {\n      if (tag == 16)\n      {\n      parse_status:\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_SINT32>(\n            input, &status_)));\n        set_has_status();\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(26))\n        goto parse_get_block_headers_response;\n      break;\n    }\n\n    // optional .libbitcoin.protocol.response.block_headers get_block_headers_response = 3;\n    case 3:\n    {\n      if (tag == 26)\n      {\n      parse_get_block_headers_response:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, mutable_get_block_headers_response()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(34))\n        goto parse_get_transactions_response;\n      break;\n    }\n\n    // optional .libbitcoin.protocol.response.transactions get_transactions_response = 4;\n    case 4:\n    {\n      if (tag == 34)\n      {\n      parse_get_transactions_response:\n        DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n            input, mutable_get_transactions_response()));\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(40))\n        goto parse_post_transaction_succeeded;\n      break;\n    }\n\n    // optional bool post_transaction_succeeded = 5;\n    case 5:\n    {\n      if (tag == 40)\n      {\n      parse_post_transaction_succeeded:\n        clear_response_type();\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(\n            input, &response_type_.post_transaction_succeeded_)));\n        set_has_post_transaction_succeeded();\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(48))\n        goto parse_validate_tx_engine_succeeded;\n      break;\n    }\n\n    // optional bool validate_tx_engine_succeeded = 6;\n    case 6:\n    {\n      if (tag == 48)\n      {\n      parse_validate_tx_engine_succeeded:\n        clear_response_type();\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(\n            input, &response_type_.validate_tx_engine_succeeded_)));\n        set_has_validate_tx_engine_succeeded();\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(56))\n        goto parse_post_block_succeeded;\n      break;\n    }\n\n    // optional bool post_block_succeeded = 7;\n    case 7:\n    {\n      if (tag == 56)\n      {\n      parse_post_block_succeeded:\n        clear_response_type();\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(\n            input, &response_type_.post_block_succeeded_)));\n        set_has_post_block_succeeded();\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectTag(64))\n        goto parse_validate_block_succeeded;\n      break;\n    }\n\n    // optional bool validate_block_succeeded = 8;\n    case 8:\n    {\n      if (tag == 64)\n      {\n      parse_validate_block_succeeded:\n        clear_response_type();\n        DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n             bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(\n            input, &response_type_.validate_block_succeeded_)));\n        set_has_validate_block_succeeded();\n      }\n      else\n      {\n        goto handle_unusual;\n      }\n      if (input->ExpectAtEnd())\n        goto success;\n      break;\n    }\n\n    default:\n    {\n    handle_unusual:\n      if (tag == 0 ||\n          ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==\n              ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP)\n      {\n        goto success;\n      }\n      if ((800u <= tag && tag < 1600u))\n      {\n        DO_(_extensions_.ParseField(tag, input, default_instance_,\n                                    mutable_unknown_fields()));\n        continue;\n      }\n      DO_(::google::protobuf::internal::WireFormat::SkipField(\n          input, tag, mutable_unknown_fields()));\n      break;\n    }\n    }\n  }\nsuccess:\n  // @@protoc_insertion_point(parse_success:libbitcoin.protocol.response)\n  return true;\nfailure:\n  // @@protoc_insertion_point(parse_failure:libbitcoin.protocol.response)\n  return false;\n#undef DO_\n}\n\nvoid response::SerializeWithCachedSizes(\n    ::google::protobuf::io::CodedOutputStream *output) const\n{\n  // @@protoc_insertion_point(serialize_start:libbitcoin.protocol.response)\n  // required uint32 id = 1;\n  if (has_id())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->id(), output);\n  }\n\n  // optional sint32 status = 2;\n  if (has_status())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteSInt32(2, this->status(), output);\n  }\n\n  // optional .libbitcoin.protocol.response.block_headers get_block_headers_response = 3;\n  if (has_get_block_headers_response())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        3, this->get_block_headers_response(), output);\n  }\n\n  // optional .libbitcoin.protocol.response.transactions get_transactions_response = 4;\n  if (has_get_transactions_response())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(\n        4, this->get_transactions_response(), output);\n  }\n\n  // optional bool post_transaction_succeeded = 5;\n  if (has_post_transaction_succeeded())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteBool(5, this->post_transaction_succeeded(), output);\n  }\n\n  // optional bool validate_tx_engine_succeeded = 6;\n  if (has_validate_tx_engine_succeeded())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteBool(6, this->validate_tx_engine_succeeded(), output);\n  }\n\n  // optional bool post_block_succeeded = 7;\n  if (has_post_block_succeeded())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteBool(7, this->post_block_succeeded(), output);\n  }\n\n  // optional bool validate_block_succeeded = 8;\n  if (has_validate_block_succeeded())\n  {\n    ::google::protobuf::internal::WireFormatLite::WriteBool(8, this->validate_block_succeeded(), output);\n  }\n\n  // Extension range [100, 200)\n  _extensions_.SerializeWithCachedSizes(\n      100, 200, output);\n\n  if (!unknown_fields().empty())\n  {\n    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(\n        unknown_fields(), output);\n  }\n  // @@protoc_insertion_point(serialize_end:libbitcoin.protocol.response)\n}\n\n::google::protobuf::uint8 *response::SerializeWithCachedSizesToArray(\n    ::google::protobuf::uint8 *target) const\n{\n  // @@protoc_insertion_point(serialize_to_array_start:libbitcoin.protocol.response)\n  // required uint32 id = 1;\n  if (has_id())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->id(), target);\n  }\n\n  // optional sint32 status = 2;\n  if (has_status())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteSInt32ToArray(2, this->status(), target);\n  }\n\n  // optional .libbitcoin.protocol.response.block_headers get_block_headers_response = 3;\n  if (has_get_block_headers_response())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            3, this->get_block_headers_response(), target);\n  }\n\n  // optional .libbitcoin.protocol.response.transactions get_transactions_response = 4;\n  if (has_get_transactions_response())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::\n        WriteMessageNoVirtualToArray(\n            4, this->get_transactions_response(), target);\n  }\n\n  // optional bool post_transaction_succeeded = 5;\n  if (has_post_transaction_succeeded())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(5, this->post_transaction_succeeded(), target);\n  }\n\n  // optional bool validate_tx_engine_succeeded = 6;\n  if (has_validate_tx_engine_succeeded())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(6, this->validate_tx_engine_succeeded(), target);\n  }\n\n  // optional bool post_block_succeeded = 7;\n  if (has_post_block_succeeded())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(7, this->post_block_succeeded(), target);\n  }\n\n  // optional bool validate_block_succeeded = 8;\n  if (has_validate_block_succeeded())\n  {\n    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(8, this->validate_block_succeeded(), target);\n  }\n\n  // Extension range [100, 200)\n  target = _extensions_.SerializeWithCachedSizesToArray(\n      100, 200, target);\n\n  if (!unknown_fields().empty())\n  {\n    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(\n        unknown_fields(), target);\n  }\n  // @@protoc_insertion_point(serialize_to_array_end:libbitcoin.protocol.response)\n  return target;\n}\n\nint response::ByteSize() const\n{\n  int total_size = 0;\n\n  if (_has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    // required uint32 id = 1;\n    if (has_id())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::UInt32Size(\n                        this->id());\n    }\n\n    // optional sint32 status = 2;\n    if (has_status())\n    {\n      total_size += 1 +\n                    ::google::protobuf::internal::WireFormatLite::SInt32Size(\n                        this->status());\n    }\n  }\n  switch (response_type_case())\n  {\n  // optional .libbitcoin.protocol.response.block_headers get_block_headers_response = 3;\n  case kGetBlockHeadersResponse:\n  {\n    total_size += 1 +\n                  ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n                      this->get_block_headers_response());\n    break;\n  }\n  // optional .libbitcoin.protocol.response.transactions get_transactions_response = 4;\n  case kGetTransactionsResponse:\n  {\n    total_size += 1 +\n                  ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(\n                      this->get_transactions_response());\n    break;\n  }\n  // optional bool post_transaction_succeeded = 5;\n  case kPostTransactionSucceeded:\n  {\n    total_size += 1 + 1;\n    break;\n  }\n  // optional bool validate_tx_engine_succeeded = 6;\n  case kValidateTransactionSucceeded:\n  {\n    total_size += 1 + 1;\n    break;\n  }\n  // optional bool post_block_succeeded = 7;\n  case kPostBlockSucceeded:\n  {\n    total_size += 1 + 1;\n    break;\n  }\n  // optional bool validate_block_succeeded = 8;\n  case kValidateBlockSucceeded:\n  {\n    total_size += 1 + 1;\n    break;\n  }\n  case RESPONSE_TYPE_NOT_SET:\n  {\n    break;\n  }\n  }\n  total_size += _extensions_.ByteSize();\n\n  if (!unknown_fields().empty())\n  {\n    total_size +=\n        ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(\n            unknown_fields());\n  }\n  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();\n  _cached_size_ = total_size;\n  GOOGLE_SAFE_CONCURRENT_WRITES_END();\n  return total_size;\n}\n\nvoid response::MergeFrom(const ::google::protobuf::Message &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  const response *source =\n      ::google::protobuf::internal::dynamic_cast_if_available<const response *>(\n          &from);\n  if (source == NULL)\n  {\n    ::google::protobuf::internal::ReflectionOps::Merge(from, this);\n  }\n  else\n  {\n    MergeFrom(*source);\n  }\n}\n\nvoid response::MergeFrom(const response &from)\n{\n  GOOGLE_CHECK_NE(&from, this);\n  switch (from.response_type_case())\n  {\n  case kGetBlockHeadersResponse:\n  {\n    mutable_get_block_headers_response()->::libbitcoin::protocol::response_block_headers::MergeFrom(from.get_block_headers_response());\n    break;\n  }\n  case kGetTransactionsResponse:\n  {\n    mutable_get_transactions_response()->::libbitcoin::protocol::response_transactions::MergeFrom(from.get_transactions_response());\n    break;\n  }\n  case kPostTransactionSucceeded:\n  {\n    set_post_transaction_succeeded(from.post_transaction_succeeded());\n    break;\n  }\n  case kValidateTransactionSucceeded:\n  {\n    set_validate_tx_engine_succeeded(from.validate_tx_engine_succeeded());\n    break;\n  }\n  case kPostBlockSucceeded:\n  {\n    set_post_block_succeeded(from.post_block_succeeded());\n    break;\n  }\n  case kValidateBlockSucceeded:\n  {\n    set_validate_block_succeeded(from.validate_block_succeeded());\n    break;\n  }\n  case RESPONSE_TYPE_NOT_SET:\n  {\n    break;\n  }\n  }\n  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32)))\n  {\n    if (from.has_id())\n    {\n      set_id(from.id());\n    }\n    if (from.has_status())\n    {\n      set_status(from.status());\n    }\n  }\n  _extensions_.MergeFrom(from._extensions_);\n  mutable_unknown_fields()->MergeFrom(from.unknown_fields());\n}\n\nvoid response::CopyFrom(const ::google::protobuf::Message &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nvoid response::CopyFrom(const response &from)\n{\n  if (&from == this)\n    return;\n  Clear();\n  MergeFrom(from);\n}\n\nbool response::IsInitialized() const\n{\n  if ((_has_bits_[0] & 0x00000001) != 0x00000001)\n    return false;\n\n  if (has_get_block_headers_response())\n  {\n    if (!this->get_block_headers_response().IsInitialized())\n      return false;\n  }\n  if (has_get_transactions_response())\n  {\n    if (!this->get_transactions_response().IsInitialized())\n      return false;\n  }\n\n  if (!_extensions_.IsInitialized())\n    return false;\n  return true;\n}\n\nvoid response::Swap(response *other)\n{\n  if (other != this)\n  {\n    std::swap(id_, other->id_);\n    std::swap(status_, other->status_);\n    std::swap(response_type_, other->response_type_);\n    std::swap(_oneof_case_[0], other->_oneof_case_[0]);\n    std::swap(_has_bits_[0], other->_has_bits_[0]);\n    _unknown_fields_.Swap(&other->_unknown_fields_);\n    std::swap(_cached_size_, other->_cached_size_);\n    _extensions_.Swap(&other->_extensions_);\n  }\n}\n\n::google::protobuf::Metadata response::GetMetadata() const\n{\n  protobuf_AssignDescriptorsOnce();\n  ::google::protobuf::Metadata metadata;\n  metadata.descriptor = response_descriptor_;\n  metadata.reflection = response_reflection_;\n  return metadata;\n}\n\n// @@protoc_insertion_point(namespace_scope)\n\n} // namespace protocol\n} // namespace libbitcoin\n\n// @@protoc_insertion_point(global_scope)\n\n#endif\n"
  },
  {
    "path": "src/UChain/protocol/packet.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifdef UC_VERSION4\n\n#include <UChain/protocol/packet.hpp>\n\n#include <UChain/coin.hpp>\n#include <UChain/protocol/zmq/msg.hpp>\n#include <UChain/protocol/zmq/socket.hpp>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\n\npacket::packet()\n{\n}\n\nconst data_chunk packet::origin() const\n{\n    return origin_;\n}\n\nconst data_chunk packet::destination() const\n{\n    return destination_;\n}\n\nvoid packet::set_destination(const data_chunk &destination)\n{\n    destination_ = destination;\n}\n\nbool packet::receive(zmq::socket &socket)\n{\n    zmq::message message;\n\n    if (socket.receive(message) != error::success || message.empty())\n        return false;\n\n    // Optional - ROUTER sockets strip this.\n    if (message.size() > 2)\n        origin_ = message.dequeue_data();\n\n    // Remove empty delimiter frame.\n    message.dequeue();\n\n    return decode_payload(message.dequeue_data()) && message.empty();\n}\n\n////bool packet::receive(const std::shared_ptr<zmq::socket>& socket)\n////{\n////    return (socket != nullptr) && receive(*(socket.get()));\n////}\n\nbool packet::send(zmq::socket &socket)\n{\n    zmq::message message;\n\n    // Optionally encode the destination.\n    if (!destination_.empty())\n        message.enqueue(destination_);\n\n    // Add empty delimiter frame.\n    message.enqueue(data_chunk{});\n\n    return encode_payload(message) && socket.send(message) == error::success;\n}\n\n////bool packet::send(const std::shared_ptr<zmq::socket>& socket)\n////{\n////    return (socket != nullptr) && send(*(socket.get()));\n////}\n\n} // namespace protocol\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "src/UChain/protocol/request_packet.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifdef UC_VERSION4\n\n#include <UChain/protocol/packet.hpp>\n\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/protocol/interface.pb.h>\n#include <UChain/protocol/request_packet.hpp>\n#include <UChain/protocol/zmq/msg.hpp>\n#include <UChain/protocol/zmq/socket.hpp>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\n\nrequest_packet::request_packet()\n    : request_(nullptr)\n{\n}\n\nstd::shared_ptr<request> request_packet::get_request() const\n{\n    return request_;\n}\n\nvoid request_packet::set_request(std::shared_ptr<request> payload)\n{\n    request_ = payload;\n}\n\nbool request_packet::encode_payload(zmq::message &message) const\n{\n    if (!request_)\n        return false;\n\n    const auto data = request_->SerializeAsString();\n    message.append({data.begin(), data.end()});\n    return true;\n}\n\nbool request_packet::decode_payload(const data_chunk &payload)\n{\n    const auto data = std::make_shared<request>();\n\n    if (!data->ParseFromString({payload.begin(), payload.end()}))\n        return false;\n\n    request_ = data;\n    return true;\n}\n\n} // namespace protocol\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "src/UChain/protocol/response_packet.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifdef UC_VERSION4\n\n#include <UChain/protocol/packet.hpp>\n\n#include <memory>\n#include <UChain/coin.hpp>\n#include <UChain/protocol/interface.pb.h>\n#include <UChain/protocol/response_packet.hpp>\n#include <UChain/protocol/zmq/msg.hpp>\n#include <UChain/protocol/zmq/socket.hpp>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\n\nresponse_packet::response_packet()\n    : response_(nullptr)\n{\n}\n\nstd::shared_ptr<response> response_packet::get_response() const\n{\n    return response_;\n}\n\nvoid response_packet::set_response(std::shared_ptr<response> payload)\n{\n    response_ = payload;\n}\n\nbool response_packet::encode_payload(zmq::message &message) const\n{\n    if (!response_)\n        return false;\n\n    const auto data = response_->SerializeAsString();\n    message.append({data.begin(), data.end()});\n    return true;\n}\n\nbool response_packet::decode_payload(const data_chunk &payload)\n{\n    const auto data = std::make_shared<response>();\n\n    if (!data->ParseFromString({payload.begin(), payload.end()}))\n        return false;\n\n    response_ = data;\n    return true;\n}\n\n} // namespace protocol\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "src/UChain/protocol/zmq/authenticator.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/protocol/zmq/authenticator.hpp>\n\n#include <functional>\n#include <future>\n#include <string>\n#include <zmq.h>\n#include <UChain/coin.hpp>\n#include <UChain/protocol/zmq/msg.hpp>\n#include <UChain/protocol/zmq/context.hpp>\n#include <UChain/protocol/zmq/poller.hpp>\n#include <UChain/protocol/zmq/socket.hpp>\n#include <UChain/protocol/zmq/worker.hpp>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\nnamespace zmq\n{\n\n// ZAP endpoint, see: rfc.zeromq.org/spec:27/ZAP\nconst config::endpoint authenticator::endpoint(\"inproc://zeromq.zap.01\");\n\n// There may be only one authenticator per process.\nauthenticator::authenticator(threadpool &pool)\n    : worker(pool),\n      context_(false),\n      require_address_(false)\n{\n}\n\nauthenticator::~authenticator()\n{\n    stop();\n}\n\nauthenticator::operator context &()\n{\n    return context_;\n}\n\n// Restartable after stop and not started on construct.\nbool authenticator::start()\n{\n    // Context is thread safe, this critical section is for start atomicity.\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    unique_lock lock(mutex_);\n\n    return context_.start() && worker::start();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nbool authenticator::stop()\n{\n    // Context is thread safe, this critical section is for stop atomicity.\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    unique_lock lock(mutex_);\n\n    // Stop the context first in case a blocking proxy is in use.\n    return context_.stop() && worker::stop();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n// github.com/zeromq/rfc/blob/master/src/spec_27.c\nvoid authenticator::work()\n{\n    socket router(context_, zmq::socket::role::router);\n\n    if (!started(router.bind(endpoint) == (code)error::success))\n        return;\n\n    poller poller;\n    poller.add(router);\n\n    while (!poller.terminated() && !stopped())\n    {\n        if (!poller.wait().contains(router.id()))\n            continue;\n\n        data_chunk origin;\n        data_chunk delimiter;\n        std::string version;\n        std::string sequence;\n        std::string status_code;\n        std::string status_text;\n        std::string userid;\n        std::string metadata;\n\n        message request;\n        auto ec = router.receive(request);\n\n        if (ec != (code)error::success || request.size() < 8)\n        {\n            status_code = \"500\";\n            status_text = \"Internal error.\";\n        }\n        else\n        {\n            origin = request.dequeue_data();\n            delimiter = request.dequeue_data();\n            version = request.dequeue_text();\n            sequence = request.dequeue_text();\n            const auto domain = request.dequeue_text();\n            const auto address = request.dequeue_text();\n            const auto identity = request.dequeue_text();\n            const auto mechanism = request.dequeue_text();\n\n            // ZAP authentication should not occur with an empty domain.\n            if (origin.empty() || !delimiter.empty() || version != \"1.0\" ||\n                sequence.empty() || domain.empty() || !identity.empty())\n            {\n                status_code = \"500\";\n                status_text = \"Internal error.\";\n            }\n            else if (!allowed_address(address))\n            {\n                // Address restrictions are independent of mechanisms.\n                status_code = \"400\";\n                status_text = \"Address not enabled for access.\";\n            }\n            else\n            {\n                if (mechanism == \"NULL\")\n                {\n                    if (request.size() != 0)\n                    {\n                        status_code = \"400\";\n                        status_text = \"Incorrect NULL parameterization.\";\n                    }\n                    else if (!allowed_weak(domain))\n                    {\n                        status_code = \"400\";\n                        status_text = \"NULL mechanism not authorized.\";\n                    }\n                    else\n                    {\n                        // It is more efficient to use an unsecured context or\n                        // to not start the authenticator, but this works too.\n                        status_code = \"200\";\n                        status_text = \"OK\";\n                        userid = \"anonymous\";\n                    }\n                }\n                else if (mechanism == \"CURVE\")\n                {\n                    if (request.size() != 1)\n                    {\n                        status_code = \"400\";\n                        status_text = \"Incorrect CURVE parameterization.\";\n                    }\n                    else\n                    {\n                        hash_digest public_key;\n\n                        if (!request.dequeue(public_key))\n                        {\n                            status_code = \"400\";\n                            status_text = \"Invalid public key.\";\n                        }\n                        else if (!allowed_key(public_key))\n                        {\n                            status_code = \"400\";\n                            status_text = \"Public key not authorized.\";\n                        }\n                        else\n                        {\n                            status_code = \"200\";\n                            status_text = \"OK\";\n                            userid = \"unspecified\";\n                        }\n                    }\n                }\n                else if (mechanism == \"PLAIN\")\n                {\n                    if (request.size() != 2)\n                    {\n                        status_code = \"400\";\n                        status_text = \"Incorrect PLAIN parameterization.\";\n                    }\n                    else\n                    {\n                        ////userid = request.dequeue_text();\n                        ////const auto password = request.dequeue_text();\n                        status_code = \"400\";\n                        status_text = \"PLAIN mechanism not supported.\";\n                    }\n                }\n                else\n                {\n                    status_code = \"400\";\n                    status_text = \"Security mechanism not supported.\";\n                }\n            }\n        }\n\n        message response;\n        response.enqueue(origin);\n        response.enqueue(delimiter);\n        response.enqueue(version);\n        response.enqueue(sequence);\n        response.enqueue(status_code);\n        response.enqueue(status_text);\n        response.enqueue(userid);\n        response.enqueue(metadata);\n\n        DEBUG_ONLY(ec =)\n        router.send(response);\n        BITCOIN_ASSERT_MSG(!ec, \"Failed to send ZAP response.\");\n    }\n\n    finished(router.stop());\n}\n\n// This must be called on the socket thread.\n// Addresses and client keys may be updated after this is applied.\n// The configuration at the time of this call determines the mode of security.\nbool authenticator::apply(socket &socket, const std::string &domain,\n                          bool secure)\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    mutex_.lock_shared();\n    const auto private_key = private_key_;\n    const auto have_public_keys = !keys_.empty();\n    const auto require_address = require_address_;\n    mutex_.unlock_shared();\n    ///////////////////////////////////////////////////////////////////////////\n\n    // A private server key is required if there are public client keys.\n    if (have_public_keys && !private_key)\n        return false;\n\n    if (!secure)\n    {\n        if (require_address)\n        {\n            // These persist after a socket closes so don't reuse domain names.\n            weak_domains_.emplace(domain);\n            return socket.set_authentication_domain(domain);\n        }\n\n        // There are no address or curve rules to apply so bypass ZAP.\n        return true;\n    }\n\n    if (private_key)\n    {\n        return socket.set_private_key(private_key) &&\n               socket.set_curve_server() &&\n               socket.set_authentication_domain(domain);\n    }\n\n    // We do not have a private key to set so we cannot set secure.\n    return false;\n}\n\nvoid authenticator::set_private_key(const config::sodium &private_key)\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    unique_lock lock(mutex_);\n\n    private_key_ = private_key;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nbool authenticator::allowed_address(const std::string &ip_address) const\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    shared_lock lock(mutex_);\n\n    return !require_address_ || adresses_.find(ip_address) != adresses_.end();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nbool authenticator::allowed_key(const hash_digest &public_key) const\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    shared_lock lock(mutex_);\n\n    return keys_.empty() || keys_.find(public_key) != keys_.end();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nbool authenticator::allowed_weak(const std::string &domain) const\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    shared_lock lock(mutex_);\n\n    return weak_domains_.find(domain) != weak_domains_.end();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid authenticator::allow(const hash_digest &public_key)\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    unique_lock lock(mutex_);\n\n    keys_.emplace(public_key);\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid authenticator::allow(const config::authority &address)\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    unique_lock lock(mutex_);\n\n    require_address_ = true;\n    adresses_.emplace(address.to_hostname(), true);\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid authenticator::deny(const config::authority &address)\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    unique_lock lock(mutex_);\n\n    // Denial is effective independent of whitelisting.\n    adresses_.emplace(address.to_hostname(), false);\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n} // namespace zmq\n} // namespace protocol\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/protocol/zmq/certificate.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/protocol/zmq/certificate.hpp>\n\n#include <string>\n#include <zmq.h>\n#include <UChain/coin.hpp>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\nnamespace zmq\n{\n\nstatic constexpr int32_t zmq_fail = -1;\nstatic constexpr size_t zmq_encoded_key_size = 40;\n\ncertificate::certificate()\n{\n    // HACK: restricted key space for use with config files.\n    create(public_, private_, true);\n}\n\n// Full key space.\ncertificate::certificate(const config::sodium &private_key)\n{\n    if (!private_key)\n    {\n        // Full key space (may include '#' character in z85 encoding).\n        create(public_, private_, false);\n        return;\n    }\n\n    if (derive(public_, private_key))\n        private_ = private_key;\n}\n\nbool certificate::derive(config::sodium &out_public,\n                         const config::sodium &private_key)\n{\n    if (!private_key)\n        return false;\n\n    const auto key = private_key.to_string();\n    char public_key[zmq_encoded_key_size + 1] = {0};\n\n    if (zmq_curve_public(public_key, key.data()) == zmq_fail)\n        return false;\n\n    out_public = config::sodium(public_key);\n    return out_public;\n}\n\n// TODO: update settings loader so this isn't necessary.\n// BUGBUG: this limitation weakens security by reducing key space.\nstatic inline bool ok_setting(const std::string &key)\n{\n    return key.find_first_of('#') == std::string::npos;\n};\n\nbool certificate::create(config::sodium &out_public,\n                         config::sodium &out_private, bool setting)\n{\n    // Loop until neither key's base85 encoding includes the # character.\n    // This ensures that the value can be used in libbitcoin settings files.\n    for (uint8_t attempt = 0; attempt <= max_uint8; attempt++)\n    {\n        char public_key[zmq_encoded_key_size + 1] = {0};\n        char private_key[zmq_encoded_key_size + 1] = {0};\n\n        if (zmq_curve_keypair(public_key, private_key) == zmq_fail)\n            return false;\n\n        if (!setting || ((ok_setting(public_key) && ok_setting(private_key))))\n        {\n            out_public = config::sodium(public_key);\n            out_private = config::sodium(private_key);\n            return out_public;\n        }\n    }\n\n    return false;\n}\n\ncertificate::operator const bool() const\n{\n    return public_;\n}\n\nconst config::sodium &certificate::public_key() const\n{\n    return public_;\n}\n\nconst config::sodium &certificate::private_key() const\n{\n    return private_;\n}\n\n} // namespace zmq\n} // namespace protocol\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/protocol/zmq/context.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/protocol/zmq/context.hpp>\n\n#include <cstdint>\n#include <zmq.h>\n#include <UChain/coin.hpp>\n#include <mutex>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\nnamespace zmq\n{\n\nstd::mutex zmq_mtx;\nstatic constexpr int32_t zmq_fail = -1;\n\ncontext::context(bool started)\n    : self_(nullptr)\n{\n    if (started)\n        start();\n}\n\ncontext::~context()\n{\n    stop();\n}\n\n// Restartable after stop and optionally started on construct.\nbool context::start()\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    std::unique_lock<std::mutex> zmq_lock(zmq_mtx);\n    unique_lock lock(mutex_);\n\n    if (self_ != nullptr)\n        return false;\n\n    self_ = zmq_ctx_new();\n    return self_ != nullptr;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n// Signal termination and block until all sockets closed.\nbool context::stop()\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    std::unique_lock<std::mutex> zmq_lock(zmq_mtx);\n    unique_lock lock(mutex_);\n\n    if (self_ == nullptr)\n        return true;\n\n    // This aborts blocking operations but blocks here until either each socket\n    // in the context is explicitly closed. This can fail by signal interrupt.\n    auto self = self_;\n    self_ = nullptr;\n    return zmq_ctx_term(self) != zmq_fail;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\ncontext::operator const bool() const\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    shared_lock lock(mutex_);\n\n    return self_ != nullptr;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid *context::self()\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    shared_lock lock(mutex_);\n\n    // This may become invalid after return. The guard only ensures atomicity.\n    return self_;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n} // namespace zmq\n} // namespace protocol\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/protocol/zmq/frame.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/protocol/zmq/frame.hpp>\n\n#include <cstddef>\n#include <cstdint>\n#include <cstring>\n#include <zmq.h>\n#include <UChain/coin.hpp>\n#include <UChain/protocol/zmq/socket.hpp>\n#include <UChain/protocol/zmq/zeromq.hpp>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\nnamespace zmq\n{\n\n// If ZMQ_DONTWAIT is set we fail on busy socket.\n// This would happen if a message is being read when we try to send.\nstatic auto constexpr wait_flag = 0;\nstatic constexpr auto zmq_fail = -1;\n\n// Use for receiving.\nframe::frame()\n    : more_(false), valid_(initialize(message_, {}))\n{\n}\n\n// Use for sending.\nframe::frame(const data_chunk &data)\n    : more_(false), valid_(initialize(message_, data))\n{\n}\n\nframe::~frame()\n{\n    destroy();\n}\n\n// static\nbool frame::initialize(zmq_msg &message, const data_chunk &data)\n{\n    const auto buffer = reinterpret_cast<zmq_msg_t *>(&message);\n\n    if (data.empty())\n        return (zmq_msg_init(buffer) != zmq_fail);\n\n    if (zmq_msg_init_size(buffer, data.size()) == zmq_fail)\n        return false;\n\n    std::memcpy(zmq_msg_data(buffer), data.data(), data.size());\n    return true;\n}\n\nframe::operator const bool() const\n{\n    return valid_;\n}\n\nbool frame::more() const\n{\n    return more_;\n}\n\n// private\nbool frame::set_more(socket &socket)\n{\n    int more;\n    auto length = static_cast<size_t>(sizeof(int));\n\n    if (zmq_getsockopt(socket.self(), ZMQ_RCVMORE, &more, &length) == zmq_fail)\n        return false;\n\n    more_ = (more != 0);\n    return true;\n}\n\ndata_chunk frame::payload()\n{\n    const auto buffer = reinterpret_cast<zmq_msg_t *>(&message_);\n    const auto size = zmq_msg_size(buffer);\n    const auto data = zmq_msg_data(buffer);\n    const auto begin = static_cast<uint8_t *>(data);\n    return {begin, begin + size};\n}\n\n// Must be called on the socket thread.\ncode frame::receive(socket &socket)\n{\n    if (!valid_)\n        return error::operation_failed;\n\n    const auto buffer = reinterpret_cast<zmq_msg_t *>(&message_);\n    const auto result = zmq_recvmsg(socket.self(), buffer, wait_flag) != zmq_fail && set_more(socket);\n    return result ? error::success : get_last_error();\n}\n\n// Must be called on the socket thread.\ncode frame::send(socket &socket, bool last)\n{\n    if (!valid_)\n        return error::operation_failed;\n\n    const int flags = (last ? 0 : ZMQ_SNDMORE) | wait_flag;\n    const auto buffer = reinterpret_cast<zmq_msg_t *>(&message_);\n    const auto result = zmq_sendmsg(socket.self(), buffer, flags) != zmq_fail;\n    return result ? error::success : get_last_error();\n}\n\n// private\nbool frame::destroy()\n{\n    const auto buffer = reinterpret_cast<zmq_msg_t *>(&message_);\n    return valid_ && (zmq_msg_close(buffer) != zmq_fail);\n}\n\n} // namespace zmq\n} // namespace protocol\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/protocol/zmq/identifiers.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/protocol/zmq/socket.hpp>\n\n#include <algorithm>\n#include <UChain/protocol/zmq/identifiers.hpp>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\nnamespace zmq\n{\n\nbool identifiers::empty() const\n{\n    return ids_.empty();\n}\n\nbool identifiers::contains(identifier value) const\n{\n    return std::find(ids_.begin(), ids_.end(), value) != ids_.end();\n}\n\nvoid identifiers::push(const void *socket)\n{\n    const auto value = reinterpret_cast<identifier>(socket);\n    ids_.push_back(value);\n}\n\n} // namespace zmq\n} // namespace protocol\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/protocol/zmq/message.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/protocol/zmq/message.hpp>\n\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChain/protocol/zmq/frame.hpp>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\nnamespace zmq\n{\n\nvoid message::enqueue()\n{\n    queue_.emplace(data_chunk{});\n}\n\nbool message::dequeue()\n{\n    if (queue_.empty())\n        return false;\n\n    queue_.pop();\n    return true;\n}\n\nbool message::dequeue(uint32_t &value)\n{\n    if (queue_.empty())\n        return false;\n\n    const auto &front = queue_.front();\n\n    if (front.size() == sizeof(uint32_t))\n    {\n        value = from_little_endian_unsafe<uint32_t>(front.begin());\n        queue_.pop();\n        return true;\n    }\n\n    queue_.pop();\n    return false;\n}\n\nbool message::dequeue(data_chunk &value)\n{\n    if (queue_.empty())\n        return false;\n\n    value = dequeue_data();\n    return true;\n}\n\nbool message::dequeue(std::string &value)\n{\n    if (queue_.empty())\n        return false;\n\n    value = dequeue_text();\n    return true;\n}\n\nbool message::dequeue(hash_digest &value)\n{\n    if (queue_.empty())\n        return false;\n\n    const auto &front = queue_.front();\n\n    if (front.size() == hash_size)\n    {\n        std::copy(front.begin(), front.end(), value.begin());\n        queue_.pop();\n        return true;\n    }\n\n    queue_.pop();\n    return false;\n}\n\ndata_chunk message::dequeue_data()\n{\n    if (queue_.empty())\n        return {};\n\n    const auto data = queue_.front();\n    queue_.pop();\n    return data;\n}\n\nstd::string message::dequeue_text()\n{\n    if (queue_.empty())\n        return {};\n\n    const auto &front = queue_.front();\n    const auto text = std::string(front.begin(), front.end());\n    queue_.pop();\n    return text;\n}\n\nvoid message::clear()\n{\n    while (!queue_.empty())\n        queue_.pop();\n}\n\nbool message::empty() const\n{\n    return queue_.empty();\n}\n\nsize_t message::size() const\n{\n    return queue_.size();\n}\n\n// Must be called on the socket thread.\ncode message::send(socket &socket)\n{\n    auto count = queue_.size();\n\n    while (!queue_.empty())\n    {\n        frame frame(queue_.front());\n        queue_.pop();\n        const auto ec = frame.send(socket, --count == 0);\n\n        if (ec)\n            return ec;\n    }\n\n    return error::success;\n}\n\n// Must be called on the socket thread.\ncode message::receive(socket &socket)\n{\n    clear();\n    auto done = false;\n\n    while (!done)\n    {\n        frame frame;\n        const auto ec = frame.receive(socket);\n\n        if (ec)\n            return ec;\n\n        queue_.emplace(frame.payload());\n        done = !frame.more();\n    }\n\n    return error::success;\n}\n\n} // namespace zmq\n} // namespace protocol\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/protocol/zmq/poller.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/protocol/zmq/poller.hpp>\n\n#include <cstdint>\n#include <zmq.h>\n#include <UChain/coin.hpp>\n#include <UChain/protocol/zmq/identifiers.hpp>\n#include <UChain/protocol/zmq/socket.hpp>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\nnamespace zmq\n{\n\npoller::poller()\n    : expired_(false),\n      terminated_(false)\n{\n}\n\n// Parameter fd is non-zmq socket (unused when socket is set).\nvoid poller::add(socket &socket)\n{\n    zmq_pollitem item;\n    item.socket = socket.self();\n    item.fd = 0;\n    item.events = ZMQ_POLLIN;\n    item.revents = 0;\n\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    unique_lock lock(mutex_);\n\n    pollers_.push_back(item);\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid poller::clear()\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    unique_lock lock(mutex_);\n\n    return pollers_.clear();\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n// This must be called on the socket thread.\nidentifiers poller::wait()\n{\n    // This is the maximum safe value on all platforms, due to zeromq bug.\n    //static constexpr int32_t maximum_safe_wait_milliseconds = 1000;\n    static constexpr int32_t maximum_safe_wait_milliseconds = -1;\n\n    return wait(maximum_safe_wait_milliseconds);\n}\n\n// This must be called on the socket thread.\n// BUGBUG: zeromq 4.2 has an overflow bug in timer parameterization.\n// The timeout is typed as 'long' by zeromq. This is 32 bit on windows and\n// actually less (potentially 1000 or 1 second) on other platforms.\n// On non-windows platforms negative doesn't actually produce infinity.\nidentifiers poller::wait(int32_t timeout_milliseconds)\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    shared_lock lock(mutex_);\n\n    const auto size = pollers_.size();\n    BITCOIN_ASSERT(size <= max_int32);\n\n    const auto item_count = static_cast<int32_t>(size);\n    const auto items = reinterpret_cast<zmq_pollitem_t *>(pollers_.data());\n    const auto signaled = zmq_poll(items, item_count, timeout_milliseconds);\n\n    // Either one of the sockets was terminated or a signal intervened.\n    if (signaled < 0)\n    {\n        terminated_ = true;\n        return {};\n    }\n\n    // No events have been signaled and no failure, so ther timer expired.\n    if (signaled == 0)\n    {\n        expired_ = true;\n        return {};\n    }\n\n    identifiers result;\n    for (const auto &poller : pollers_)\n        if ((poller.revents & ZMQ_POLLIN) != 0)\n            result.push(poller.socket);\n\n    // At least one event was signaled, but this poll-in set may be empty.\n    return result;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nbool poller::expired() const\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    shared_lock lock(mutex_);\n\n    return expired_;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nbool poller::terminated() const\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    shared_lock lock(mutex_);\n\n    return terminated_;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n} // namespace zmq\n} // namespace protocol\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/protocol/zmq/socket.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/protocol/zmq/socket.hpp>\n\n#include <cstdint>\n#include <string>\n#include <zmq.h>\n#include <UChain/coin.hpp>\n#include <UChain/protocol/zmq/authenticator.hpp>\n#include <UChain/protocol/zmq/certificate.hpp>\n#include <UChain/protocol/zmq/identifiers.hpp>\n#include <UChain/protocol/zmq/message.hpp>\n#include <UChain/protocol/zmq/zeromq.hpp>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\nnamespace zmq\n{\n\nstatic constexpr int32_t zmq_true = 1;\nstatic constexpr int32_t zmq_fail = -1;\nstatic constexpr int32_t zmq_send_buffer = 1000;\nstatic constexpr int32_t zmq_receive_buffer = 1000;\nstatic constexpr int32_t zmq_linger_milliseconds = 10;\n\nint32_t socket::to_socket_type(role socket_role)\n{\n    switch (socket_role)\n    {\n    case role::pair:\n        return ZMQ_PAIR;\n    case role::publisher:\n        return ZMQ_PUB;\n    case role::subscriber:\n        return ZMQ_SUB;\n    case role::requester:\n        return ZMQ_REQ;\n    case role::replier:\n        return ZMQ_REP;\n    case role::dealer:\n        return ZMQ_DEALER;\n    case role::router:\n        return ZMQ_ROUTER;\n    case role::puller:\n        return ZMQ_PULL;\n    case role::pusher:\n        return ZMQ_PUSH;\n    case role::extended_publisher:\n        return ZMQ_XPUB;\n    case role::extended_subscriber:\n        return ZMQ_XSUB;\n    case role::streamer:\n        return ZMQ_STREAM;\n    default:\n        return -1;\n    }\n}\n\n// zmq_term terminates blocking operations but blocks until each socket in the\n// context is explicitly closed. Socket close kills transfers after linger.\nsocket::socket(void *zmq_socket)\n    : self_(zmq_socket),\n      send_buffer_(zmq_send_buffer),\n      receive_buffer_(zmq_receive_buffer),\n      identifier_(reinterpret_cast<identifier>(zmq_socket))\n{\n    if (self_ == nullptr)\n        return;\n\n    // Because self is only set on construct, sockets are not restartable.\n    if (!set(ZMQ_SNDHWM, send_buffer_) ||\n        !set(ZMQ_RCVHWM, receive_buffer_) ||\n        !set(ZMQ_LINGER, zmq_linger_milliseconds))\n    {\n        stop();\n    }\n}\n\nsocket::socket(context &context, role socket_role)\n    : socket(zmq_socket(context.self(), to_socket_type(socket_role)))\n{\n}\n\nsocket::~socket()\n{\n    stop();\n}\n\n// This must be called on the socket thread.\nbool socket::stop()\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    unique_lock lock(mutex_);\n\n    if (self_ == nullptr)\n        return true;\n\n    auto self = self_;\n    self_ = nullptr;\n    return zmq_close(self) != zmq_fail;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nsocket::operator const bool() const\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    shared_lock lock(mutex_);\n\n    return self_ != nullptr;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nvoid *socket::self()\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    shared_lock lock(mutex_);\n\n    // This may become invalid after return. The guard only ensures atomicity.\n    return self_;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n// To preserve idetity the id survives after the socket is destroyed.\nidentifier socket::id() const\n{\n    return identifier_;\n}\n\n// This must be called on the socket thread.\ncode socket::bind(const config::endpoint &address)\n{\n    if (zmq_bind(self_, address.to_string().c_str()) == zmq_fail)\n        return get_last_error();\n\n    return error::success;\n}\n\n// This must be called on the socket thread.\ncode socket::connect(const config::endpoint &address)\n{\n    if (zmq_connect(self_, address.to_string().c_str()) == zmq_fail)\n        return get_last_error();\n\n    return error::success;\n}\n\n// private\nbool socket::set(int32_t option, int32_t value)\n{\n    return zmq_setsockopt(self_, option, &value, sizeof(value)) != zmq_fail;\n}\n\n// private\nbool socket::set(int32_t option, const std::string &value)\n{\n    if (value.empty())\n        return true;\n\n    const auto buffer = value.c_str();\n    return zmq_setsockopt(self_, option, buffer, value.size()) != zmq_fail;\n}\n\n// This must be called on the socket thread.\nbool socket::set_authentication_domain(const std::string &domain)\n{\n    return set(ZMQ_ZAP_DOMAIN, domain);\n}\n\n// This must be called on the socket thread.\nbool socket::set_curve_server()\n{\n    return set(ZMQ_CURVE_SERVER, zmq_true);\n}\n\n// This must be called on the socket thread.\nbool socket::set_curve_client(const config::sodium &server_public_key)\n{\n    return set(ZMQ_CURVE_SERVERKEY, server_public_key.to_string());\n}\n\n// This must be called on the socket thread.\nbool socket::set_public_key(const config::sodium &key)\n{\n    return set(ZMQ_CURVE_PUBLICKEY, key.to_string());\n}\n\n// This must be called on the socket thread.\nbool socket::set_private_key(const config::sodium &key)\n{\n    return set(ZMQ_CURVE_SECRETKEY, key.to_string());\n}\n\n// This must be called on the socket thread.\nbool socket::set_certificate(const certificate &certificate)\n{\n    return certificate &&\n           set_public_key(certificate.public_key().to_string()) &&\n           set_private_key(certificate.private_key().to_string());\n}\n\ncode socket::send(message &packet)\n{\n    return packet.send(*this);\n}\n\ncode socket::receive(message &packet)\n{\n    return packet.receive(*this);\n}\n\n} // namespace zmq\n} // namespace protocol\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/protocol/zmq/worker.cpp",
    "content": "/*\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/protocol/zmq/worker.hpp>\n\n#include <zmq.h>\n#include <functional>\n#include <future>\n#include <UChain/coin.hpp>\n#include <UChain/protocol/zmq/message.hpp>\n#include <UChain/protocol/zmq/socket.hpp>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\nnamespace zmq\n{\n\n#define NAME \"worker\"\n\n// Derive from this abstract worker to implement real worker.\nworker::worker(threadpool &pool)\n    : dispatch_(pool, NAME),\n      stopped_(true)\n{\n}\n\nworker::~worker()\n{\n    stop();\n}\n\n// Restartable after stop and not started on construct.\nbool worker::start()\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    unique_lock lock(mutex_);\n\n    if (stopped_)\n    {\n        stopped_ = false;\n\n        // Create the replier thread and socket and start polling.\n        dispatch_.concurrent(\n            std::bind(&worker::work, this));\n\n        // Wait on replier start.\n        const auto result = started_.get_future().get();\n\n        // Reset for restartability.\n        started_ = std::promise<bool>();\n        return result;\n    }\n\n    return false;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\nbool worker::stop()\n{\n    ///////////////////////////////////////////////////////////////////////////\n    // Critical Section\n    unique_lock lock(mutex_);\n\n    if (!stopped_)\n    {\n        stopped_ = true;\n\n        // Wait on replier stop.\n        const auto result = finished_.get_future().get();\n\n        // Reset for restartability.\n        finished_ = std::promise<bool>();\n        return result;\n    }\n\n    return true;\n    ///////////////////////////////////////////////////////////////////////////\n}\n\n// Utilities.\n//-----------------------------------------------------------------------------\n\n// Call from work to detect an explicit stop.\nbool worker::stopped()\n{\n    return stopped_;\n}\n\n// Call from work when started (connected/bound) or failed to do so.\nbool worker::started(bool result)\n{\n    started_.set_value(result);\n\n    if (!result)\n        finished(true);\n\n    return result;\n}\n\n// Call from work when finished working, do not call if started was called.\nbool worker::finished(bool result)\n{\n    finished_.set_value(result);\n    return result;\n}\n\n// Call from work to forward a message from one socket to another.\nbool worker::forward(socket &from, socket &to)\n{\n    message packet;\n    return !from.receive(packet) && !to.send(packet);\n}\n\n// Call from work to establish a proxy between two sockets.\nvoid worker::relay(socket &left, socket &right)\n{\n    // Blocks until the context is terminated, always returns -1.\n    zmq_proxy_steerable(left.self(), right.self(), nullptr, nullptr);\n\n    // Equivalent implementation:\n    ////zmq::poller poller;\n    ////poller.add(left);\n    ////poller.add(right);\n    ////\n    ////while (!poller.terminated())\n    ////{\n    ////    const auto signaled = poller.wait();\n    ////\n    ////    if (signaled.contains(left.id()))\n    ////        forward(left, right);\n    ////\n    ////    if (signaled.contains(right.id()))\n    ////        forward(right, left);\n    ////}\n}\n\n} // namespace zmq\n} // namespace protocol\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChain/protocol/zmq/zeromq.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain-protocol.\n *\n * UChain-protocol is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChain/protocol/zmq/zeromq.hpp>\n\n#include <zmq.h>\n#include <UChain/coin.hpp>\n\nnamespace libbitcoin\n{\nnamespace protocol\n{\nnamespace zmq\n{\n\n// See: zmq::errno_to_string\ncode get_last_error()\n{\n    switch (zmq_errno())\n    {\n    case 0:\n        return error::success;\n\n#if defined _WIN32\n    case ENOBUFS:\n    case ENOTSUP:\n    case EPROTONOSUPPORT:\n        return error::operation_failed;\n    case ENETDOWN:\n        return error::network_unreachable;\n    case EADDRINUSE:\n        return error::address_in_use;\n    case EADDRNOTAVAIL:\n        return error::resolve_failed;\n    case ECONNREFUSED:\n        return error::accept_failed;\n    case EINPROGRESS:\n        return error::channel_timeout;\n#endif\n    case EFSM:\n    case EAGAIN:\n        return error::channel_timeout;\n    case EFAULT:\n        return error::bad_stream;\n    case EINTR:\n    case ETERM:\n        return error::service_stopped;\n    case ENOTSOCK:\n    case EMTHREAD:\n    case ENOCOMPATPROTO:\n        return error::operation_failed;\n    default:\n        return error::unknown;\n    }\n}\n\n} // namespace zmq\n} // namespace protocol\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainApp/uc-cli/CMakeLists.txt",
    "content": "\nFILE(GLOB_RECURSE uc-cli_SOURCES \"*.cpp\")\n\nADD_DEFINITIONS(-DBCX_STATIC=1)\n\nADD_EXECUTABLE(uc-cli ${uc-cli_SOURCES})\n\n# for experimental/string_view\nSET(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations\")\n\nIF(ENABLE_SHARED_LIBS)\n    TARGET_LINK_LIBRARIES(uc-cli ${mongoose_LIBRARY} ${jsoncpp_LIBRARY}\n        ${txs_LIBRARY} ${bitcoin_LIBRARY} ${explorer_LIBRARY})\nELSE()\n    TARGET_LINK_LIBRARIES(uc-cli ${mongoose_LIBRARY} ${jsoncpp_LIBRARY}\n        ${txs_LIBRARY} ${bitcoin_LIBRARY} ${explorer_LIBRARY})\nENDIF()\n\nINSTALL(TARGETS uc-cli DESTINATION bin)\n"
  },
  {
    "path": "src/UChainApp/uc-cli/main.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/txs/utility/path.hpp>\n#include <UChain/coin/unicode/ifstream.hpp>\n#include <boost/program_options.hpp>\n#include <boost/algorithm/string/trim.hpp>\n#include <jsoncpp/json/json.h>\n#include <UChainService/api/restful/MongooseCli.hpp>\n#include <UChain/coin/unicode/unicode.hpp>\n\nBC_USE_UC_MAIN\n\n/**\n * Invoke this program with the raw arguments provided on the command line.\n * All console input and output streams for the application originate here.\n * @param argc  The number of elements in the argv array.\n * @param argv  The array of arguments, including the process.\n * @return      The numeric result to return via console exit.\n */\nusing namespace mgbubble::cli;\nnamespace po = boost::program_options;\n\nvoid my_impl(const http_message *hm)\n{\n    auto &&reply = std::string(hm->body.p, hm->body.len);\n    Json::Reader reader;\n    Json::Value root;\n    if (reader.parse(reply, root) && root.isObject())\n    {\n        if (root[\"error\"][\"code\"].isInt() && root[\"error\"][\"code\"].asInt() != 0)\n        {\n            bc::cout << root[\"error\"].toStyledString();\n        }\n        else if (root[\"result\"].isString())\n        {\n            bc::cout << root[\"result\"].asString() << std::endl;\n        }\n        else if (root[\"result\"].isNumeric())\n        {\n            bc::cout << root[\"result\"] << std::endl;\n        }\n        else if (root[\"result\"].isArray() || root[\"result\"].isObject())\n        {\n            bc::cout << root[\"result\"].toStyledString();\n        }\n        else\n        {\n            bc::cout << reply << std::endl;\n        }\n    }\n    else\n    {\n        bc::cout << reply << std::endl;\n    }\n}\n\nint bc::main(int argc, char *argv[])\n{\n    auto cur_path = boost::filesystem::current_path();\n    //boost::filesystem::remove(cur_path/\"conf\");\n    bc::set_utf8_stdout();\n    auto work_path = bc::default_data_path();\n    int index = 0;\n    if (argc > 2)\n    {\n        std::string op = argv[1], cfg_path = argv[2];\n        boost::trim(op);\n        boost::trim(cfg_path);\n        if (!op.compare(\"-c\"))\n        {\n            if (!boost::filesystem::exists(cfg_path))\n            {\n                log::info(\"config\") << \"uc.config path is invalid.\";\n                return -1;\n            }\n            try\n            {\n                boost::filesystem::remove(cur_path / \"conf\");\n                boost::filesystem::create_symlink(boost::filesystem::path(cfg_path), cur_path / \"conf\");\n                if (argc == 3)\n                    return 0;\n                else\n                    index = 2;\n            }\n            catch (...)\n            {\n                log::info(\"config\") << \"Please use administrator privilege to allow uc-cli access! \";\n                return -1;\n            }\n        }\n    }\n    auto &&config_file = boost::filesystem::exists(cur_path / \"conf\") ? cur_path / \"conf\" : work_path / \"uc.conf\";\n    std::string url{\"127.0.0.1:8707/rpc/v3\"};\n\n    if (boost::filesystem::exists(config_file))\n    {\n        const auto &path = config_file.string();\n        bc::ifstream file(path);\n\n        if (!file.good())\n        {\n            BOOST_THROW_EXCEPTION(po::reading_file(path.c_str()));\n        }\n\n        std::string tmp;\n        po::options_description desc(\"\");\n        desc.add_options()(\"server.mongoose_listen\", po::value<std::string>(&tmp)->default_value(\"127.0.0.1:8707\"));\n\n        po::variables_map vm;\n        po::store(po::parse_config_file(file, desc, true), vm);\n        po::notify(vm);\n\n        if (vm.count(\"server.mongoose_listen\"))\n        {\n            if (!tmp.empty())\n            {\n                // On Windows, client can not connect to 0.0.0.0\n                if (tmp.find(\"0.0.0.0\") == 0)\n                {\n                    tmp.replace(0, 7, \"127.0.0.1\");\n                }\n                url = tmp + \"/rpc/v3\";\n            }\n        }\n    }\n\n    // HTTP request call commands\n    HttpReq req(url, 3000, reply_handler(my_impl));\n\n    Json::Value jsonvar;\n    Json::Value jsonopt;\n    jsonvar[\"jsonrpc\"] = \"3.0\";\n    jsonvar[\"id\"] = 1;\n    jsonvar[\"method\"] = (argc < 2) ? \"help\" : argv[1 + index];\n    jsonvar[\"params\"] = Json::arrayValue;\n\n    if (argc > 2 + index)\n    {\n        for (int i = 2 + index; i < argc; i++)\n        {\n            jsonvar[\"params\"].append(argv[i]);\n        }\n    }\n\n    req.post(jsonvar.toStyledString());\n    return 0;\n}\n"
  },
  {
    "path": "src/UChainApp/ucd/CMakeLists.txt",
    "content": "FILE(GLOB_RECURSE ucd_SOURCES \"*.cpp\")\n\nADD_EXECUTABLE(ucd ${ucd_SOURCES})\n\nSET(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations\")\n\nIF(ENABLE_SHARED_LIBS)\n    ADD_DEFINITIONS(-DBCS_DLL=1)\n    TARGET_LINK_LIBRARIES(ucd ${Boost_LIBRARIES} ${network_LIBRARY} ${data_LIBRARY} ${database_LIBRARY} ${consensus_LIBRARY}\n    ${blockchain_LIBRARY} ${txs_LIBRARY} ${bitcoin_LIBRARY} ${mongoose_LIBRARY} ${node_LIBRARY}\n    ${protocol_LIBRARY} ${client_LIBRARY} ${api_LIBRARY} ${explorer_LIBRARY} ${cryptojs_LIBRARY} )\nELSE()\n    ADD_DEFINITIONS(-DBCS_STATIC=1)\n    TARGET_LINK_LIBRARIES(ucd ${Boost_LIBRARIES} ${network_LIBRARY} ${data_LIBRARY} ${database_LIBRARY} ${consensus_LIBRARY}\n    ${blockchain_LIBRARY} ${txs_LIBRARY} ${bitcoin_LIBRARY} ${mongoose_LIBRARY} ${node_LIBRARY}\n    ${protocol_LIBRARY} ${client_LIBRARY} ${api_LIBRARY} ${explorer_LIBRARY} ${cryptojs_LIBRARY})\nENDIF()\nif(MINGW OR MSYS)\n    FIND_PACKAGE(Boost 1.56 REQUIRED random)\n\tTARGET_LINK_LIBRARIES(ucd ${Boost_RANDOM_LIBRARIES})\nENDIF()\nINSTALL(TARGETS ucd DESTINATION bin)\n"
  },
  {
    "path": "src/UChainApp/ucd/executor.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include \"executor.hpp\"\n\n#include <algorithm>\n#include <csignal>\n#include <functional>\n#include <future>\n#include <iostream>\n#include <memory>\n#include <mutex>\n#include <string>\n#include <boost/filesystem.hpp>\n#include <boost/format.hpp>\n#include <UChainApp/ucd.hpp>\n#include <UChainService/txs/utility/callstack.hpp>\n#include <UChainService/txs/utility/path.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nusing boost::format;\nusing namespace std::placeholders;\nusing namespace boost::system;\nusing namespace bc::config;\nusing namespace bc::database;\nusing namespace bc::network;\n\nstatic constexpr int initialize_stop = 0;\nstatic constexpr int directory_exists = 0;\nstatic constexpr int directory_not_found = 2;\nstatic constexpr auto append = std::ofstream::out | std::ofstream::app;\nstatic const auto application_name = \"bs\";\n\nstd::promise<code> executor::stopping_;\n\nexecutor::executor(parser &metadata, std::istream &input,\n                   std::ostream &output, std::ostream &error)\n    : metadata_(metadata), output_(output),\n      debug_file_((metadata_.configured.network.debug_file == \"debug.log\" ? (default_data_path() / metadata_.configured.network.debug_file) : metadata_.configured.network.debug_file).string(), append),\n      error_file_((metadata_.configured.network.error_file == \"error.log\" ? (default_data_path() / metadata_.configured.network.error_file) : metadata_.configured.network.error_file).string(), append)\n{\n    initialize_logging(debug_file_, error_file_, output, error, metadata_.configured.server.log_level);\n    handle_stop(initialize_stop);\n}\n\n// Command line options.\n// ----------------------------------------------------------------------------\n// Emit directly to standard output (not the log).\n\nvoid executor::do_help()\n{\n    const auto options = metadata_.load_options();\n    printer help(options, application_name, BS_INFORMATION_MESSAGE);\n    help.initialize();\n    help.commandline(output_);\n}\n\nvoid executor::do_settings()\n{\n    const auto settings = metadata_.load_settings();\n    printer print(settings, application_name, BS_SETTINGS_MESSAGE);\n    print.initialize();\n    print.settings(output_);\n}\n\nvoid executor::do_version()\n{\n    output_ << format(BS_VERSION_MESSAGE) %\n                   UC_VERSION %\n                   UC_SERVER_VERSION %\n                   UC_PROTOCOL_VERSION %\n                   UC_NODE_VERSION %\n                   UC_BLOCKCHAIN_VERSION %\n                   UC_VERSION\n            << std::endl;\n}\n\nvoid executor::set_admin()\n{\n    data_base db(metadata_.configured.database);\n    db.start();\n    db.set_admin(\"administerator\", \"ucgo\");\n    db.stop();\n}\n\nvoid executor::set_blackhole_rewardpool_block_vote()\n{\n    data_base db(metadata_.configured.database);\n    db.start();\n    db.set_blackhole_uid();\n    db.set_block_vote_token();\n    db.set_reward_pool_candidate();\n    db.stop();\n}\n\n// Emit to the log.\nbool executor::do_initchain()\n{\n    initialize_output();\n\n    boost::system::error_code ec;\n\n    const auto &directory = metadata_.configured.database.directory;\n    const auto &data_path = directory;\n\n    if (create_directories(data_path, ec))\n    {\n        log::info(LOG_SERVER) << format(BS_INITIALIZING_CHAIN) % data_path;\n\n        // Unfortunately we are still limited to a choice of hardcoded chains.\n        //const auto genesis = metadata_.configured.chain.use_testnet_rules ?\n        //   chain::block::genesis_testnet() : chain::block::genesis_mainnet();\n        auto genesis = consensus::miner::create_genesis_block(!metadata_.configured.chain.use_testnet_rules);\n\n        const auto result = data_base::initialize(data_path, *genesis);\n        if (!result)\n        {\n            //rm directories\n            remove_all(data_path);\n            throw std::runtime_error{\"initialize chain failed\"};\n        }\n        // init admin wallet\n        set_admin();\n        // init blackhole UID,block and vote token\n        set_blackhole_rewardpool_block_vote();\n        log::info(LOG_SERVER) << BS_INITCHAIN_COMPLETE;\n        return true;\n    }\n    else if (UC_DATABASE_VERSION_NUMBER >= 63)\n    {\n        if (!data_base::upgrade_version_63(data_path))\n        {\n            throw std::runtime_error{\" upgrade database to version 63 failed!\"};\n        }\n    }\n\n    if (ec.value() == directory_exists)\n    {\n        return false;\n    }\n\n    auto error_info = format(BS_INITCHAIN_NEW) % data_path % ec.message();\n    throw std::runtime_error{error_info.str()};\n    return false;\n}\n\n// Menu selection.\n// ----------------------------------------------------------------------------\n\nbool executor::menu()\n{\n    const auto &config = metadata_.configured;\n\n    if (config.help)\n    {\n        do_help();\n        return true;\n    }\n\n    if (config.settings)\n    {\n        do_settings();\n        return true;\n    }\n\n    if (config.version)\n    {\n        do_version();\n        return true;\n    }\n\n    try\n    {\n        log::info(LOG_SERVER) << \"Ucd version is \" << UC_VERSION;\n        // set block data absolute path\n        const auto &directory = metadata_.configured.database.directory;\n        if (!directory.is_absolute())\n        {\n            const auto &home = metadata_.configured.data_dir;\n            metadata_.configured.database.directory = home / directory;\n        }\n        else\n        {\n            const auto &default_directory = metadata_.configured.database.default_directory;\n            metadata_.configured.database.directory = directory / default_directory;\n        }\n\n        auto result = do_initchain(); // false means no need to initial chain\n\n        if (config.initchain)\n        {\n            return result;\n        }\n    }\n    catch (const std::exception &e)\n    { // initialize failed\n        //log::error(LOG_SERVER) << format(BS_INITCHAIN_EXISTS) % data_path;\n        log::error(LOG_SERVER) << \"initialize chain failed,\" << e.what();\n        return false;\n    }\n\n    // There are no command line arguments, just run the server.\n    return run();\n}\n\n// Run.\n// ----------------------------------------------------------------------------\n\nbool executor::run()\n{\n    //    initialize_output();\n\n    log::info(LOG_SERVER) << BS_NODE_STARTING;\n\n    if (!verify_directory())\n        return false;\n\n    // Ensure all configured services can function.\n    set_minimum_threadpool_size();\n\n    // Now that the directory is verified we can create the node for it.\n    node_ = std::make_shared<server_node>(metadata_.configured);\n\n    // The callback may be returned on the same thread.\n    node_->start(\n        std::bind(&executor::handle_started,\n                  this, _1));\n\n    // Wait for stop.\n    stopping_.get_future().wait();\n\n    log::info(LOG_SERVER) << BS_NODE_STOPPING;\n\n    // Close must be called from main thread.\n    if (node_->close())\n        log::info(LOG_NODE) << BS_NODE_STOPPED;\n    else\n        log::info(LOG_NODE) << BS_NODE_STOP_FAIL;\n\n    return true;\n}\n\n// Handle the completion of the start sequence and begin the run sequence.\nvoid executor::handle_started(const code &ec)\n{\n    if (ec)\n    {\n        log::error(LOG_SERVER) << format(BS_NODE_START_FAIL) % ec.message();\n        stop(ec);\n        return;\n    }\n\n    log::info(LOG_SERVER) << BS_NODE_SEEDED;\n\n    // This is the beginning of the stop sequence.\n    node_->subscribe_stop(\n        std::bind(&executor::handle_stopped,\n                  this, _1));\n\n    // This is the beginning of the run sequence.\n    node_->run(\n        std::bind(&executor::handle_running,\n                  this, _1));\n}\n\n// This is the end of the run sequence.\nvoid executor::handle_running(const code &ec)\n{\n    if (ec)\n    {\n        log::info(LOG_SERVER) << format(BS_NODE_START_FAIL) % ec.message();\n        stop(ec);\n        return;\n    }\n\n    log::info(LOG_SERVER) << BS_NODE_STARTED;\n}\n\n// This is the end of the stop sequence.\nvoid executor::handle_stopped(const code &ec)\n{\n    stop(ec);\n}\n\n// Stop signal.\n// ----------------------------------------------------------------------------\n\nvoid executor::handle_stop(int code)\n{\n    // Reinitialize after each capture to prevent hard shutdown.\n    std::signal(SIGINT, handle_stop);\n    std::signal(SIGTERM, handle_stop);\n    std::signal(SIGABRT, handle_stop);\n\n    if (code == initialize_stop)\n        return;\n\n    if (SIGINT != code)\n    {\n        do_callstack(\"signal.out\");\n    }\n\n    log::info(LOG_SERVER) << format(BS_NODE_SIGNALED) % code;\n    stop(error::success);\n}\n\nvoid executor::stop(const code &ec)\n{\n    static std::once_flag stop_mutex;\n    std::call_once(stop_mutex, [&]() { stopping_.set_value(ec); });\n}\n\n// Utilities.\n// ----------------------------------------------------------------------------\n\n// Set up logging.\nvoid executor::initialize_output()\n{\n    //log::info(LOG_SERVER) << BS_LOG_HEADER;\n    auto file = metadata_.configured.file.string().compare(\"uc.conf\")\n                    ? metadata_.configured.file\n                    : default_data_path() / metadata_.configured.file;\n\n    if (file.empty())\n        log::info(LOG_SERVER) << BS_USING_DEFAULT_CONFIG;\n    else\n        log::info(LOG_SERVER) << format(BS_USING_CONFIG_FILE) % file;\n}\n\n// Use missing directory as a sentinel indicating lack of initialization.\nbool executor::verify_directory()\n{\n    boost::system::error_code ec;\n    const auto &directory = metadata_.configured.database.directory;\n    auto data_path = directory;\n\n    if (exists(data_path, ec))\n        return true;\n\n    if (ec.value() == directory_not_found)\n    {\n        log::error(LOG_SERVER) << format(BS_UNINITIALIZED_CHAIN) % data_path;\n        return false;\n    }\n\n    const auto message = ec.message();\n    log::error(LOG_SERVER) << format(BS_INITCHAIN_TRY) % data_path % message;\n    return false;\n}\n\n// Increase the configured minomum as required to operate the service.\nvoid executor::set_minimum_threadpool_size()\n{\n    metadata_.configured.network.threads =\n        std::max(metadata_.configured.network.threads,\n                 server_node::threads_required(metadata_.configured));\n}\n\n} // namespace server\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainApp/ucd/executor.hpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#ifndef UC_SERVER_EXECUTOR_HPP\n#define UC_SERVER_EXECUTOR_HPP\n\n#include <future>\n#include <iostream>\n#include <UChainApp/ucd.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nclass executor\n{\n  public:\n    executor(parser &metadata, std::istream &, std::ostream &output,\n             std::ostream &error);\n\n    /// This class is not copyable.\n    executor(const executor &) = delete;\n    void operator=(const executor &) = delete;\n\n    /// Invoke the command indicated by the metadata.\n    bool menu();\n\n  private:\n    static void stop(const code &ec);\n    static void handle_stop(int code);\n\n    void handle_started(const code &ec);\n    void handle_running(const code &ec);\n    void handle_stopped(const code &ec);\n\n    void do_help();\n    void do_settings();\n    void do_version();\n    bool do_initchain();\n    void set_admin();\n    void set_blackhole_rewardpool_block_vote();\n\n    void initialize_output();\n    bool verify_directory();\n    void set_minimum_threadpool_size();\n    bool run();\n\n    // Termination state.\n    static std::promise<code> stopping_;\n\n    parser &metadata_;\n    std::ostream &output_;\n    bc::ofstream debug_file_;\n    bc::ofstream error_file_;\n    server_node::ptr node_;\n};\n\n// Localizable messages.\n#define BS_SETTINGS_MESSAGE \\\n    \"These are the configuration settings that can be set.\"\n#define BS_INFORMATION_MESSAGE \\\n    \"Runs a full UChain node in the global peer-to-peer network.\"\n\n#define BS_UNINITIALIZED_CHAIN                            \\\n    \"The %1% directory is not initialized. \"              \\\n    \"If this is your first time running ucd, please run:\" \\\n    \" 'ucd -i' for initializing.\"\n#define BS_INITIALIZING_CHAIN \\\n    \"Please wait while initializing %1% directory...\"\n#define BS_INITCHAIN_NEW \\\n    \"Failed to create directory %1% with error, '%2%'.\"\n#define BS_INITCHAIN_EXISTS \\\n    \"Failed because the directory %1% already exists.\"\n#define BS_INITCHAIN_TRY \\\n    \"Failed to test directory %1% with error, '%2%'.\"\n#define BS_INITCHAIN_COMPLETE \\\n    \"Completed initialization.\"\n\n#define BS_NODE_INTERRUPT \\\n    \"Press CTRL-C to stop the server.\"\n#define BS_NODE_STARTING \\\n    \"Please wait while the server is starting...\"\n#define BS_NODE_START_FAIL \\\n    \"Server failed to start with error, %1%.\"\n#define BS_NODE_SEEDED \\\n    \"Seeding is complete.\"\n#define BS_NODE_STARTED \\\n    \"Server is started.\"\n\n#define BS_NODE_SIGNALED \\\n    \"Stop signal detected (code: %1%).\"\n#define BS_NODE_STOPPING \\\n    \"Please wait while the server is stopping...\"\n#define BS_NODE_STOP_FAIL \\\n    \"Server failed to stop properly, see log.\"\n#define BS_NODE_STOPPED \\\n    \"Server stopped successfully.\"\n\n#define BS_USING_CONFIG_FILE \\\n    \"Using config file: %1%\"\n#define BS_USING_DEFAULT_CONFIG \\\n    \"Using default configuration settings.\"\n#define BS_VERSION_MESSAGE       \\\n    \"\\nVersion Information:\\n\\n\" \\\n    \"ucd:           %1%\\n\"       \\\n    \"uc-server:     %2%\\n\"       \\\n    \"uc-protocol:   %3%\\n\"       \\\n    \"uc-node:       %4%\\n\"       \\\n    \"uc-blockchain: %5%\\n\"       \\\n    \"uc-base:       %6%\"\n#define BS_LOG_HEADER \\\n    \"***************** start-up *****************\"\n\n} // namespace server\n} // namespace libbitcoin\n\n#endif\n"
  },
  {
    "path": "src/UChainApp/ucd/main.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <iostream>\n#include <UChainApp/ucd.hpp>\n#include <UChainService/txs/utility/callstack.hpp>\n#include <UChainService/txs/utility/daemon.hpp>\n#include \"executor.hpp\"\n#include <UChainApp/ucd/utility/coredump.hpp>\n\nBC_USE_UC_MAIN\n\n/**\n * Invoke this program with the raw arguments provided on the command line.\n * All console input and output streams for the application originate here.\n * @param argc  The number of elements in the argv array.\n * @param argv  The array of arguments, including the process.\n * @return      The numeric result to return via console exit.\n */\nint bc::main(int argc, char *argv[])\n{\n    using namespace bc;\n    using namespace bc::server;\n    // core dump catch\n    start_unhandled_exception_filter();\n\n    //libzmq crashes  when differs from main standard IO encoding\n    set_utf8_stdio();\n    server::parser metadata(bc::settings::mainnet);\n    const auto &args = const_cast<const char **>(argv);\n\n    if (!metadata.parse(argc, args, cerr))\n        return console_result::failure;\n\n    std::ostream *out = &cout;\n    std::ostream *err = &cerr;\n    if (metadata.configured.daemon)\n    {\n        libbitcoin::daemon();\n        static fstream fout;\n        fout.open(\"/dev/null\");\n        if (!fout.good())\n            throw std::runtime_error{\"open /dev/null failed\"};\n        out = &fout;\n        err = &fout;\n    }\n\n    if (metadata.configured.use_testnet_rules) // option priority No.1\n    {\n        metadata.configured.chain.use_testnet_rules = true;\n\n        server::parser test_metadata(bc::settings::testnet);\n        if (!test_metadata.parse(argc, args, cerr))\n            return console_result::failure;\n        test_metadata.configured.chain.use_testnet_rules = true;\n        executor test_host(test_metadata, cin, *out, *err);\n        return test_host.menu() ? console_result::okay : console_result::failure;\n    }\n\n    executor host(metadata, cin, *out, *err);\n    return host.menu() ? console_result::okay : console_result::failure;\n}\n"
  },
  {
    "path": "src/UChainApp/ucd/server/address_key.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainApp/ucd/utility/address_key.hpp>\n\n#include <string>\n#include <UChain/coin.hpp>\n#include <UChainApp/ucd/messages/route.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\naddress_key::address_key(const route &reply_to, const binary &prefix_filter)\n    : reply_to_(reply_to), prefix_filter_(prefix_filter)\n{\n}\n\nbool address_key::operator==(const address_key &other) const\n{\n    return reply_to_ == other.reply_to_ &&\n           prefix_filter_ == other.prefix_filter_;\n}\n\nconst route &address_key::reply_to() const\n{\n    return reply_to_;\n}\n\nconst binary &address_key::prefix_filter() const\n{\n    return prefix_filter_;\n}\n\n} // namespace server\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainApp/ucd/server/config.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain-server is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainApp/ucd/config.hpp>\n\n#include <UChainApp/ucd/settings.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\n// Construct with defaults derived from given context.\nconfiguration::configuration(bc::settings context)\n    : node::configuration(context),\n      server(context)\n{\n}\n\n// Copy constructor.\nconfiguration::configuration(const configuration &other)\n    : node::configuration(other),\n      server(other.server)\n{\n}\n\n} // namespace server\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainApp/ucd/server/interface/address.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainApp/ucd/interface/address.hpp>\n\n#include <cstdint>\n#include <functional>\n#include <UChain/coin.hpp>\n#include <UChainApp/ucd/messages/message.hpp>\n#include <UChainApp/ucd/server_node.hpp>\n#include <UChainApp/ucd/utility/fetch_helpers.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nusing namespace std::placeholders;\nusing namespace bc::chain;\nusing namespace bc::wallet;\n\nvoid address::fetch_history2(server_node &node, const message &request,\n                             send_handler handler)\n{\n    static constexpr uint64_t limit = 0;\n    uint32_t from_height;\n    payment_address address;\n\n    if (!unwrap_fetch_history_args(address, from_height, request))\n    {\n        handler(message(request, error::bad_stream));\n        return;\n    }\n\n    // Obtain payment address history from the transaction pool and blockchain.\n    node.pool().fetch_history(address, limit, from_height,\n                              std::bind(send_history_result,\n                                        _1, _2, request, handler));\n}\n\n// v2/v3 (deprecated), used for resubscription, alias for subscribe in v3.\nvoid address::renew(server_node &node, const message &request,\n                    send_handler handler)\n{\n    subscribe(node, request, handler);\n}\n\n// v2/v3 (deprecated), requires an explicit subscription type.\nvoid address::subscribe(server_node &node, const message &request,\n                        send_handler handler)\n{\n    binary prefix_filter;\n    subscribe_type type;\n\n    if (!unwrap_subscribe_args(prefix_filter, type, request))\n    {\n        handler(message(request, error::bad_stream));\n        return;\n    }\n\n    node.subscribe_address(request.route(), request.id(), prefix_filter, type);\n    handler(message(request, error::success));\n}\n\nbool address::unwrap_subscribe_args(binary &prefix_filter,\n                                    subscribe_type &type, const message &request)\n{\n    static constexpr auto address_bits = short_hash_size * byte_bits;\n    static constexpr auto stealth_bits = sizeof(uint32_t) * byte_bits;\n\n    // [ type:1 ] (0 = address prefix, 1 = stealth prefix)\n    // [ prefix_bitsize:1 ]\n    // [ prefix_blocks:...]\n    const auto &data = request.data();\n\n    if (data.size() < 2)\n        return false;\n\n    // First byte is the subscribe_type enumeration.\n    type = static_cast<subscribe_type>(data[0]);\n\n    if (type != subscribe_type::payment && type != subscribe_type::stealth)\n        return false;\n\n    // Second byte is the number of bits.\n    const auto bit_length = data[1];\n\n    if ((type == subscribe_type::payment && bit_length > address_bits) ||\n        (type == subscribe_type::stealth && bit_length > stealth_bits))\n        return false;\n\n    // Convert the bit length to byte length.\n    const auto byte_length = binary::blocks_size(bit_length);\n\n    if (data.size() - 2 != byte_length)\n        return false;\n\n    const data_chunk bytes({data.begin() + 2, data.end()});\n    prefix_filter = binary(bit_length, bytes);\n    return true;\n}\n\n// v3 eliminates the subscription type, which we map to 'unspecified'.\nvoid address::subscribe2(server_node &node, const message &request,\n                         send_handler handler)\n{\n    static constexpr auto type = subscribe_type::unspecified;\n\n    binary prefix_filter;\n\n    if (!unwrap_subscribe2_args(prefix_filter, request))\n    {\n        handler(message(request, error::bad_stream));\n        return;\n    }\n\n    node.subscribe_address(request.route(), request.id(), prefix_filter, type);\n    handler(message(request, error::success));\n}\n\n// v3 adds unsubscribe2, which we map to subscription_type 'unsubscribe'.\nvoid address::unsubscribe2(server_node &node, const message &request,\n                           send_handler handler)\n{\n    static constexpr auto type = subscribe_type::unsubscribe;\n\n    binary prefix_filter;\n\n    if (!unwrap_subscribe2_args(prefix_filter, request))\n    {\n        handler(message(request, error::bad_stream));\n        return;\n    }\n\n    node.subscribe_address(request.route(), request.id(), prefix_filter, type);\n    handler(message(request, error::success));\n}\n\nbool address::unwrap_subscribe2_args(binary &prefix_filter,\n                                     const message &request)\n{\n    static constexpr auto address_bits = hash_size * byte_bits;\n\n    // [ prefix_bitsize:1 ]\n    // [ prefix_blocks:...]\n    const auto &data = request.data();\n\n    if (data.empty())\n        return false;\n\n    // First byte is the number of bits.\n    const auto bit_length = data[0];\n\n    // always false for this case: -\n    //if (bit_length > address_bits)\n    //    return false;\n\n    // Convert the bit length to byte length.\n    const auto byte_length = binary::blocks_size(bit_length);\n\n    if (data.size() - 1 != byte_length)\n        return false;\n\n    const data_chunk bytes({data.begin() + 1, data.end()});\n    prefix_filter = binary(bit_length, bytes);\n    return true;\n}\n\n} // namespace server\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainApp/ucd/server/interface/blockchain.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainApp/ucd/interface/blockchain.hpp>\n\n#include <cstdint>\n#include <cstddef>\n#include <functional>\n#include <UChain/blockchain.hpp>\n#include <UChainApp/ucd/define.hpp>\n#include <UChainApp/ucd/messages/message.hpp>\n#include <UChainApp/ucd/server_node.hpp>\n#include <UChainApp/ucd/utility/fetch_helpers.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nusing namespace std::placeholders;\nusing namespace bc::blockchain;\nusing namespace bc::chain;\nusing namespace bc::wallet;\n\nvoid blockchain::fetch_history(server_node &node, const message &request,\n                               send_handler handler)\n{\n    static constexpr uint64_t limit = 0;\n    uint32_t from_height;\n    payment_address address;\n\n    if (!unwrap_fetch_history_args(address, from_height, request))\n    {\n        handler(message(request, error::bad_stream));\n        return;\n    }\n\n    log::debug(LOG_SERVER)\n        << \"blockchain.fetch_history(\" << address.encoded()\n        << \", from_height=\" << from_height << \")\";\n\n    node.chain().fetch_history(address, limit, from_height,\n                               std::bind(send_history_result,\n                                         _1, _2, request, handler));\n}\n\nvoid blockchain::fetch_transaction(server_node &node, const message &request,\n                                   send_handler handler)\n{\n    hash_digest tx_hash;\n\n    if (!unwrap_fetch_transaction_args(tx_hash, request))\n    {\n        handler(message(request, error::bad_stream));\n        return;\n    }\n\n    log::debug(LOG_SERVER)\n        << \"blockchain.fetch_transaction(\" << encode_hash(tx_hash) << \")\";\n\n    node.chain().fetch_transaction(tx_hash,\n                                   std::bind(chain_transaction_fetched,\n                                             _1, _2, request, handler));\n}\n\nvoid blockchain::fetch_last_height(server_node &node, const message &request,\n                                   send_handler handler)\n{\n    const auto &data = request.data();\n\n    if (!data.empty())\n    {\n        handler(message(request, error::bad_stream));\n        return;\n    }\n\n    node.chain().fetch_last_height(\n        std::bind(&blockchain::last_height_fetched,\n                  _1, _2, request, handler));\n}\n\nvoid blockchain::last_height_fetched(const code &ec, size_t last_height,\n                                     const message &request, send_handler handler)\n{\n    BITCOIN_ASSERT(last_height <= max_uint32);\n    auto last_height32 = static_cast<uint32_t>(last_height);\n\n    // [ code:4 ]\n    // [ heigh:4 ]\n    const auto result = build_chunk(\n        {message::to_bytes(ec),\n         to_little_endian(last_height32)});\n\n    handler(message(request, result));\n}\n\nvoid blockchain::fetch_block_header(server_node &node, const message &request,\n                                    send_handler handler)\n{\n    const auto &data = request.data();\n\n    if (data.size() == hash_size)\n        blockchain::fetch_block_header_by_hash(node, request, handler);\n    else if (data.size() == sizeof(uint32_t))\n        blockchain::fetch_block_header_by_height(node, request, handler);\n    else if (data.size() == sizeof(uint64_t) + sizeof(bool))\n        blockchain::fetch_block_header_by_height_range(node, request, handler);\n    else\n        handler(message(request, error::bad_stream));\n}\n\nvoid blockchain::fetch_block_header_by_hash(server_node &node,\n                                            const message &request, send_handler handler)\n{\n    const auto &data = request.data();\n    BITCOIN_ASSERT(data.size() == hash_size);\n\n    auto deserial = make_deserializer(data.begin(), data.end());\n    const auto block_hash = deserial.read_hash();\n\n    node.chain().fetch_block_header(block_hash,\n                                    std::bind(&blockchain::block_header_fetched,\n                                              _1, _2, request, handler));\n}\n\nvoid blockchain::fetch_block_header_by_height(server_node &node,\n                                              const message &request, send_handler handler)\n{\n    const auto &data = request.data();\n    BITCOIN_ASSERT(data.size() == sizeof(uint32_t));\n\n    auto deserial = make_deserializer(data.begin(), data.end());\n    const uint64_t height = deserial.read_4_bytes_little_endian();\n\n    node.chain().fetch_block_header(height,\n                                    std::bind(&blockchain::block_header_fetched,\n                                              _1, _2, request, handler));\n}\n\nvoid blockchain::fetch_block_header_by_height_range(server_node &node,\n                                                    const message &request, send_handler handler)\n{\n    const auto &data = request.data();\n    BITCOIN_ASSERT(data.size() == sizeof(uint64_t) + sizeof(bool));\n\n    auto deserial = make_deserializer(data.begin(), data.end());\n    const uint64_t start = deserial.read_4_bytes_little_endian();\n    const uint64_t end = deserial.read_4_bytes_little_endian();\n    const bool order = deserial.read_byte();\n\n    node.chain().fetch_block_headers(start, end, order,\n                                     std::bind(&blockchain::block_headers_fetched,\n                                               _1, _2, request, handler));\n}\n\nvoid blockchain::block_header_fetched(const code &ec,\n                                      const chain::header &block, const message &request, send_handler handler)\n{\n    // [ code:4 ]\n    // [ block... ]\n    const auto result = build_chunk(\n        {message::to_bytes(ec),\n         block.to_data()});\n\n    handler(message(request, result));\n}\n\nvoid blockchain::block_headers_fetched(const code &ec,\n                                       const std::vector<chain::header> &blocks, const message &request, send_handler handler)\n{\n    data_chunk data;\n    for (auto &block : blocks)\n    {\n        auto chunk = block.to_data();\n        data.insert(data.end(), std::make_move_iterator(chunk.begin()), std::make_move_iterator(chunk.end()));\n    }\n    const auto result = build_chunk(\n        {message::to_bytes(ec),\n         data});\n\n    handler(message(request, result));\n}\n\nvoid blockchain::fetch_block_transaction_hashes(server_node &node,\n                                                const message &request, send_handler handler)\n{\n    const auto &data = request.data();\n\n    if (data.size() == hash_size)\n        fetch_block_transaction_hashes_by_hash(node, request, handler);\n    else if (data.size() == sizeof(uint32_t))\n        fetch_block_transaction_hashes_by_height(node, request, handler);\n    else\n        handler(message(request, error::bad_stream));\n}\n\nvoid blockchain::fetch_block_transaction_hashes_by_hash(server_node &node,\n                                                        const message &request, send_handler handler)\n{\n    const auto &data = request.data();\n    BITCOIN_ASSERT(data.size() == hash_size);\n\n    auto deserial = make_deserializer(data.begin(), data.end());\n    const auto block_hash = deserial.read_hash();\n    node.chain().fetch_block_transaction_hashes(block_hash,\n                                                std::bind(&blockchain::block_transaction_hashes_fetched,\n                                                          _1, _2, request, handler));\n}\n\nvoid blockchain::fetch_block_transaction_hashes_by_height(server_node &node,\n                                                          const message &request, send_handler handler)\n{\n    const auto &data = request.data();\n    BITCOIN_ASSERT(data.size() == sizeof(uint32_t));\n\n    auto deserial = make_deserializer(data.begin(), data.end());\n    const size_t block_height = deserial.read_4_bytes_little_endian();\n    node.chain().fetch_block_transaction_hashes(block_height,\n                                                std::bind(&blockchain::block_transaction_hashes_fetched,\n                                                          _1, _2, request, handler));\n}\n\nvoid blockchain::block_transaction_hashes_fetched(const code &ec,\n                                                  const hash_list &hashes, const message &request, send_handler handler)\n{\n    // [ code:4 ]\n    // [[ hash:32 ]...]\n    data_chunk result(code_size + hash_size * hashes.size());\n    auto serial = make_serializer(result.begin());\n    serial.write_error_code(ec);\n\n    for (const auto &tx_hash : hashes)\n        serial.write_hash(tx_hash);\n\n    handler(message(request, result));\n}\n\nvoid blockchain::fetch_transaction_index(server_node &node,\n                                         const message &request, send_handler handler)\n{\n    const auto &data = request.data();\n\n    if (data.size() != hash_size)\n    {\n        handler(message(request, error::bad_stream));\n        return;\n    }\n\n    auto deserial = make_deserializer(data.begin(), data.end());\n    const auto tx_hash = deserial.read_hash();\n\n    node.chain().fetch_transaction_index(tx_hash,\n                                         std::bind(&blockchain::transaction_index_fetched,\n                                                   _1, _2, _3, request, handler));\n}\n\nvoid blockchain::transaction_index_fetched(const code &ec, size_t block_height,\n                                           size_t index, const message &request, send_handler handler)\n{\n    BITCOIN_ASSERT(index <= max_uint32);\n    BITCOIN_ASSERT(block_height <= max_uint32);\n\n    auto index32 = static_cast<uint32_t>(index);\n    auto block_height32 = static_cast<uint32_t>(block_height);\n\n    // [ code:4 ]\n    // [ block_height:32 ]\n    // [ tx_index:4 ]\n    const auto result = build_chunk(\n        {message::to_bytes(ec),\n         to_little_endian(block_height32),\n         to_little_endian(index32)});\n\n    handler(message(request, result));\n}\n\nvoid blockchain::fetch_spend(server_node &node, const message &request,\n                             send_handler handler)\n{\n    const auto &data = request.data();\n\n    if (data.size() != point_size)\n    {\n        handler(message(request, error::bad_stream));\n        return;\n    }\n\n    using namespace boost::iostreams;\n    static const auto fail_bit = stream<byte_source<data_chunk>>::failbit;\n    stream<byte_source<data_chunk>> istream(data);\n    istream.exceptions(fail_bit);\n    chain::output_point outpoint;\n    outpoint.from_data(istream);\n\n    node.chain().fetch_spend(outpoint,\n                             std::bind(&blockchain::spend_fetched,\n                                       _1, _2, request, handler));\n}\n\nvoid blockchain::spend_fetched(const code &ec, const chain::input_point &inpoint,\n                               const message &request, send_handler handler)\n{\n    // [ code:4 ]\n    // [ hash:32 ]\n    // [ index:4 ]\n    const auto result = build_chunk(\n        {message::to_bytes(ec),\n         inpoint.to_data()});\n\n    handler(message(request, result));\n}\n\nvoid blockchain::fetch_block_height(server_node &node,\n                                    const message &request, send_handler handler)\n{\n    const auto &data = request.data();\n\n    if (data.size() != hash_size)\n    {\n        handler(message(request, error::bad_stream));\n        return;\n    }\n\n    auto deserial = make_deserializer(data.begin(), data.end());\n    const auto block_hash = deserial.read_hash();\n    node.chain().fetch_block_height(block_hash,\n                                    std::bind(&blockchain::block_height_fetched,\n                                              _1, _2, request, handler));\n}\n\nvoid blockchain::block_height_fetched(const code &ec, size_t block_height,\n                                      const message &request, send_handler handler)\n{\n    BITCOIN_ASSERT(block_height <= max_uint32);\n    auto block_height32 = static_cast<uint32_t>(block_height);\n\n    // [ code:4 ]\n    // [ height:4 ]\n    const auto result = build_chunk(\n        {message::to_bytes(ec),\n         to_little_endian(block_height32)});\n\n    handler(message(request, result));\n}\n\nvoid blockchain::fetch_stealth(server_node &node, const message &request,\n                               send_handler handler)\n{\n    const auto &data = request.data();\n\n    if (data.empty())\n    {\n        handler(message(request, error::bad_stream));\n        return;\n    }\n\n    auto deserial = make_deserializer(data.begin(), data.end());\n\n    // number_bits\n    const auto bit_size = deserial.read_byte();\n\n    if (data.size() != sizeof(uint8_t) + binary::blocks_size(bit_size) +\n                           sizeof(uint32_t))\n    {\n        handler(message(request, error::bad_stream));\n        return;\n    }\n\n    // actual bitfield data\n    const auto blocks = deserial.read_data(binary::blocks_size(bit_size));\n    const binary prefix(bit_size, blocks);\n\n    // from_height\n    const uint64_t from_height = deserial.read_4_bytes_little_endian();\n\n    node.chain().fetch_stealth(prefix, from_height,\n                               std::bind(&blockchain::stealth_fetched,\n                                         _1, _2, request, handler));\n}\n\nvoid blockchain::stealth_fetched(const code &ec,\n                                 const stealth_compact::list &stealth_results, const message &request,\n                                 send_handler handler)\n{\n    static constexpr size_t row_size = hash_size + short_hash_size + hash_size;\n\n    // [ code:4 ]\n    // [[ ephemeral_key_hash:32 ][ address_hash:20 ][ tx_hash:32 ]...]\n    data_chunk result(code_size + row_size * stealth_results.size());\n    auto serial = make_serializer(result.begin());\n    serial.write_error_code(ec);\n\n    for (const auto &row : stealth_results)\n    {\n        serial.write_hash(row.ephemeral_public_key_hash);\n        serial.write_short_hash(row.public_key_hash);\n        serial.write_hash(row.transaction_hash);\n    }\n\n    handler(message(request, result));\n}\n\nvoid blockchain::fetch_stealth2(server_node &node, const message &request,\n                                send_handler handler)\n{\n    const auto &data = request.data();\n\n    if (data.empty())\n    {\n        handler(message(request, error::bad_stream));\n        return;\n    }\n\n    auto deserial = make_deserializer(data.begin(), data.end());\n\n    // number_bits\n    const auto bit_size = deserial.read_byte();\n\n    if (data.size() != sizeof(uint8_t) + binary::blocks_size(bit_size) +\n                           sizeof(uint32_t))\n    {\n        handler(message(request, error::bad_stream));\n        return;\n    }\n\n    // actual bitfield data\n    const auto blocks = deserial.read_data(binary::blocks_size(bit_size));\n    const binary prefix(bit_size, blocks);\n\n    // from_height\n    const uint64_t from_height = deserial.read_4_bytes_little_endian();\n\n    node.chain().fetch_stealth(prefix, from_height,\n                               std::bind(&blockchain::stealth_fetched2,\n                                         _1, _2, request, handler));\n}\n\nvoid blockchain::stealth_fetched2(const code &ec,\n                                  const stealth_compact::list &stealth_results, const message &request,\n                                  send_handler handler)\n{\n    // [ code:4 ]\n    // [[ tx_hash:32 ]...]\n    data_chunk result(code_size + hash_size * stealth_results.size());\n    auto serial = make_serializer(result.begin());\n    serial.write_error_code(ec);\n\n    for (const auto &row : stealth_results)\n        serial.write_hash(row.transaction_hash);\n\n    handler(message(request, result));\n}\n\n} // namespace server\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainApp/ucd/server/interface/protocol.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainApp/ucd/interface/protocol.hpp>\n\n#include <cstdint>\n#include <cstddef>\n#include <functional>\n#include <UChainApp/ucd.hpp>\n#include <UChainApp/ucd/config.hpp>\n#include <UChainApp/ucd/messages/message.hpp>\n#include <UChainApp/ucd/server_node.hpp>\n#include <UChainApp/ucd/utility/fetch_helpers.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nusing namespace std::placeholders;\n\n// This does NOT save to our memory pool.\n// The transaction will hit our memory pool when it is picked up from a peer.\nvoid protocol::broadcast_transaction(server_node &node, const message &request,\n                                     send_handler handler)\n{\n    using transaction_ptr = libbitcoin::blockchain::tx_pool::transaction_ptr;\n    using indexes = libbitcoin::blockchain::tx_pool::indexes;\n    static const auto version = bc::message::version::level::maximum;\n    transaction_ptr tx = std::make_shared<bc::message::tx_message>();\n    ;\n    //    bc::message::tx_message tx;\n\n    if (!tx->from_data(version, request.data()))\n    {\n        handler(message(request, error::bad_stream));\n        return;\n    }\n\n    const auto ignore_complete = [](const code &) {};\n    const auto ignore_send = [](const code &, network::channel::ptr) {};\n\n    // Send and hope for the best!\n    //    node.broadcast(tx, ignore_send, ignore_complete);\n\n    node.pool().store(tx, [tx](const code &ec, transaction_ptr) { log::debug(LOG_SERVER) << encode_hash(tx->hash()) << \" confirmed\"; }, [handler, request, tx](const code &ec, transaction_ptr, indexes) {\n        log::debug(LOG_SERVER) << encode_hash(tx->hash()) << \" validated\";\n        handler(message(request, ec)); });\n\n    // Tell the user everything is fine.\n}\n\nvoid protocol::total_connections(server_node &node, const message &request,\n                                 send_handler handler)\n{\n    if (!request.data().empty())\n    {\n        handler(message(request, error::bad_stream));\n        return;\n    }\n\n    node.connected_count(\n        std::bind(&protocol::handle_total_connections,\n                  _1, request, handler));\n}\n\nvoid protocol::handle_total_connections(size_t count, const message &request,\n                                        send_handler handler)\n{\n    BITCOIN_ASSERT(count <= max_uint32);\n    const auto total_connections = static_cast<uint32_t>(count);\n\n    // [ code:4 ]\n    // [ connections:4 ]\n    const auto result = build_chunk(\n        {message::to_bytes(error::success),\n         to_little_endian(total_connections)});\n\n    handler(message(request, result));\n}\n\n} // namespace server\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainApp/ucd/server/interface/tx_pool.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainApp/ucd/interface/tx_pool.hpp>\n\n#include <cstdint>\n#include <cstddef>\n#include <functional>\n#include <memory>\n#include <UChainApp/ucd/config.hpp>\n#include <UChainApp/ucd/messages/message.hpp>\n#include <UChainApp/ucd/server_node.hpp>\n#include <UChainApp/ucd/utility/fetch_helpers.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nusing namespace std::placeholders;\nusing namespace bc::chain;\nusing namespace bc::message;\n\nvoid tx_pool::fetch_transaction(server_node &node,\n                                         const message &request, send_handler handler)\n{\n    hash_digest hash;\n\n    if (!unwrap_fetch_transaction_args(hash, request))\n    {\n        handler(message(request, error::bad_stream));\n        return;\n    }\n\n    log::debug(LOG_SERVER)\n        << \"tx_pool.fetch_transaction(\" << encode_hash(hash) << \")\";\n\n    node.pool().fetch(hash,\n                      std::bind(pool_transaction_fetched,\n                                _1, _2, request, handler));\n}\n\n// Broadcast a transaction with penetration subscription.\nvoid tx_pool::broadcast(server_node &node, const message &request,\n                                 send_handler handler)\n{\n    transaction tx;\n\n    if (!tx.from_data(request.data()))\n    {\n        handler(message(request, error::bad_stream));\n        return;\n    }\n\n    // TODO: conditionally subscribe to penetration notifications.\n    // TODO: broadcast transaction to receiving peers.\n    handler(message(request, error::operation_failed));\n}\n\n// NOTE: the format of this response changed in v3 (send only code on error).\nvoid tx_pool::validate(server_node &node, const message &request,\n                                send_handler handler)\n{\n    static const auto version = bc::message::version::level::maximum;\n    const auto tx = std::make_shared<tx_message>();\n\n    if (!tx->from_data(version, request.data()))\n    {\n        handler(message(request, error::bad_stream));\n        return;\n    }\n\n    node.pool().validate(tx,\n                         std::bind(&tx_pool::handle_validated,\n                                   _1, _2, _3, request, handler));\n}\n\nvoid tx_pool::handle_validated(const code &ec,\n                                        tx_message::ptr, const point::indexes &unconfirmed,\n                                        const message &request, send_handler handler)\n{\n    // [ code:4 ]\n    // [[ unconfirmed_index:4 ]...]\n    data_chunk result(code_size + unconfirmed.size() * index_size);\n    auto serial = make_serializer(result.begin());\n    serial.write_error_code(ec);\n\n    for (const auto unconfirmed_index : unconfirmed)\n    {\n        BITCOIN_ASSERT(unconfirmed_index <= max_uint32);\n        const auto index32 = static_cast<uint32_t>(unconfirmed_index);\n        serial.write_4_bytes_little_endian(index32);\n    }\n\n    handler(message(request, result));\n}\n\n} // namespace server\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainApp/ucd/server/messages/message.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainApp/ucd/messages/message.hpp>\n\n#include <cstdint>\n#include <string>\n#include <UChain/protocol.hpp>\n#include <UChainApp/ucd/messages/route.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nusing namespace bc::protocol;\n\n// Protocol delimitation migration plan.\n//-----------------------------------------------------------------------------\n//    v1/v2 server: ROUTER, requires not delimited\n//       v3 server: ROUTER, allows/echos delimited\n// v1/v2/v3 client: DEALER (not delimited)\n//-----------------------------------------------------------------------------\n//       v4 server: ROUTER, requires delimited\n//       v4 client: DEALER (delimited) or REQ\n//-----------------------------------------------------------------------------\n\n// Convert an error code to data for payload.\ndata_chunk message::to_bytes(const code &ec)\n{\n    return build_chunk(\n        {to_little_endian(static_cast<uint32_t>(ec.value()))});\n}\n\n// Constructors.\n//-------------------------------------------------------------------------\n\n// Construct an empty message with security routing context.\nmessage::message(bool secure)\n{\n    // For subscriptions, directs notifier to respond on secure endpoint.\n    route_.secure = secure;\n}\n\n// Construct a response for the request (response code only).\nmessage::message(const message &request, const code &ec)\n    : message(request, to_bytes(ec))\n{\n}\n\n// Construct a response for the request (response data with code).\nmessage::message(const message &request, const data_chunk &data)\n    : message(request.route(), request.command(), request.id(), data)\n{\n}\n\n// Construct a response for the route (subscription code only).\nmessage::message(const server::route &route, const std::string &command,\n                 uint32_t id, const code &ec)\n    : message(route, command, id, to_bytes(ec))\n{\n}\n\n// Construct a response for the route (subscription data with code).\nmessage::message(const server::route &route, const std::string &command,\n                 uint32_t id, const data_chunk &data)\n    : route_(route), command_(command), id_(id), data_(data)\n{\n}\n\n// Properties.\n//-------------------------------------------------------------------------\n\n/// Arbitrary caller data (returned to caller for correlation).\nuint32_t message::id() const\n{\n    return id_;\n}\n\n/// Serialized query or response (defined in relation to command).\nconst data_chunk &message::data() const\n{\n    return data_;\n}\n\n/// Query command (used for subscription, always returned to caller).\nconst std::string &message::command() const\n{\n    return command_;\n}\n\n/// The message route.\nconst server::route &message::route() const\n{\n    return route_;\n}\n\n// Transport.\n//-------------------------------------------------------------------------\n\ncode message::receive(zmq::socket &socket)\n{\n    zmq::message message;\n    auto ec = socket.receive(message);\n\n    if (ec)\n        return ec;\n\n    if (message.size() < 5 || message.size() > 6)\n        return error::bad_stream;\n\n    // Decode the routing information (TODO: generalize in route).\n    //-------------------------------------------------------------------------\n\n    // Client is undelimited DEALER -> 2 addresses with no delimiter.\n    // Client is REQ or delimited DEALER -> 2 addresses with delimiter.\n    route_.address1 = message.dequeue_data();\n    route_.address2 = message.dequeue_data();\n\n    // In the reply we echo the delimited-ness of the original request.\n    route_.delimited = message.size() == 4;\n\n    if (route_.delimited)\n        message.dequeue();\n\n    // All libbitcoin queries and responses have these three frames.\n    //-------------------------------------------------------------------------\n\n    // Query command (returned to caller).\n    command_ = message.dequeue_text();\n\n    // Arbitrary caller data (returned to caller for correlation).\n    if (!message.dequeue(id_))\n        return error::bad_stream;\n\n    // Serialized query.\n    data_ = message.dequeue_data();\n\n    return error::success;\n}\n\ncode message::send(zmq::socket &socket)\n{\n    zmq::message message;\n\n    // Encode the routing information (TODO: generalize in route).\n    //-------------------------------------------------------------------------\n\n    // Client is undelimited DEALER -> 2 addresses with no delimiter.\n    // Client is REQ or delimited DEALER -> 2 addresses with delimiter.\n    message.enqueue(route_.address1);\n    message.enqueue(route_.address2);\n\n    // In the reply we echo the delimited-ness of the original request.\n    if (route_.delimited)\n        message.enqueue();\n\n    // All libbitcoin queries and responses have these three frames.\n    //-------------------------------------------------------------------------\n    message.enqueue(command_);\n    message.enqueue_little_endian(id_);\n    message.enqueue(data_);\n\n    return socket.send(message);\n}\n\n} // namespace server\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainApp/ucd/server/messages/route.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainApp/ucd/messages/route.hpp>\n\n#include <string>\n#include <boost/functional/hash_fwd.hpp>\n#include <UChain/coin.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nroute::route()\n    : secure(false), delimited(false)\n{\n}\n\nstd::string route::display() const\n{\n  return \"[\" + encode_base16(address1) +\n         /*\":\" + encode_base16(address2) +*/ \"]\";\n}\n\nbool route::operator==(const route &other) const\n{\n  return secure == other.secure && /*delimited == other.delimited &&*/\n         address1 == other.address1 /*&& address2 == other.address2*/;\n}\n\n} // namespace server\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainApp/ucd/server/parser.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainApp/ucd/parser.hpp>\n\n#include <cstdint>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <UChain/node.hpp>\n#include <UChainApp/ucd/define.hpp>\n#include <UChainApp/ucd/settings.hpp>\n#include <UChainService/txs/utility/path.hpp>\n\nBC_DECLARE_CONFIG_DEFAULT_PATH(\".UChain\" / \"uc.conf\")\n\n// TODO: localize descriptions.\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nusing namespace boost::filesystem;\nusing namespace boost::program_options;\nusing namespace bc::config;\nusing namespace bc::network;\n\n// Initialize configuration by copying the given instance.\nparser::parser(const configuration defaults)\n    : configured(defaults)\n{\n}\n\n// Initialize configuration using defaults of the given context.\nparser::parser(bc::settings context)\n    : configured(context)\n{\n}\n\noptions_metadata parser::load_options()\n{\n    options_metadata description(\"options\");\n    description.add_options()(\n        BS_CONFIG_VARIABLE \",c\",\n        value<path>(&configured.file)->default_value(\"uc.conf\"),\n        \"Specify path to a configuration settings file based on path ~/.UChain\")(\n        BS_HELP_VARIABLE \",h\",\n        value<bool>(&configured.help)->default_value(false)->zero_tokens(),\n        \"Display command line options.\")(\n        \"initchain,i\",\n        value<bool>(&configured.initchain)->default_value(false)->zero_tokens(),\n        \"Initialize blockchain in the configured directory.\")(\n        BS_SETTINGS_VARIABLE \",s\",\n        value<bool>(&configured.settings)->default_value(false)->zero_tokens(),\n        \"Display all configuration settings.\")(\n        BS_VERSION_VARIABLE \",v\",\n        value<bool>(&configured.version)->default_value(false)->zero_tokens(),\n        \"Display version information.\")(\n        BS_DAEMON_VARIABLE \",d\",\n        value<bool>(&configured.daemon)->default_value(false)->zero_tokens(),\n        \"Run in daemon mode (unix/apple).\")\n        /*(\n        \"testnet,t\",\n        value<bool>(&configured.use_testnet_rules)->\n            default_value(false)->zero_tokens(),\n        \"Use testnet rules for determination of work required, defaults to false.\"\n    )*/\n        (\n            BS_DATADIR_VARIABLE \",D\",\n            value<path>(&configured.data_dir)->default_value(default_data_path()),\n            \"Specify ucd workspace path.\")(\n            BS_UI_VARIABLE \",u\",\n            value<bool>(&configured.ui)->default_value(false),\n            \"Open wallet UI.\")(\n            \"upnp,U\",\n            value<bool>(&configured.upnp_map_port)->default_value(true)->zero_tokens(),\n            \"Add a upnp map port in your router which has a extern address to allow connections to your local address.\");\n\n    return description;\n}\n\narguments_metadata parser::load_arguments()\n{\n    arguments_metadata description;\n    return description\n        .add(BS_CONFIG_VARIABLE, 1);\n}\n\noptions_metadata parser::load_environment()\n{\n    options_metadata description(\"environment\");\n    description.add_options()(\n        // For some reason po requires this to be a lower case name.\n        // The case must match the other declarations for it to compose.\n        // This composes with the cmdline options and inits to system path.\n        BS_CONFIG_VARIABLE,\n        value<path>(&configured.file)->composing()->default_value(config_default_path()),\n        \"The path to the configuration settings file.\");\n\n    return description;\n}\n\noptions_metadata parser::load_settings()\n{\n    options_metadata description(\"settings\");\n    description.add_options()\n        /* [network] */\n        (\n            \"network.threads\",\n            value<uint32_t>(&configured.network.threads),\n            \"The minimum number of threads in the application threadpool, defaults to 50.\")(\n            \"network.protocol\",\n            value<uint32_t>(&configured.network.protocol),\n            \"The network protocol version, defaults to 70012.\")(\n            \"network.identifier\",\n            value<uint32_t>(&configured.network.identifier),\n            \"The magic number for message headers, defaults to 0x6d73766d.\")(\n            \"network.inbound_port\",\n            value<uint16_t>(&configured.network.inbound_port),\n            \"The port for incoming connections, defaults to 5682.\")(\n            \"network.inbound_connections\",\n            value<uint32_t>(&configured.network.inbound_connections),\n            \"The target number of incoming network connections, defaults to 8.\")(\n            \"network.outbound_connections\",\n            value<uint32_t>(&configured.network.outbound_connections),\n            \"The target number of outgoing network connections, defaults to 8.\")(\n            \"network.manual_attempt_limit\",\n            value<uint32_t>(&configured.network.manual_attempt_limit),\n            \"The attempt limit for manual connection establishment, defaults to 0 (forever).\")(\n            \"network.connect_batch_size\",\n            value<uint32_t>(&configured.network.connect_batch_size),\n            \"The number of concurrent attempts to estalish one connection, defaults to 5.\")(\n            \"network.connect_timeout_seconds\",\n            value<uint32_t>(&configured.network.connect_timeout_seconds),\n            \"The time limit for connection establishment, defaults to 5.\")(\n            \"network.channel_handshake_seconds\",\n            value<uint32_t>(&configured.network.channel_handshake_seconds),\n            \"The time limit to complete the connection handshake, defaults to 30.\")(\n            \"network.channel_heartbeat_minutes\",\n            value<uint32_t>(&configured.network.channel_heartbeat_minutes),\n            \"The time between ping messages, defaults to 5.\")(\n            \"network.channel_inactivity_minutes\",\n            value<uint32_t>(&configured.network.channel_inactivity_minutes),\n            \"The inactivity time limit for any connection, defaults to 30.\")(\n            \"network.channel_expiration_minutes\",\n            value<uint32_t>(&configured.network.channel_expiration_minutes),\n            \"The maximum age limit for an outbound connection, defaults to 1440.\")(\n            \"network.channel_germination_seconds\",\n            value<uint32_t>(&configured.network.channel_germination_seconds),\n            \"The maximum time limit for obtaining seed addresses, defaults to 30.\")(\n            \"network.host_pool_capacity\",\n            value<uint32_t>(&configured.network.host_pool_capacity),\n            \"The maximum number of peer hosts in the pool, defaults to 1000.\")(\n            \"network.relay_transactions\",\n            value<bool>(&configured.network.relay_transactions),\n            \"Request that peers relay transactions, defaults to true.\")(\n            \"network.enable_re_seeding\",\n            value<bool>(&configured.network.enable_re_seeding),\n            \"Re-connect the seed nodes to refresh local hosts cache, when the actual number of outgoing network connection <= 1. defaults to true.\")(\n            \"network.hosts_file\",\n            value<path>(&configured.network.hosts_file),\n            \"The peer hosts cache file path, defaults to 'hosts.cache'.\")(\n            \"network.debug_file\",\n            value<path>(&configured.network.debug_file),\n            \"The debug log file path, defaults to 'debug.log'.\")(\n            \"network.error_file\",\n            value<path>(&configured.network.error_file),\n            \"The error log file path, defaults to 'error.log'.\")(\n            \"network.self\",\n            value<config::authority>(&configured.network.self),\n            \"The advertised public address of this node, defaults to none.\")(\n            \"network.blacklist\",\n            value<config::authority::list>(&configured.network.blacklists),\n            \"IP address to disallow as a peer, multiple entries allowed.\")(\n            \"network.peer\",\n            value<config::endpoint::list>(&configured.network.peers),\n            \"Persistent host:port channels, multiple entries allowed.\")(\n            \"network.upnp_map_port\",\n            value<bool>(&configured.network.upnp_map_port),\n            \"Add a upnp map port in your router which has a extern address to allow connections to your local address.\")(\n            \"network.be_found\",\n            value<bool>(&configured.network.be_found),\n            \"If broadcast your upnp extern address on the network to allow others find you and connect you.\")(\n            \"network.seed\",\n            value<config::endpoint::list>(&configured.network.seeds),\n            \"A seed node for initializing the host pool, multiple entries allowed.\")\n        /* [database] */\n        (\n            \"database.history_start_height\",\n            value<uint32_t>(&configured.database.history_start_height),\n            \"The lower limit of spend indexing, defaults to 0.\")(\n            \"database.stealth_start_height\",\n            value<uint32_t>(&configured.database.stealth_start_height),\n            \"The lower limit of stealth indexing, defaults to 350000.\")(\n            \"database.directory\",\n            value<path>(&configured.database.directory),\n            \"The blockchain database directory, defaults to 'mainnet'.\")\n\n        /* [blockchain] */\n        (\n            \"blockchain.block_pool_capacity\",\n            value<uint32_t>(&configured.chain.block_pool_capacity),\n            \"The maximum number of orphan blocks in the pool, defaults to 50.\")(\n            \"blockchain.tx_pool_capacity\",\n            value<uint32_t>(&configured.chain.tx_pool_capacity),\n            \"The maximum number of transactions in the pool, defaults to 2000.\")(\n            \"blockchain.tx_pool_consistency\",\n            value<bool>(&configured.chain.tx_pool_consistency),\n            \"Enforce consistency between the pool and the blockchain, defaults to false.\")(\n            \"blockchain.use_testnet_rules\",\n            value<bool>(&configured.chain.use_testnet_rules),\n            \"Use testnet rules for determination of work required, defaults to false.\")(\n            \"blockchain.checkpoint\",\n            value<config::checkpoint::list>(&configured.chain.checkpoints),\n            \"A hash:height checkpoint, multiple entries allowed.\")\n\n        /* [node] */\n        (\n            \"node.block_timeout_seconds\",\n            value<uint32_t>(&configured.node.block_timeout_seconds),\n            \"The time limit for block receipt during initial block download, defaults to 5.\")(\n            \"node.download_connections\",\n            value<uint32_t>(&configured.node.download_connections),\n            \"The maximum number of connections for initial block download, defaults to 8.\")(\n            \"node.tx_pool_refresh\",\n            value<bool>(&configured.node.tx_pool_refresh),\n            \"Refresh the transaction pool on reorganization and channel start, defaults to true.\")\n\n        /* [server] */\n        (\n            \"server.administrator_required\",\n            value<bool>(&configured.server.administrator_required),\n            \"Whether wallet needs administrator to execute non-wallet commands(shutdown/showinfo...), defaults to false.\")(\n            \"server.read_only\",\n            value<bool>(&configured.server.read_only),\n            \"Whether read request allowed, defaults to false.\")(\n            \"server.mongoose_listen\",\n            value<std::string>(&configured.server.mongoose_listen),\n            \"The listening port for mongoose(Json-RPC), defaults to 127.0.0.1:8707.\")(\n            \"server.websocket_listen\",\n            value<std::string>(&configured.server.websocket_listen),\n            \"The listening port for websocket pub/sub service, defaults to 127.0.0.1:28707.\")(\n            \"server.query_workers\",\n            value<uint16_t>(&configured.server.query_workers),\n            \"The number of query worker threads per endpoint, defaults to 1.\")(\n            \"server.heartbeat_interval_seconds\",\n            value<uint32_t>(&configured.server.heartbeat_interval_seconds),\n            \"The heartbeat interval, defaults to 5.\")(\n            \"server.subscription_expiration_minutes\",\n            value<uint32_t>(&configured.server.subscription_expiration_minutes),\n            \"The subscription expiration time, defaults to 10.\")(\n            \"server.subscription_limit\",\n            value<uint32_t>(&configured.server.subscription_limit),\n            \"The maximum number of subscriptions, defaults to 100000000.\")(\n            \"server.log_level\",\n            value<std::string>(&configured.server.log_level),\n            \"Setup log level of debug log in level [TRACE,DEBUG,INFO], defaults to DEBUG.\")(\n            \"server.secure_only\",\n            value<bool>(&configured.server.secure_only),\n            \"Disable public endpoints, defaults to false.\")(\n            \"server.query_service_enabled\",\n            value<bool>(&configured.server.query_service_enabled),\n            \"Enable the query service, defaults to true.\")(\n            \"server.heartbeat_service_enabled\",\n            value<bool>(&configured.server.heartbeat_service_enabled),\n            \"Enable the heartbeat service, defaults to false.\")(\n            \"server.block_service_enabled\",\n            value<bool>(&configured.server.block_service_enabled),\n            \"Enable the block publishing service, defaults to false.\")(\n            \"server.tx_service_enabled\",\n            value<bool>(&configured.server.tx_service_enabled),\n            \"Enable the transaction publishing service, defaults to false.\")(\n            \"server.websocket_service_enabled\",\n            value<bool>(&configured.server.websocket_service_enabled),\n            \"Enable the websocket pub/sub service, defaults to false.\")(\n            \"server.public_query_endpoint\",\n            value<endpoint>(&configured.server.public_query_endpoint),\n            \"The public query endpoint, defaults to 'tcp://*:18707'.\")(\n            \"server.public_heartbeat_endpoint\",\n            value<endpoint>(&configured.server.public_heartbeat_endpoint),\n            \"The public heartbeat endpoint, defaults to 'tcp://*:9092'.\")(\n            \"server.public_block_endpoint\",\n            value<endpoint>(&configured.server.public_block_endpoint),\n            \"The public block publishing endpoint, defaults to 'tcp://*:9093'.\")(\n            \"server.public_transaction_endpoint\",\n            value<endpoint>(&configured.server.public_transaction_endpoint),\n            \"The public transaction publishing endpoint, defaults to 'tcp://*:9094'.\")(\n            \"server.secure_query_endpoint\",\n            value<endpoint>(&configured.server.secure_query_endpoint),\n            \"The secure query endpoint, defaults to 'tcp://*:9081'.\")(\n            \"server.secure_heartbeat_endpoint\",\n            value<endpoint>(&configured.server.secure_heartbeat_endpoint),\n            \"The secure heartbeat endpoint, defaults to 'tcp://*:9082'.\")(\n            \"server.secure_block_endpoint\",\n            value<endpoint>(&configured.server.secure_block_endpoint),\n            \"The secure block publishing endpoint, defaults to 'tcp://*:9083'.\")(\n            \"server.secure_transaction_endpoint\",\n            value<endpoint>(&configured.server.secure_transaction_endpoint),\n            \"The secure transaction publishing endpoint, defaults to 'tcp://*:9084'.\")(\n            \"server.server_private_key\",\n            value<config::sodium>(&configured.server.server_private_key),\n            \"The Z85-encoded private key of the server, enables secure endpoints.\")(\n            \"server.client_public_key\",\n            value<config::sodium::list>(&configured.server.client_public_keys),\n            \"Allowed Z85-encoded public key of the client, multiple entries allowed.\")(\n            \"server.client_address\",\n            value<config::authority::list>(&configured.server.client_addresses),\n            \"Allowed client IP address, multiple entries allowed.\");\n\n    return description;\n}\n\nbool parser::parse(int argc, const char *argv[], std::ostream &error)\n{\n    try\n    {\n        auto file = false;\n        variables_map variables;\n        load_command_variables(variables, argc, argv);\n        load_environment_variables(variables, BS_ENVIRONMENT_VARIABLE_PREFIX);\n\n        // Don't load the rest if any of these options are specified.\n        if (!get_option(variables, BS_VERSION_VARIABLE) &&\n            !get_option(variables, BS_SETTINGS_VARIABLE) &&\n            !get_option(variables, BS_HELP_VARIABLE))\n        {\n            if (get_option(variables, BS_TESTNET_VARIABLE))\n            {\n                configured.network.hosts_file = \"hosts-test.cache\";\n                const_cast<path &>(variables[BS_CONFIG_VARIABLE].as<path>()) = \"uc-test.conf\";\n            }\n            auto data_dir = variables[BS_DATADIR_VARIABLE].as<path>();\n            if (!data_dir.empty())\n            {\n                if (boost::filesystem::exists(data_dir) && !boost::filesystem::is_directory(data_dir))\n                {\n                    error << format_invalid_parameter(\"datadir path is invalid.\") << std::endl;\n                    return false;\n                }\n            }\n            // Returns true if the settings were loaded from a file.\n            file = load_configuration_variables(variables, BS_CONFIG_VARIABLE);\n        }\n\n        // Update bound variables in metadata.settings.\n        notify(variables);\n\n        // Clear the config file path if it wasn't used.\n        if (!file)\n            configured.file.clear();\n    }\n    catch (const boost::program_options::error &e)\n    {\n        // This is obtained from boost, which circumvents our localization.\n        error << format_invalid_parameter(e.what()) << std::endl;\n        return false;\n    }\n\n    return true;\n}\n\n} // namespace server\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainApp/ucd/server/server_node.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainApp/ucd/server_node.hpp>\n\n#include <cstdint>\n#include <functional>\n#include <memory>\n#include <UChain/node.hpp>\n#include <UChainApp/ucd/config.hpp>\n#include <UChainApp/ucd/messages/route.hpp>\n#include <UChainApp/ucd/workers/query_worker.hpp>\n#include <UChainService/api/rest.hpp>\n\n#include <thread>\n\n#ifdef _WIN32\n#include <tchar.h>\n#include <windows.h>\n#include <shellapi.h>\n#endif\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nusing namespace std::placeholders;\nusing namespace bc::chain;\nusing namespace bc::node;\nusing namespace bc::protocol;\n\nserver_node::server_node(const configuration &configuration)\n    : p2p_node(configuration),\n      under_blockchain_sync_(true),\n      configuration_(configuration),\n      authenticator_(*this),\n      secure_query_service_(authenticator_, *this, true),\n      public_query_service_(authenticator_, *this, false),\n      secure_heartbeat_service_(authenticator_, *this, true),\n      public_heartbeat_service_(authenticator_, *this, false),\n      secure_block_service_(authenticator_, *this, true),\n      public_block_service_(authenticator_, *this, false),\n      secure_tx_service_(authenticator_, *this, true),\n      public_tx_service_(authenticator_, *this, false),\n      secure_notification_worker_(authenticator_, *this, true),\n      public_notification_worker_(authenticator_, *this, false),\n      miner_(*this),\n      rest_server_(new mgbubble::RestServ(webpage_path_.string().data(), *this, configuration.server.mongoose_listen)),\n      push_server_(new mgbubble::WsPushServ(*this, configuration.server.websocket_listen))\n{\n}\n\n// This allows for shutdown based on destruct without need to call stop.\nserver_node::~server_node()\n{\n    server_node::close();\n}\n\n// Properties.\n// ----------------------------------------------------------------------------\n\nconst settings &server_node::server_settings() const\n{\n    return configuration_.server;\n}\n\n// Run sequence.\n// ----------------------------------------------------------------------------\n\nvoid server_node::run(result_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped);\n        return;\n    }\n\n    if (!rest_server_->start() || !push_server_->start())\n    {\n        log::error(LOG_SERVER) << \"Http/Websocket server can not start.\";\n        handler(error::operation_failed);\n        return;\n    }\n\n    // The handler is invoked on a new thread.\n    p2p_node::run(\n        std::bind(&server_node::handle_running,\n                  this, _1, handler));\n}\n\nvoid server_node::handle_running(const code &ec, result_handler handler)\n{\n    if (stopped())\n    {\n        handler(error::service_stopped);\n        return;\n    }\n\n    if (ec)\n    {\n        handler(ec);\n        return;\n    }\n\n    if (!start_services())\n    {\n        handler(error::operation_failed);\n        return;\n    }\n\n    under_blockchain_sync_.store(false, std::memory_order_relaxed);\n\n    // This is the end of the derived run sequence.\n    handler(error::success);\n}\n\n// Shutdown.\n// ----------------------------------------------------------------------------\n\nbool server_node::stop()\n{\n    // Suspend new work last so we can use work to clear subscribers.\n    return authenticator_.stop() && p2p_node::stop();\n}\n\n// This must be called from the thread that constructed this class (see join).\nbool server_node::close()\n{\n    // Invoke own stop to signal work suspension, then close node and join.\n    return server_node::stop() && p2p_node::close();\n}\n\n/// Get miner.\nconsensus::miner &server_node::miner()\n{\n    return miner_;\n}\n\n// Notification.\n// ----------------------------------------------------------------------------\n\n// Subscribe to address (including stealth) prefix notifications.\nvoid server_node::subscribe_address(const route &reply_to, uint32_t id,\n                                    const binary &prefix_filter, subscribe_type type)\n{\n    if (reply_to.secure)\n        secure_notification_worker_\n            .subscribe_address(reply_to, id, prefix_filter, type);\n    else\n        public_notification_worker_\n            .subscribe_address(reply_to, id, prefix_filter, type);\n}\n\n// Subscribe to transaction penetration notifications.\nvoid server_node::subscribe_penetration(const route &reply_to, uint32_t id,\n                                        const hash_digest &tx_hash)\n{\n    if (reply_to.secure)\n        secure_notification_worker_\n            .subscribe_penetration(reply_to, id, tx_hash);\n    else\n        public_notification_worker_\n            .subscribe_penetration(reply_to, id, tx_hash);\n}\n\n// Services.\n// ----------------------------------------------------------------------------\n\nbool server_node::start_services()\n{\n    return start_authenticator() && start_query_services() &&\n           start_heartbeat_services() && start_block_services() &&\n           start_tx_services();\n}\n\nbool server_node::start_authenticator()\n{\n    const auto &settings = configuration_.server;\n    const auto heartbeat_interval = settings.heartbeat_interval_seconds;\n\n    if ((!settings.server_private_key && settings.secure_only) ||\n        ((!settings.query_service_enabled || settings.query_workers == 0) &&\n         (!settings.heartbeat_service_enabled || heartbeat_interval == 0) &&\n         (!settings.block_service_enabled) &&\n         (!settings.tx_service_enabled)))\n        return true;\n\n    return authenticator_.start();\n}\n\nbool server_node::start_query_services()\n{\n    const auto &settings = configuration_.server;\n\n    if (!settings.query_service_enabled || settings.query_workers == 0)\n        return true;\n\n    // Start secure service, query workers and notification workers if enabled.\n    if (settings.server_private_key && (!secure_query_service_.start() ||\n                                        (settings.subscription_limit > 0 && !secure_notification_worker_.start()) ||\n                                        !start_query_workers(true)))\n        return false;\n\n    // Start public service, query workers and notification workers if enabled.\n    if (!settings.secure_only && (!public_query_service_.start() ||\n                                  (settings.subscription_limit > 0 && !public_notification_worker_.start()) ||\n                                  !start_query_workers(false)))\n        return false;\n\n    return true;\n}\n\nbool server_node::start_heartbeat_services()\n{\n    const auto &settings = configuration_.server;\n\n    if (!settings.heartbeat_service_enabled ||\n        settings.heartbeat_interval_seconds == 0)\n        return true;\n\n    // Start secure service if enabled.\n    if (settings.server_private_key && !secure_heartbeat_service_.start())\n        return false;\n\n    // Start public service if enabled.\n    if (!settings.secure_only && !public_heartbeat_service_.start())\n        return false;\n\n    return true;\n}\n\nbool server_node::start_block_services()\n{\n    const auto &settings = configuration_.server;\n\n    if (!settings.block_service_enabled)\n        return true;\n\n    // Start secure service if enabled.\n    if (settings.server_private_key && !secure_block_service_.start())\n        return false;\n\n    // Start public service if enabled.\n    if (!settings.secure_only && !public_block_service_.start())\n        return false;\n\n    return true;\n}\n\nbool server_node::start_tx_services()\n{\n    const auto &settings = configuration_.server;\n\n    if (!settings.tx_service_enabled)\n        return true;\n\n    // Start secure service if enabled.\n    if (settings.server_private_key && !secure_tx_service_.start())\n        return false;\n\n    // Start public service if enabled.\n    if (!settings.secure_only && !public_tx_service_.start())\n        return false;\n\n    return true;\n}\n\n// Called from start_query_services.\nbool server_node::start_query_workers(bool secure)\n{\n    auto &server = *this;\n    const auto &settings = configuration_.server;\n\n    for (auto count = 0; count < settings.query_workers; ++count)\n    {\n        auto worker = std::make_shared<query_worker>(authenticator_,\n                                                     server, secure);\n\n        if (!worker->start())\n            return false;\n\n        subscribe_stop([=](const code &) { worker->stop(); });\n    }\n\n    return true;\n}\n\nbool server_node::open_ui()\n{\n#ifdef _WIN32\n    const TCHAR szOperation[] = _T(\"open\");\n    const TCHAR szAddress[] = _T(\"http://127.0.0.1:8707\");\n    HINSTANCE hRslt = ShellExecute(NULL, szOperation,\n                                   szAddress, NULL, NULL, SW_SHOWNORMAL);\n\n    if (hRslt <= (HINSTANCE)HINSTANCE_ERROR)\n        log::error(\"shell execute failed when open UI\");\n    return false;\n    log::info(\"UI on display\");\n#endif\n    return true;\n}\n\n// static\nuint32_t server_node::threads_required(const configuration &configuration)\n{\n    const auto &settings = configuration.server;\n    const auto threads = configuration.network.threads;\n    const auto heartbeat_interval = settings.heartbeat_interval_seconds;\n\n    // The network/node requires a minimum of one thread.\n    uint32_t required = 1;\n\n    if (settings.query_service_enabled && settings.query_workers > 0)\n    {\n        if (settings.server_private_key)\n        {\n            ++required;\n            required += settings.query_workers;\n            required += (settings.subscription_limit > 0 ? 4 : 0);\n        }\n\n        if (!settings.secure_only)\n        {\n            ++required;\n            required += settings.query_workers;\n            required += (settings.subscription_limit > 0 ? 4 : 0);\n        }\n    }\n\n    if (settings.heartbeat_service_enabled && heartbeat_interval > 0)\n    {\n        required += (settings.server_private_key ? 1 : 0);\n        required += (settings.secure_only ? 0 : 1);\n    }\n\n    if (settings.block_service_enabled)\n    {\n        required += (settings.server_private_key ? 1 : 0);\n        required += (settings.secure_only ? 0 : 1);\n    }\n\n    if (settings.tx_service_enabled)\n    {\n        required += (settings.server_private_key ? 1 : 0);\n        required += (settings.secure_only ? 0 : 1);\n    }\n\n    // If any services are enabled increment for the authenticator.\n    return required == 1 ? required : required + 1;\n}\n\nboost::filesystem::path server_node::webpage_path_ = webpage_path();\n\n} // namespace server\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainApp/ucd/server/services/block_service.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainApp/ucd/services/block_service.hpp>\n\n#include <cstdint>\n#include <functional>\n#include <memory>\n#include <UChain/protocol.hpp>\n#include <UChainApp/ucd/config.hpp>\n#include <UChainApp/ucd/server_node.hpp>\n#include <UChainApp/ucd/settings.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nusing namespace std::placeholders;\nusing namespace bc::chain;\nusing namespace bc::protocol;\n\nstatic const auto domain = \"block\";\nconst config::endpoint block_service::public_worker(\"inproc://public_block\");\nconst config::endpoint block_service::secure_worker(\"inproc://secure_block\");\n\nblock_service::block_service(zmq::authenticator &authenticator,\n                             server_node &node, bool secure)\n    : worker(node.thread_pool()),\n      secure_(secure),\n      settings_(node.server_settings()),\n      authenticator_(authenticator),\n      node_(node)\n{\n}\n\n// There is no unsubscribe so this class shouldn't be restarted.\nbool block_service::start()\n{\n    // Subscribe to blockchain reorganizations.\n    node_.subscribe_blockchain(\n        std::bind(&block_service::handle_reorganization,\n                  this, _1, _2, _3, _4));\n\n    return zmq::worker::start();\n}\n\n// No unsubscribe so must be kept in scope until subscriber stop complete.\nbool block_service::stop()\n{\n    return zmq::worker::stop();\n}\n\n// Implement worker as extended pub-sub.\n// The publisher drops messages for lost peers (clients) and high water.\nvoid block_service::work()\n{\n    zmq::socket xpub(authenticator_, zmq::socket::role::extended_publisher);\n    zmq::socket xsub(authenticator_, zmq::socket::role::extended_subscriber);\n\n    // Bind sockets to the service and worker endpoints.\n    if (!started(bind(xpub, xsub)))\n        return;\n\n    // TODO: tap in to failure conditions, such as high water.\n    // Relay messages between subscriber and publisher (blocks on context).\n    relay(xpub, xsub);\n\n    // Unbind the sockets and exit this thread.\n    finished(unbind(xpub, xsub));\n}\n\n// Bind/Unbind.\n//-----------------------------------------------------------------------------\n\nbool block_service::bind(zmq::socket &xpub, zmq::socket &xsub)\n{\n    const auto security = secure_ ? \"secure\" : \"public\";\n    const auto &worker = secure_ ? secure_worker : public_worker;\n    const auto &service = secure_ ? settings_.secure_block_endpoint : settings_.public_block_endpoint;\n\n    if (!authenticator_.apply(xpub, domain, secure_))\n        return false;\n\n    auto ec = xpub.bind(service);\n\n    if (ec)\n    {\n        log::error(LOG_SERVER)\n            << \"Failed to bind \" << security << \" block service to \"\n            << service << \" : \" << ec.message();\n        return false;\n    }\n\n    ec = xsub.bind(worker);\n\n    if (ec)\n    {\n        log::error(LOG_SERVER)\n            << \"Failed to bind \" << security << \" block workers to \"\n            << worker << \" : \" << ec.message();\n        return false;\n    }\n\n    log::info(LOG_SERVER)\n        << \"Bound \" << security << \" block service to \" << service;\n    return true;\n}\n\nbool block_service::unbind(zmq::socket &xpub, zmq::socket &xsub)\n{\n    // Stop both even if one fails.\n    const auto service_stop = xpub.stop();\n    const auto worker_stop = xsub.stop();\n    const auto security = secure_ ? \"secure\" : \"public\";\n\n    if (!service_stop)\n        log::error(LOG_SERVER)\n            << \"Failed to unbind \" << security << \" block service.\";\n\n    if (!worker_stop)\n        log::error(LOG_SERVER)\n            << \"Failed to unbind \" << security << \" block workers.\";\n\n    // Don't log stop success.\n    return service_stop && worker_stop;\n}\n\n// Publish (integral worker).\n// ----------------------------------------------------------------------------\n\nbool block_service::handle_reorganization(const code &ec, uint64_t fork_point,\n                                          const block_list &new_blocks, const block_list &)\n{\n    if (stopped() || ec == (code)error::service_stopped)\n        return false;\n\n    if (ec == error::mock)\n        return true;\n\n    if (ec)\n    {\n        log::warning(LOG_SERVER)\n            << \"Failure handling new block: \" << ec.message();\n\n        // Don't let a failure here prevent prevent future notifications.\n        return true;\n    }\n\n    // Blockchain height is 64 bit but obelisk protocol is 32 bit.\n    BITCOIN_ASSERT(fork_point <= max_uint32);\n    const auto fork_point32 = static_cast<uint32_t>(fork_point);\n\n    publish_blocks(fork_point32, new_blocks);\n    return true;\n}\n\nvoid block_service::publish_blocks(uint32_t fork_point,\n                                   const block_list &blocks)\n{\n    if (stopped())\n        return;\n\n    const auto security = secure_ ? \"secure\" : \"public\";\n    const auto &endpoint = secure_ ? block_service::secure_worker : block_service::public_worker;\n\n    // Subscriptions are off the pub-sub thread so this must connect back.\n    // This could be optimized by caching the socket as thread static.\n    zmq::socket publisher(authenticator_, zmq::socket::role::publisher);\n    const auto ec = publisher.connect(endpoint);\n\n    if (ec == (code)error::service_stopped)\n        return;\n\n    if (ec)\n    {\n        log::warning(LOG_SERVER)\n            << \"Failed to connect \" << security << \" block worker: \"\n            << ec.message();\n        return;\n    }\n\n    BITCOIN_ASSERT(blocks.size() <= max_uint32);\n    BITCOIN_ASSERT(fork_point < max_uint32 - blocks.size());\n    auto height = fork_point;\n\n    for (const auto block : blocks)\n        publish_block(publisher, height++, block);\n}\n\n// [ height:4 ]\n// [ header:80 ]\n// [ txs... ]\n// The payload for block publication is delimited within the zeromq message.\n// This is required for compatability and inconsistent with query payloads.\nvoid block_service::publish_block(zmq::socket &publisher, uint32_t height,\n                                  const block_ptr block)\n{\n    if (stopped())\n        return;\n\n    const auto security = secure_ ? \"secure\" : \"public\";\n\n    zmq::message broadcast;\n    broadcast.enqueue_little_endian(height);\n    broadcast.enqueue(block->to_data(false));\n    const auto ec = publisher.send(broadcast);\n\n    if (ec == (code)error::service_stopped)\n        return;\n\n    if (ec)\n    {\n        log::warning(LOG_SERVER)\n            << \"Failed to publish \" << security << \" bloc [\"\n            << encode_hash(block->header.hash()) << \"] \" << ec.message();\n        return;\n    }\n\n    // This isn't actually a request, should probably update settings.\n    log::debug(LOG_SERVER)\n        << \"Published \" << security << \" block [\"\n        << encode_hash(block->header.hash()) << \"]\";\n}\n\n} // namespace server\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainApp/ucd/server/services/heartbeat_service.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainApp/ucd/services/heartbeat_service.hpp>\n\n#include <algorithm>\n#include <cstdint>\n#include <UChain/protocol.hpp>\n#include <UChainApp/ucd/server_node.hpp>\n#include <UChainApp/ucd/settings.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nstatic const auto domain = \"heartbeat\";\n\nusing namespace bc::config;\nusing namespace bc::protocol;\n\nstatic uint32_t to_milliseconds(uint16_t seconds)\n{\n    const auto milliseconds = static_cast<uint32_t>(seconds) * 1000;\n    return std::min(milliseconds, max_uint32);\n};\n\n// Heartbeat is capped at ~ 25 days by signed/millsecond conversions.\nheartbeat_service::heartbeat_service(zmq::authenticator &authenticator,\n                                     server_node &node, bool secure)\n    : worker(node.thread_pool()),\n      settings_(node.server_settings()),\n      period_(to_milliseconds(settings_.heartbeat_interval_seconds)),\n      authenticator_(authenticator),\n      secure_(secure)\n{\n}\n\n// Implement service as a publisher.\n// The publisher does not block if there are no subscribers or at high water.\nvoid heartbeat_service::work()\n{\n    zmq::socket publisher(authenticator_, zmq::socket::role::publisher);\n\n    // Bind socket to the worker endpoint.\n    if (!started(bind(publisher)))\n        return;\n\n    zmq::poller poller;\n    poller.add(publisher);\n\n    // Pick a random counter start, will wrap around at overflow.\n    auto count = static_cast<uint32_t>(pseudo_random());\n\n    // We will not receive on the poller, we use its timer and context stop.\n    while (!poller.terminated() && !stopped())\n    {\n        poller.wait(period_);\n        publish(count++, publisher);\n    }\n\n    // Unbind the socket and exit this thread.\n    finished(unbind(publisher));\n}\n\n// Bind/Unbind.\n//-----------------------------------------------------------------------------\n\nbool heartbeat_service::bind(zmq::socket &publisher)\n{\n    const auto security = secure_ ? \"secure\" : \"public\";\n    const auto &endpoint = secure_ ? settings_.secure_heartbeat_endpoint : settings_.public_heartbeat_endpoint;\n\n    if (!authenticator_.apply(publisher, domain, secure_))\n        return false;\n\n    const auto ec = publisher.bind(endpoint);\n\n    if (ec)\n    {\n        log::error(LOG_SERVER)\n            << \"Failed to bind \" << security << \" heartbeat service to \"\n            << endpoint << \" : \" << ec.message();\n        return false;\n    }\n\n    log::info(LOG_SERVER)\n        << \"Bound \" << security << \" heartbeat service to \" << endpoint;\n    return true;\n}\n\nbool heartbeat_service::unbind(zmq::socket &publisher)\n{\n    const auto security = secure_ ? \"secure\" : \"public\";\n\n    // Don't log stop success.\n    if (publisher.stop())\n        return true;\n\n    log::error(LOG_SERVER)\n        << \"Failed to disconnect \" << security << \" heartbeat worker.\";\n    return false;\n}\n\n// Publish Execution (integral worker).\n//-----------------------------------------------------------------------------\n\nvoid heartbeat_service::publish(uint32_t count, zmq::socket &publisher)\n{\n    if (stopped())\n        return;\n\n    const auto security = secure_ ? \"secure\" : \"public\";\n\n    zmq::message message;\n    message.enqueue_little_endian(count);\n    auto ec = publisher.send(message);\n\n    if (ec == (code)error::service_stopped)\n        return;\n\n    if (ec)\n    {\n        log::warning(LOG_SERVER)\n            << \"Failed to publish \" << security << \" heartbeat: \"\n            << ec.message();\n        return;\n    }\n\n    // This isn't actually a request, should probably update settings.\n    log::debug(LOG_SERVER)\n        << \"Published \" << security << \" heartbeat [\" << count << \"].\";\n}\n\n} // namespace server\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainApp/ucd/server/services/query_service.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainApp/ucd/services/query_service.hpp>\n\n#include <UChain/protocol.hpp>\n#include <UChainApp/ucd/server_node.hpp>\n#include <UChainApp/ucd/settings.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nusing namespace bc::config;\nusing namespace bc::protocol;\n\nstatic const auto domain = \"query\";\nconst config::endpoint query_service::public_query(\"inproc://public_query\");\nconst config::endpoint query_service::secure_query(\"inproc://secure_query\");\nconst config::endpoint query_service::public_notify(\"inproc://public_notify\");\nconst config::endpoint query_service::secure_notify(\"inproc://secure_notify\");\n\nquery_service::query_service(zmq::authenticator &authenticator,\n                             server_node &node, bool secure)\n    : worker(node.thread_pool()),\n      secure_(secure),\n      settings_(node.server_settings()),\n      authenticator_(authenticator)\n{\n}\n\n// Implement worker as a broker.\n// The dealer blocks until there are available workers.\n// The router drops messages for lost peers (clients) and high water.\nvoid query_service::work()\n{\n    zmq::socket router(authenticator_, zmq::socket::role::router);\n    zmq::socket query_dealer(authenticator_, zmq::socket::role::dealer);\n    zmq::socket notify_dealer(authenticator_, zmq::socket::role::dealer);\n\n    // Bind sockets to the service and worker endpoints.\n    if (!started(bind(router, query_dealer, notify_dealer)))\n        return;\n\n    zmq::poller poller;\n    poller.add(router);\n    poller.add(query_dealer);\n    poller.add(notify_dealer);\n\n    while (!poller.terminated() && !stopped())\n    {\n        const auto signaled = poller.wait();\n\n        if (signaled.contains(router.id()) &&\n            !forward(router, query_dealer))\n        {\n            log::warning(LOG_SERVER)\n                << \"Failed to forward from router to query_dealer.\";\n        }\n\n        if (signaled.contains(query_dealer.id()) &&\n            !forward(query_dealer, router))\n        {\n            log::warning(LOG_SERVER)\n                << \"Failed to forward from query_dealer to router.\";\n        }\n\n        if (signaled.contains(notify_dealer.id()) &&\n            !forward(notify_dealer, router))\n        {\n            log::warning(LOG_SERVER)\n                << \"Failed to forward from notify_dealer to router.\";\n        }\n    }\n\n    // Unbind the sockets and exit this thread.\n    finished(unbind(router, query_dealer, notify_dealer));\n}\n\n// Bind/Unbind.\n//-----------------------------------------------------------------------------\n\nbool query_service::bind(zmq::socket &router, zmq::socket &query_dealer,\n                         zmq::socket &notify_dealer)\n{\n    const auto security = secure_ ? \"secure\" : \"public\";\n    const auto &query_worker = secure_ ? secure_query : public_query;\n    const auto &notify_worker = secure_ ? secure_notify : public_notify;\n    const auto &query_service = secure_ ? settings_.secure_query_endpoint : settings_.public_query_endpoint;\n\n    if (!authenticator_.apply(router, domain, secure_))\n        return false;\n\n    auto ec = router.bind(query_service);\n\n    if (ec)\n    {\n        log::error(LOG_SERVER)\n            << \"Failed to bind \" << security << \" query service to \"\n            << query_service << \" : \" << ec.message();\n        return false;\n    }\n\n    ec = query_dealer.bind(query_worker);\n\n    if (ec)\n    {\n        log::error(LOG_SERVER)\n            << \"Failed to bind \" << security << \" query workers to \"\n            << query_worker << \" : \" << ec.message();\n        return false;\n    }\n\n    ec = notify_dealer.bind(notify_worker);\n\n    if (ec)\n    {\n        log::error(LOG_SERVER)\n            << \"Failed to bind \" << security << \" notify workers to \"\n            << notify_worker << \" : \" << ec.message();\n        return false;\n    }\n\n    log::info(LOG_SERVER)\n        << \"Bound \" << security << \" query service to \" << query_service;\n    return true;\n}\n\nbool query_service::unbind(zmq::socket &router, zmq::socket &query_dealer,\n                           zmq::socket &notify_dealer)\n{\n    // Stop all even if one fails.\n    const auto service_stop = router.stop();\n    const auto query_stop = query_dealer.stop();\n    const auto notify_stop = notify_dealer.stop();\n    const auto security = secure_ ? \"secure\" : \"public\";\n\n    if (!service_stop)\n        log::error(LOG_SERVER)\n            << \"Failed to unbind \" << security << \" query service.\";\n\n    if (!query_stop)\n        log::error(LOG_SERVER)\n            << \"Failed to unbind \" << security << \" query workers.\";\n\n    if (!notify_stop)\n        log::error(LOG_SERVER)\n            << \"Failed to unbind \" << security << \" notify workers.\";\n\n    // Don't log stop success.\n    return service_stop && query_stop && notify_stop;\n}\n\n} // namespace server\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainApp/ucd/server/services/tx_service.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainApp/ucd/services/tx_service.hpp>\n\n#include <functional>\n#include <memory>\n#include <UChain/protocol.hpp>\n#include <UChainApp/ucd/config.hpp>\n#include <UChainApp/ucd/server_node.hpp>\n#include <UChainApp/ucd/settings.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nusing namespace std::placeholders;\nusing namespace bc::chain;\nusing namespace bc::message;\nusing namespace bc::protocol;\n\nstatic const auto domain = \"transaction\";\nconst config::endpoint tx_service::public_worker(\"inproc://public_tx\");\nconst config::endpoint tx_service::secure_worker(\"inproc://secure_tx\");\n\ntx_service::tx_service(zmq::authenticator &authenticator,\n                                         server_node &node, bool secure)\n    : worker(node.thread_pool()),\n      secure_(secure),\n      settings_(node.server_settings()),\n      authenticator_(authenticator),\n      node_(node)\n{\n}\n\n// There is no unsubscribe so this class shouldn't be restarted.\nbool tx_service::start()\n{\n    // Subscribe to transaction pool acceptances.\n    node_.subscribe_tx_pool(\n        std::bind(&tx_service::handle_transaction,\n                  this, _1, _2, _3));\n\n    return zmq::worker::start();\n}\n\n// No unsubscribe so must be kept in scope until subscriber stop complete.\nbool tx_service::stop()\n{\n    return zmq::worker::stop();\n}\n\n// Implement worker as extended pub-sub.\n// The publisher drops messages for lost peers (clients) and high water.\nvoid tx_service::work()\n{\n    zmq::socket xpub(authenticator_, zmq::socket::role::extended_publisher);\n    zmq::socket xsub(authenticator_, zmq::socket::role::extended_subscriber);\n\n    // Bind sockets to the service and worker endpoints.\n    if (!started(bind(xpub, xsub)))\n        return;\n\n    // TODO: tap in to failure conditions, such as high water.\n    // Relay messages between subscriber and publisher (blocks on context).\n    relay(xpub, xsub);\n\n    // Unbind the sockets and exit this thread.\n    finished(unbind(xpub, xsub));\n}\n\n// Bind/Unbind.\n//-----------------------------------------------------------------------------\n\nbool tx_service::bind(zmq::socket &xpub, zmq::socket &xsub)\n{\n    const auto security = secure_ ? \"secure\" : \"public\";\n    const auto &worker = secure_ ? secure_worker : public_worker;\n    const auto &service = secure_ ? settings_.secure_transaction_endpoint : settings_.public_transaction_endpoint;\n\n    if (!authenticator_.apply(xpub, domain, secure_))\n        return false;\n\n    auto ec = xpub.bind(service);\n\n    if (ec)\n    {\n        log::error(LOG_SERVER)\n            << \"Failed to bind \" << security << \" transaction service to \"\n            << service << \" : \" << ec.message();\n        return false;\n    }\n\n    ec = xsub.bind(worker);\n\n    if (ec)\n    {\n        log::error(LOG_SERVER)\n            << \"Failed to bind \" << security << \" transaction workers to \"\n            << worker << \" : \" << ec.message();\n        return false;\n    }\n\n    log::info(LOG_SERVER)\n        << \"Bound \" << security << \" transaction service to \" << service;\n    return true;\n}\n\nbool tx_service::unbind(zmq::socket &xpub, zmq::socket &xsub)\n{\n    // Stop both even if one fails.\n    const auto service_stop = xpub.stop();\n    const auto worker_stop = xsub.stop();\n    const auto security = secure_ ? \"secure\" : \"public\";\n\n    if (!service_stop)\n        log::error(LOG_SERVER)\n            << \"Failed to unbind \" << security << \" transaction service.\";\n\n    if (!worker_stop)\n        log::error(LOG_SERVER)\n            << \"Failed to unbind \" << security << \" transaction workers.\";\n\n    // Don't log stop success.\n    return service_stop && worker_stop;\n}\n\n// Publish (integral worker).\n// ----------------------------------------------------------------------------\n\nbool tx_service::handle_transaction(const code &ec, const index_list &,\n                                             tx_message::ptr tx)\n{\n    if (stopped() || ec == (code)error::service_stopped)\n        return false;\n\n    if (ec == (code)error::mock)\n    {\n        return true;\n    }\n\n    if (ec)\n    {\n        log::warning(LOG_SERVER)\n            << \"Failure handling new transaction: \" << ec.message();\n\n        // Don't let a failure here prevent prevent future notifications.\n        return true;\n    }\n\n    publish_transaction(*tx);\n    return true;\n}\n\n// [ tx... ]\nvoid tx_service::publish_transaction(const transaction &tx)\n{\n    if (stopped())\n        return;\n\n    const auto security = secure_ ? \"secure\" : \"public\";\n    const auto &endpoint = secure_ ? tx_service::secure_worker : tx_service::public_worker;\n\n    // Subscriptions are off the pub-sub thread so this must connect back.\n    // This could be optimized by caching the socket as thread static.\n    zmq::socket publisher(authenticator_, zmq::socket::role::publisher);\n    auto ec = publisher.connect(endpoint);\n\n    if (ec == (code)error::service_stopped)\n        return;\n\n    if (ec)\n    {\n        log::warning(LOG_SERVER)\n            << \"Failed to connect \" << security << \" transaction worker: \"\n            << ec.message();\n        return;\n    }\n\n    if (stopped())\n        return;\n\n    zmq::message broadcast;\n    bc::message::tx_message tx_msg(tx);\n    broadcast.enqueue(tx_msg.to_data(bc::message::version::level::maximum));\n    ec = publisher.send(broadcast);\n\n    if (ec == (code)error::service_stopped)\n        return;\n\n    if (ec)\n    {\n        log::warning(LOG_SERVER)\n            << \"Failed to publish \" << security << \" transaction [\"\n            << encode_hash(tx_msg.hash()) << \"] \" << ec.message();\n        return;\n    }\n\n    // This isn't actually a request, should probably update settings.\n    log::debug(LOG_SERVER)\n        << \"Published \" << security << \" transaction [\"\n        << encode_hash(tx_msg.hash()) << \"]\";\n}\n\n} // namespace server\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainApp/ucd/server/settings.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainApp/ucd/settings.hpp>\n\n#include <UChain/node.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nusing namespace asio;\n\nsettings::settings()\n    : query_workers(1),\n      heartbeat_interval_seconds(5),\n      subscription_expiration_minutes(10),\n      subscription_limit(100000000),\n      mongoose_listen(\"127.0.0.1:8707\"),\n      websocket_listen(\"127.0.0.1:28707\"),\n      administrator_required(false),\n      log_level(\"DEBUG\"),\n      secure_only(false),\n      read_only(false),\n      query_service_enabled(true),\n      heartbeat_service_enabled(false),\n      block_service_enabled(false),\n      tx_service_enabled(false),\n      websocket_service_enabled(true),\n      public_query_endpoint(\"tcp://*:18707\"),\n      public_heartbeat_endpoint(\"tcp://*:9092\"),\n      public_block_endpoint(\"tcp://*:9093\"),\n      public_transaction_endpoint(\"tcp://*:9094\"),\n      secure_query_endpoint(\"tcp://*:9081\"),\n      secure_heartbeat_endpoint(\"tcp://*:9082\"),\n      secure_block_endpoint(\"tcp://*:9083\"),\n      secure_transaction_endpoint(\"tcp://*:9084\")\n{\n}\n\n// There are no current distinctions spanning chain contexts.\nsettings::settings(bc::settings context)\n    : settings()\n{\n}\n\nduration settings::heartbeat_interval() const\n{\n  return seconds(heartbeat_interval_seconds);\n}\n\nduration settings::subscription_expiration() const\n{\n  return minutes(subscription_expiration_minutes);\n}\n\n} // namespace server\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainApp/ucd/server/utility/authenticator.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainApp/ucd/utility/authenticator.hpp>\n\n#include <string>\n#include <UChain/protocol.hpp>\n#include <UChainApp/ucd/config.hpp>\n#include <UChainApp/ucd/server_node.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nusing namespace bc::protocol;\n\nauthenticator::authenticator(server_node &node)\n    : zmq::authenticator(node.thread_pool())\n{\n    const auto &settings = node.server_settings();\n\n    set_private_key(settings.server_private_key);\n\n    for (const auto &address : settings.client_addresses)\n    {\n        log::debug(LOG_SERVER)\n            << \"Allow client address [\" << address\n            << (address.port() == 0 ? \":*\" : \"\") << \"]\";\n\n        allow(address);\n    }\n\n    for (const auto &public_key : settings.client_public_keys)\n    {\n        log::debug(LOG_SERVER)\n            << \"Allow client public key [\" << public_key << \"]\";\n\n        allow(public_key);\n    }\n}\n\nbool authenticator::apply(zmq::socket &socket, const std::string &domain,\n                          bool secure)\n{\n    // This will fail if there are client keys but no server key.\n    if (!zmq::authenticator::apply(socket, domain, secure))\n    {\n        log::error(LOG_SERVER)\n            << \"Failed to apply authentication to socket [\" << domain << \"]\";\n        return false;\n    }\n\n    if (secure)\n    {\n        log::debug(LOG_SERVER)\n            << \"Applied curve authentication to socket [\" << domain << \"]\";\n    }\n    else\n    {\n        log::debug(LOG_SERVER)\n            << \"Applied address authentication to socket [\" << domain << \"]\";\n    }\n\n    return true;\n}\n\n} // namespace server\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainApp/ucd/server/utility/fetch_helpers.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainApp/ucd/utility/fetch_helpers.hpp>\n\n#include <cstdint>\n#include <cstddef>\n#include <UChain/blockchain.hpp>\n#include <UChainApp/ucd/config.hpp>\n#include <UChainApp/ucd/messages/message.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nusing namespace bc::blockchain;\nusing namespace bc::chain;\nusing namespace bc::message;\nusing namespace bc::wallet;\n\n// fetch_history stuff\n// ----------------------------------------------------------------------------\n\nbool unwrap_fetch_history_args(payment_address &address,\n                               uint32_t &from_height, const message &request)\n{\n    static constexpr size_t history_args_size = sizeof(uint8_t) +\n                                                short_hash_size + sizeof(uint32_t);\n\n    const auto &data = request.data();\n\n    if (data.size() != history_args_size)\n    {\n        log::error(LOG_SERVER)\n            << \"Incorrect data size for .fetch_history\";\n        return false;\n    }\n\n    auto deserial = make_deserializer(data.begin(), data.end());\n    const auto version_byte = deserial.read_byte();\n    const auto hash = deserial.read_short_hash();\n    from_height = deserial.read_4_bytes_little_endian();\n    BITCOIN_ASSERT(deserial.iterator() == data.end());\n\n    address = payment_address(hash, version_byte);\n    return true;\n}\n\nvoid send_history_result(const code &ec, const history_compact::list &history,\n                         const message &request, send_handler handler)\n{\n    static constexpr size_t row_size = sizeof(uint8_t) + point_size +\n                                       sizeof(uint32_t) + sizeof(uint64_t);\n\n    data_chunk result(code_size + row_size * history.size());\n    auto serial = make_serializer(result.begin());\n    serial.write_error_code(ec);\n    BITCOIN_ASSERT(serial.iterator() == result.begin() + code_size);\n\n    for (const auto &row : history)\n    {\n        BITCOIN_ASSERT(row.height <= max_uint32);\n        serial.write_byte(static_cast<uint8_t>(row.kind));\n        serial.write_data(row.point.to_data());\n        serial.write_4_bytes_little_endian(static_cast<uint32_t>(row.height));\n        serial.write_8_bytes_little_endian(row.value);\n    }\n\n    BITCOIN_ASSERT(serial.iterator() == result.end());\n\n    handler(message(request, result));\n}\n\n// fetch_transaction stuff\n// ----------------------------------------------------------------------------\n\nbool unwrap_fetch_transaction_args(hash_digest &hash,\n                                   const message &request)\n{\n    const auto &data = request.data();\n\n    if (data.size() != hash_size)\n    {\n        log::error(LOG_SERVER)\n            << \"Invalid hash length in fetch_transaction request.\";\n        return false;\n    }\n\n    auto deserial = make_deserializer(data.begin(), data.end());\n    hash = deserial.read_hash();\n    return true;\n}\n\nvoid chain_transaction_fetched(const code &ec, const chain::transaction &tx,\n                               const message &request, send_handler handler)\n{\n    // wdy add for tx is null reference\n    if ((code)error::not_found == ec)\n    {\n        handler(message(request, error::not_found));\n        return;\n    }\n\n    const auto result = build_chunk(\n        {message::to_bytes(ec),\n         tx.to_data()});\n\n    handler(message(request, result));\n}\n\nvoid pool_transaction_fetched(const code &ec, tx_message::ptr tx,\n                              const message &request, send_handler handler)\n{\n    chain_transaction_fetched(ec, *tx, request, handler);\n}\n\n} // namespace server\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainApp/ucd/server/workers/notification_worker.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainApp/ucd/workers/notification_worker.hpp>\n\n#include <algorithm>\n#include <cstdint>\n#include <functional>\n#include <memory>\n#include <string>\n#include <UChain/protocol.hpp>\n#include <UChainApp/ucd/messages/message.hpp>\n#include <UChainApp/ucd/messages/route.hpp>\n#include <UChainApp/ucd/server_node.hpp>\n#include <UChainApp/ucd/services/query_service.hpp>\n#include <UChainApp/ucd/settings.hpp>\n#include <UChainApp/ucd/utility/fetch_helpers.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\n#define NAME \"notification_worker\"\n\nusing namespace std::placeholders;\nusing namespace bc::chain;\nusing namespace bc::protocol;\nusing namespace bc::wallet;\n\n// Purge subscriptions at 10% of the expiration period.\nstatic constexpr int64_t purge_interval_ratio = 10;\n\n// Notifications respond with commands that are distinct from the subscription.\nstatic const std::string address_update(\"address.update\");\nstatic const std::string address_stealth(\"address.stealth_update\");\nstatic const std::string address_update2(\"address.update2\");\nstatic const std::string penetration_update(\"penetration.update\");\n\nnotification_worker::notification_worker(zmq::authenticator &authenticator,\n                                         server_node &node, bool secure)\n    : worker(node.thread_pool()),\n      secure_(secure),\n      settings_(node.server_settings()),\n      node_(node),\n      authenticator_(authenticator),\n      payment_subscriber_(std::make_shared<payment_subscriber>(\n          node.thread_pool(), settings_.subscription_limit, NAME \"_payment\")),\n      stealth_subscriber_(std::make_shared<stealth_subscriber>(\n          node.thread_pool(), settings_.subscription_limit, NAME \"_stealth\")),\n      address_subscriber_(std::make_shared<address_subscriber>(\n          node.thread_pool(), settings_.subscription_limit, NAME \"_address\")),\n      penetration_subscriber_(std::make_shared<penetration_subscriber>(\n          node.thread_pool(), settings_.subscription_limit, NAME \"_penetration\"))\n{\n}\n\n// There is no unsubscribe so this class shouldn't be restarted.\nbool notification_worker::start()\n{\n    // v2/v3 (deprecated)\n    payment_subscriber_->start();\n    stealth_subscriber_->start();\n\n    // v3\n    address_subscriber_->start();\n    penetration_subscriber_->start();\n\n    if (settings_.block_service_enabled)\n    {\n        // Subscribe to blockchain reorganizations.\n        node_.subscribe_blockchain(\n            std::bind(&notification_worker::handle_blockchain_reorganization,\n                      this, _1, _2, _3, _4));\n    }\n\n    // Subscribe to transaction pool acceptances.\n    node_.subscribe_tx_pool(\n        std::bind(&notification_worker::handle_tx_pool,\n                  this, _1, _2, _3));\n\n    // Subscribe to all inventory messages from all peers.\n    node_.subscribe<bc::message::inventory>(\n        std::bind(&notification_worker::handle_inventory,\n                  this, _1, _2));\n\n    return zmq::worker::start();\n}\n\n// No unsubscribe so must be kept in scope until subscriber stop complete.\nbool notification_worker::stop()\n{\n    static const auto code = error::channel_stopped;\n\n    // v2/v3 (deprecated)\n    payment_subscriber_->stop();\n    payment_subscriber_->invoke(code, {}, 0, {}, {});\n\n    stealth_subscriber_->stop();\n    stealth_subscriber_->invoke(code, 0, 0, {}, {});\n\n    // v3\n    address_subscriber_->stop();\n    address_subscriber_->invoke(code, {}, 0, {}, {});\n\n    penetration_subscriber_->stop();\n    penetration_subscriber_->invoke(code, 0, {}, {});\n\n    return zmq::worker::stop();\n}\n\n// Implement worker as a router to the query service.\n// The notification worker receives no messages from the query service.\nvoid notification_worker::work()\n{\n    zmq::socket router(authenticator_, zmq::socket::role::router);\n\n    // Connect socket to the service endpoint.\n    if (!started(connect(router)))\n        return;\n\n    zmq::poller poller;\n    poller.add(router);\n    const auto interval = purge_interval_milliseconds();\n\n    // We do not send/receive on the poller, we use its timer and context stop.\n    // Other threads connect and disconnect dynamically to send updates.\n    while (!poller.terminated() && !stopped())\n    {\n        // BUGBUG: this can fail on some platforms if interval is > 1000.\n        poller.wait(interval);\n        purge();\n    }\n\n    // Disconnect the socket and exit this thread.\n    finished(disconnect(router));\n}\n\nint32_t notification_worker::purge_interval_milliseconds() const\n{\n    const int64_t minutes = settings_.subscription_expiration_minutes;\n    const int64_t milliseconds = minutes * 60 * 1000 / purge_interval_ratio;\n    const auto capped = std::max(milliseconds, static_cast<int64_t>(max_int32));\n    return static_cast<int32_t>(capped);\n}\n\n// Connect/Disconnect.\n//-----------------------------------------------------------------------------\n\nbool notification_worker::connect(socket &router)\n{\n    const auto security = secure_ ? \"secure\" : \"public\";\n    const auto &endpoint = secure_ ? query_service::secure_notify : query_service::public_notify;\n\n    const auto ec = router.connect(endpoint);\n\n    if (ec)\n    {\n        log::error(LOG_SERVER)\n            << \"Failed to connect \" << security << \" notification worker to \"\n            << endpoint << \" : \" << ec.message();\n        return false;\n    }\n\n    log::debug(LOG_SERVER)\n        << \"Connected \" << security << \" notification worker to \" << endpoint;\n    return true;\n}\n\nbool notification_worker::disconnect(socket &router)\n{\n    const auto security = secure_ ? \"secure\" : \"public\";\n\n    // Don't log stop success.\n    if (router.stop())\n        return true;\n\n    log::error(LOG_SERVER)\n        << \"Failed to disconnect \" << security << \" notification worker.\";\n    return false;\n}\n\n// Pruning.\n// ----------------------------------------------------------------------------\n\n// Signal expired subscriptions to self-remove.\nvoid notification_worker::purge()\n{\n    static const auto code = error::channel_timeout;\n\n    // v2/v3 (deprecated)\n    payment_subscriber_->purge(code, {}, 0, {}, {});\n    stealth_subscriber_->purge(code, 0, 0, {}, {});\n\n    // v3\n    address_subscriber_->purge(code, {}, 0, {}, {});\n    penetration_subscriber_->purge(code, 0, {}, {});\n}\n\n// Sending.\n// ----------------------------------------------------------------------------\n\nvoid notification_worker::send(const route &reply_to,\n                               const std::string &command, uint32_t id, const data_chunk &payload)\n{\n    const auto security = secure_ ? \"secure\" : \"public\";\n    const auto &endpoint = secure_ ? query_service::secure_notify : query_service::public_notify;\n\n    zmq::socket notifier(authenticator_, zmq::socket::role::router);\n    auto ec = notifier.connect(endpoint);\n\n    if (ec == (code)error::service_stopped)\n        return;\n\n    if (ec)\n    {\n        log::warning(LOG_SERVER)\n            << \"Failed to connect \" << security << \" notification worker: \"\n            << ec.message();\n        return;\n    }\n\n    // Notifications are formatted as query response messages.\n    message notification(reply_to, command, id, payload);\n    ec = notification.send(notifier);\n\n    if (ec && ec != (code)error::service_stopped)\n        log::warning(LOG_SERVER)\n            << \"Failed to send notification to \"\n            << notification.route().display() << \" \" << ec.message();\n}\n\nvoid notification_worker::send_payment(const route &reply_to, uint32_t id,\n                                       const bc::wallet::payment_address &address, uint32_t height,\n                                       const hash_digest &block_hash, const chain::transaction &tx)\n{\n    // [ address.version:1 ]\n    // [ address.hash:20 ]\n    // [ height:4 ]\n    // [ block_hash:32 ]\n    // [ tx:... ]\n    const auto payload = build_chunk(\n        {to_array(address.version()),\n         address.hash(),\n         to_little_endian(height),\n         block_hash,\n         tx.to_data()});\n\n    send(reply_to, address_update, id, payload);\n}\n\nvoid notification_worker::send_stealth(const route &reply_to, uint32_t id,\n                                       uint32_t prefix, uint32_t height, const hash_digest &block_hash,\n                                       const chain::transaction &tx)\n{\n    // [ prefix:4 ]\n    // [ height:4 ]\n    // [ block_hash:32 ]\n    // [ tx:... ]\n    const auto payload = build_chunk(\n        {to_little_endian(prefix),\n         to_little_endian(height),\n         block_hash,\n         tx.to_data()});\n\n    send(reply_to, address_stealth, id, payload);\n}\n\nvoid notification_worker::send_address(const route &reply_to, uint32_t id,\n                                       uint8_t sequence, uint32_t height, const hash_digest &block_hash,\n                                       const chain::transaction &tx)\n{\n    // [ code:4 ]\n    // [ sequence:1 ]\n    // [ height:4 ]\n    // [ block_hash:32 ]\n    // [ tx:... ]\n    const auto payload = build_chunk(\n        {message::to_bytes(error::success),\n         to_array(sequence),\n         to_little_endian(height),\n         block_hash,\n         tx.to_data()});\n\n    send(reply_to, address_update2, id, payload);\n}\n\n// Handlers.\n// ----------------------------------------------------------------------------\n\nbool notification_worker::handle_payment(const code &ec,\n                                         const payment_address &address, uint32_t height,\n                                         const hash_digest &block_hash, const chain::transaction &tx,\n                                         const route &reply_to, uint32_t id, const binary &prefix_filter)\n{\n    if (ec)\n    {\n        send(reply_to, address_update, id, message::to_bytes(ec));\n        return false;\n    }\n\n    if (prefix_filter.is_prefix_of(address.hash()))\n        send_payment(reply_to, id, address, height, block_hash, tx);\n\n    return true;\n}\n\nbool notification_worker::handle_stealth(const code &ec,\n                                         uint32_t prefix, uint32_t height, const hash_digest &block_hash,\n                                         const chain::transaction &tx, const route &reply_to, uint32_t id,\n                                         const binary &prefix_filter)\n{\n    if (ec)\n    {\n        send(reply_to, address_stealth, id, message::to_bytes(ec));\n        return false;\n    }\n\n    if (prefix_filter.is_prefix_of(prefix))\n        send_stealth(reply_to, id, prefix, height, block_hash, tx);\n\n    return true;\n}\n\nbool notification_worker::handle_address(const code &ec,\n                                         const binary &field, uint32_t height, const hash_digest &block_hash,\n                                         const chain::transaction &tx, const route &reply_to, uint32_t id,\n                                         const binary &prefix_filter, sequence_ptr sequence)\n{\n    if (ec)\n    {\n        send(reply_to, address_update2, id, message::to_bytes(ec));\n        return false;\n    }\n\n    if (prefix_filter.is_prefix_of(field))\n    {\n        send_address(reply_to, id, *sequence, height, block_hash, tx);\n        ++(*sequence);\n    }\n\n    return true;\n}\n\n// Subscribers.\n// ----------------------------------------------------------------------------\n\n// Subscribe to address and stealth prefix notifications.\n// Each delegate must connect to the appropriate query notification endpoint.\nvoid notification_worker::subscribe_address(const route &reply_to, uint32_t id,\n                                            const binary &prefix_filter, subscribe_type type)\n{\n    static const auto error_code = error::channel_stopped;\n    const auto &duration = settings_.subscription_expiration();\n    const address_key key(reply_to, prefix_filter);\n\n    switch (type)\n    {\n    // v2/v3 (deprecated)\n    case subscribe_type::payment:\n    {\n        // This class must be kept in scope until work is terminated.\n        const auto handler =\n            std::bind(&notification_worker::handle_payment,\n                      this, _1, _2, _3, _4, _5, reply_to, id, prefix_filter);\n\n        payment_subscriber_->subscribe(handler, key, duration, error_code,\n                                       {}, 0, {}, {});\n        break;\n    }\n\n    // v2/v3 (deprecated)\n    case subscribe_type::stealth:\n    {\n        // This class must be kept in scope until work is terminated.\n        const auto handler =\n            std::bind(&notification_worker::handle_stealth,\n                      this, _1, _2, _3, _4, _5, reply_to, id, prefix_filter);\n\n        stealth_subscriber_->subscribe(handler, key, duration, error_code,\n                                       0, 0, {}, {});\n        break;\n    }\n\n    // v3\n    case subscribe_type::unspecified:\n    {\n        // The sequence enables the client to detect dropped messages.\n        const auto sequence = std::make_shared<uint8_t>(0);\n\n        // This class must be kept in scope until work is terminated.\n        const auto handler =\n            std::bind(&notification_worker::handle_address,\n                      this, _1, _2, _3, _4, _5, reply_to, id, prefix_filter,\n                      sequence);\n\n        // v3\n        address_subscriber_->subscribe(handler, key, duration, error_code,\n                                       {}, 0, {}, {});\n        break;\n    }\n\n    // v3\n    default:\n    case subscribe_type::unsubscribe:\n    {\n        // Just as with an expiration (purge) this will cause the stored\n        // handler (notification_worker::handle_address) to be invoked but\n        // with the specified error code (error::channel_stopped) as\n        // opposed to error::channel_timeout.\n\n        // v3\n        address_subscriber_->unsubscribe(key, error_code, {}, 0, {}, {});\n        break;\n    }\n    }\n}\n\n// Subscribe to transaction penetration notifications.\n// Each delegate must connect to the appropriate query notification endpoint.\nvoid notification_worker::subscribe_penetration(const route &reply_to,\n                                                uint32_t id, const hash_digest &tx_hash)\n{\n    // TODO:\n    // Height and hash are zeroized if tx is not chained (inv/mempool).\n    // If chained or penetration is 100 (percent) drop subscription.\n    // Only send messages at configured thresholds (e.g. 20/40/60/80/100%).\n    // Thresholding allows the server to mask its peer count.\n    // Penetration is computed by the relay handler.\n    // No sequence is required because gaps are okay.\n    // [ tx_hash:32 ]\n    // [ penetration:1 ]\n    // [ height:4 ]\n    // [ block_hash:32 ]\n    ////penetration_subscriber_->subscribe();\n}\n\n// Notification (via blockchain).\n// ----------------------------------------------------------------------------\n\nbool notification_worker::handle_blockchain_reorganization(const code &ec,\n                                                           uint64_t fork_point, const block_list &new_blocks, const block_list &)\n{\n    if (stopped() || ec == (code)error::service_stopped)\n        return false;\n\n    if (ec)\n    {\n        log::warning(LOG_SERVER)\n            << \"Failure handling new block: \" << ec.message();\n\n        // Don't let a failure here prevent prevent future notifications.\n        return true;\n    }\n\n    // Blockchain height is 64 bit but obelisk protocol is 32 bit.\n    BITCOIN_ASSERT(fork_point <= max_uint32);\n    const auto fork_point32 = static_cast<uint32_t>(fork_point);\n\n    notify_blocks(fork_point32, new_blocks);\n    return true;\n}\n\nvoid notification_worker::notify_blocks(uint32_t fork_point,\n                                        const block_list &blocks)\n{\n    if (stopped())\n        return;\n\n    const auto security = secure_ ? \"secure\" : \"public\";\n    const auto &endpoint = secure_ ? block_service::secure_worker : block_service::public_worker;\n\n    // Notifications are off the pub-sub thread so this must connect back.\n    // This could be optimized by caching the socket as thread static.\n    zmq::socket publisher(authenticator_, zmq::socket::role::publisher);\n    const auto ec = publisher.connect(endpoint);\n\n    if (ec == (code)error::service_stopped)\n        return;\n\n    if (ec)\n    {\n        log::warning(LOG_SERVER)\n            << \"Failed to connect \" << security << \" block worker: \"\n            << ec.message();\n        return;\n    }\n\n    BITCOIN_ASSERT(blocks.size() <= max_uint32);\n    BITCOIN_ASSERT(fork_point < max_uint32 - blocks.size());\n    auto height = fork_point;\n\n    for (const auto block : blocks)\n        notify_block(publisher, height++, block);\n}\n\nvoid notification_worker::notify_block(zmq::socket &publisher, uint32_t height,\n                                       const block::ptr block)\n{\n    if (stopped())\n        return;\n\n    const auto block_hash = block->header.hash();\n\n    for (const auto &tx : block->transactions)\n    {\n        const auto tx_hash = tx.hash();\n\n        notify_transaction(height, block_hash, tx);\n        notify_penetration(height, block_hash, tx_hash);\n    }\n}\n\n// Notification (via transaction inventory).\n// ----------------------------------------------------------------------------\n// This relies on peers always notifying us of new txs via inv messages.\n\nbool notification_worker::handle_inventory(const code &ec,\n                                           const bc::message::inventory::ptr packet)\n{\n    if (stopped() || ec == (code)error::service_stopped)\n        return false;\n\n    if (ec)\n    {\n        log::warning(LOG_SERVER)\n            << \"Failure handling inventory: \" << ec.message();\n\n        // Don't let a failure here prevent prevent future notifications.\n        return true;\n    }\n\n    // Loop inventories and extract transaction hashes.\n    for (const auto &inventory : packet->inventories)\n        if (inventory.is_transaction_type())\n            notify_penetration(0, null_hash, inventory.hash);\n\n    return true;\n}\n\n// Notification (via mempool).\n// ----------------------------------------------------------------------------\n\nbool notification_worker::handle_tx_pool(const code &ec,\n                                                  const point::indexes &, bc::message::tx_message::ptr tx)\n{\n    if (stopped() || ec == (code)error::service_stopped)\n        return false;\n\n    if (ec == (code)error::mock)\n    {\n        return true;\n    }\n\n    if (ec)\n    {\n        log::warning(LOG_SERVER)\n            << \"Failure handling new transaction: \" << ec.message();\n\n        // Don't let a failure here prevent future notifications.\n        return true;\n    }\n\n    notify_transaction(0, null_hash, *tx);\n    return true;\n}\n\n// This parsing is duplicated by bc::database::data_base.\nvoid notification_worker::notify_transaction(uint32_t height,\n                                             const hash_digest &block_hash, const transaction &tx)\n{\n    uint32_t prefix;\n\n    // TODO: move full integer and array constructors into binary.\n    static constexpr size_t prefix_bits = sizeof(prefix) * byte_bits;\n    static constexpr size_t address_bits = short_hash_size * byte_bits;\n\n    if (stopped() || tx.outputs.empty())\n        return;\n\n    // see data_base::push_inputs\n    // Loop inputs and extract payment addresses.\n    for (const auto &input : tx.inputs)\n    {\n        const auto address = payment_address::extract(input.script);\n\n        if (address)\n        {\n            const binary field(address_bits, address.hash());\n            notify_address(field, height, block_hash, tx);\n            notify_payment(address, height, block_hash, tx);\n        }\n    }\n\n    // see data_base::push_outputs\n    // Loop outputs and extract payment addresses.\n    for (const auto &output : tx.outputs)\n    {\n        const auto address = payment_address::extract(output.script);\n\n        if (address)\n        {\n            const binary field(address_bits, address.hash());\n            notify_address(field, height, block_hash, tx);\n            notify_payment(address, height, block_hash, tx);\n        }\n    }\n\n    // see data_base::push_stealth\n    // Loop output pairs and extract stealth payments.\n    for (size_t index = 0; index < (tx.outputs.size() - 1); ++index)\n    {\n        const auto &ephemeral_script = tx.outputs[index].script;\n        const auto &payment_script = tx.outputs[index + 1].script;\n\n        // Try to extract a stealth prefix from the first output.\n        // Try to extract the payment address from the second output.\n        if (to_stealth_prefix(prefix, ephemeral_script) &&\n            payment_address::extract(payment_script))\n        {\n            const binary field(prefix_bits, to_little_endian(prefix));\n            notify_address(field, height, block_hash, tx);\n            notify_stealth(prefix, height, block_hash, tx);\n        }\n    }\n}\n\n// v2/v3 (deprecated)\nvoid notification_worker::notify_payment(const payment_address &address,\n                                         uint32_t height, const hash_digest &block_hash, const transaction &tx)\n{\n    static const auto code = error::success;\n    payment_subscriber_->relay(code, address, height, block_hash, tx);\n}\n\n// v2/v3 (deprecated)\nvoid notification_worker::notify_stealth(uint32_t prefix, uint32_t height,\n                                         const hash_digest &block_hash, const transaction &tx)\n{\n    static const auto code = error::success;\n    stealth_subscriber_->relay(code, prefix, height, block_hash, tx);\n}\n\n// v3\nvoid notification_worker::notify_address(const binary &field, uint32_t height,\n                                         const hash_digest &block_hash, const transaction &tx)\n{\n    static const auto code = error::success;\n    address_subscriber_->relay(code, field, height, block_hash, tx);\n}\n\n// v3.x\nvoid notification_worker::notify_penetration(uint32_t height,\n                                             const hash_digest &block_hash, const hash_digest &tx_hash)\n{\n    static const auto code = error::success;\n    penetration_subscriber_->relay(code, height, block_hash, tx_hash);\n}\n\n} // namespace server\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainApp/ucd/server/workers/query_worker.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainApp/ucd/workers/query_worker.hpp>\n\n#include <functional>\n#include <string>\n#include <UChain/protocol.hpp>\n#include <UChainApp/ucd/define.hpp>\n#include <UChainApp/ucd/interface/address.hpp>\n#include <UChainApp/ucd/interface/blockchain.hpp>\n#include <UChainApp/ucd/interface/protocol.hpp>\n#include <UChainApp/ucd/interface/tx_pool.hpp>\n#include <UChainApp/ucd/messages/message.hpp>\n#include <UChainApp/ucd/server_node.hpp>\n\nnamespace libbitcoin\n{\nnamespace server\n{\n\nusing namespace std::placeholders;\nusing namespace bc::protocol;\n\nquery_worker::query_worker(zmq::authenticator &authenticator,\n                           server_node &node, bool secure)\n    : worker(node.thread_pool()),\n      secure_(secure),\n      settings_(node.server_settings()),\n      node_(node),\n      authenticator_(authenticator)\n{\n    // The same interface is attached to the secure and public interfaces.\n    attach_interface();\n}\n\n// Implement worker as a router to the query service.\n// v2 libbitcoin-client DEALER does not add delimiter frame.\n// The router drops messages for lost peers (query service) and high water.\nvoid query_worker::work()\n{\n    zmq::socket router(authenticator_, zmq::socket::role::router);\n\n    // Connect socket to the service endpoint.\n    if (!started(connect(router)))\n        return;\n\n    zmq::poller poller;\n    poller.add(router);\n\n    while (!poller.terminated() && !stopped())\n    {\n        if (poller.wait().contains(router.id()))\n            query(router);\n    }\n\n    // Disconnect the socket and exit this thread.\n    finished(disconnect(router));\n}\n\n// Connect/Disconnect.\n//-----------------------------------------------------------------------------\n\nbool query_worker::connect(zmq::socket &router)\n{\n    const auto security = secure_ ? \"secure\" : \"public\";\n    const auto &endpoint = secure_ ? query_service::secure_query : query_service::public_query;\n\n    const auto ec = router.connect(endpoint);\n\n    if (ec)\n    {\n        log::error(LOG_SERVER)\n            << \"Failed to connect \" << security << \" query worker to \"\n            << endpoint << \" : \" << ec.message();\n        return false;\n    }\n\n    log::debug(LOG_SERVER)\n        << \"Connected \" << security << \" query worker to \" << endpoint;\n    return true;\n}\n\nbool query_worker::disconnect(zmq::socket &router)\n{\n    const auto security = secure_ ? \"secure\" : \"public\";\n\n    // Don't log stop success.\n    if (router.stop())\n        return true;\n\n    log::error(LOG_SERVER)\n        << \"Failed to disconnect \" << security << \" query worker.\";\n    return false;\n}\n\n// Query Execution.\n//-----------------------------------------------------------------------------\n\n// Because the socket is a router we may simply drop invalid queries.\n// As a single thread worker this router should not reach high water.\n// If we implemented as a replier we would need to always provide a response.\nvoid query_worker::query(zmq::socket &router)\n{\n    if (stopped())\n        return;\n\n    // TODO: rewrite the serial blockchain interface to avoid callbacks.\n    // We are using a closure vs. bind to take advantage of move arg syntax.\n    const auto sender = [&router](message &&response) {\n        const auto ec = response.send(router);\n\n        if (ec && ec != (code)error::service_stopped)\n            log::warning(LOG_SERVER)\n                << \"Failed to send query response to \"\n                << response.route().display() << \" \" << ec.message();\n    };\n\n    message request(secure_);\n    const auto ec = request.receive(router);\n\n    if (ec == (code)error::service_stopped)\n        return;\n\n    if (ec)\n    {\n        log::debug(LOG_SERVER)\n            << \"Failed to receive query from \" << request.route().display()\n            << \" \" << ec.message();\n\n        // Because the query uid not parse this is likely to be misaddressed.\n        sender(message(request, ec));\n        return;\n    }\n\n    // Locate the request handler for this command.\n    const auto handler = command_handlers_.find(request.command());\n\n    if (handler == command_handlers_.end())\n    {\n        log::debug(LOG_SERVER)\n            << \"Invalid query command from \" << request.route().display();\n\n        sender(message(request, error::not_found));\n        return;\n    }\n\n    log::debug(LOG_SERVER)\n        << \"Query \" << request.command() << \" from \"\n        << request.route().display();\n\n    // The query executor is the delegate bound by the attach method.\n    const auto &query_execute = handler->second;\n\n    // Execute the request and forward result to queue.\n    // Example: address.renew(node_, request, sender);\n    // Example: blockchain.fetch_history(node_, request, sender);\n    query_execute(request, sender);\n}\n\n// Query Interface.\n// ----------------------------------------------------------------------------\n\n// Class and method names must match protocol expectations (do not change).\n#define ATTACH(class_name, method_name, node)              \\\n    attach(#class_name \".\" #method_name,                   \\\n           std::bind(&bc::server::class_name::method_name, \\\n                     std::ref(node), _1, _2));\n\nvoid query_worker::attach(const std::string &command,\n                          command_handler handler)\n{\n    command_handlers_[command] = handler;\n}\n\n//=============================================================================\n// TODO: add to client:\n// blockchain.fetch_spend\n// blockchain.fetch_block_transaction_hashes\n//=============================================================================\n// address.fetch_history was present in v1 (obelisk) and v2 (server).\n// address.fetch_history was called by client v1 (sx) and v2 (bx).\n//-----------------------------------------------------------------------------\n// address.renew is deprecated in v3.\n// address.subscribe is deprecated in v3.\n// address.subscribe2 is new in v3, also call for renew.\n// address.unsubscribe2 is new in v3 (there was never an address.unsubscribe).\n//-----------------------------------------------------------------------------\n///protocol.fetch_stealth is deprecated in v3.\n// protocol.fetch_stealth2 is new in v3.\n//-----------------------------------------------------------------------------\n// blockchain.broadcast_transaction is deprecated in v3 (deferred).\n// tx_pool.broadcast (with radar) is new in v3 (deferred).\n//=============================================================================\n// Interface class.method names must match protocol (do not change).\nvoid query_worker::attach_interface()\n{\n    ATTACH(address, renew, node_);\n    ATTACH(address, subscribe, node_);\n    ATTACH(address, subscribe2, node_);\n    ATTACH(address, unsubscribe2, node_);\n    ATTACH(address, fetch_history2, node_);\n    ATTACH(blockchain, fetch_history, node_);\n    ATTACH(blockchain, fetch_block_header, node_);\n    ATTACH(blockchain, fetch_block_height, node_);\n    ATTACH(blockchain, fetch_block_transaction_hashes, node_);\n    ATTACH(blockchain, fetch_last_height, node_);\n    ATTACH(blockchain, fetch_transaction, node_);\n    ATTACH(blockchain, fetch_transaction_index, node_);\n    ATTACH(blockchain, fetch_spend, node_);\n    ATTACH(blockchain, fetch_stealth, node_);\n    ATTACH(blockchain, fetch_stealth2, node_);\n    ATTACH(tx_pool, fetch_transaction, node_);\n    ATTACH(tx_pool, validate, node_);\n    ////ATTACH(tx_pool, broadcast, node_);\n    ATTACH(protocol, broadcast_transaction, node_);\n    ATTACH(protocol, total_connections, node_);\n}\n\n#undef ATTACH\n\n} // namespace server\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/CMakeLists.txt",
    "content": "FILE(GLOB_RECURSE api_SOURCES \"*.cpp\")\n\nADD_DEFINITIONS(-DBCX_STATIC=1)\n\nSET(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations\")\n\nADD_LIBRARY(api_static STATIC ${api_SOURCES})\nSET_TARGET_PROPERTIES(api_static PROPERTIES OUTPUT_NAME uc_api)\nTARGET_LINK_LIBRARIES(api_static zmq_static ${Boost_LIBRARIES}\n    ${txs_LIBRARY} ${explorer_LIBRARY} ${bitcoin_LIBRARY} ${network_LIBRARY} ${protocol_LIBRARY} ${client_LIBRARY}\n    ${blockchain_LIBRARY} ${jsoncpp_LIBRARY} ${cryptojs_LIBRARY})\nINSTALL(TARGETS api_static DESTINATION lib)\n\nIF(ENABLE_SHARED_LIBS)\n    ADD_DEFINITIONS(-DBCX_DLL=1)\n  ADD_LIBRARY(api_shared SHARED ${api_SOURCES})\n  SET_TARGET_PROPERTIES(api_shared PROPERTIES OUTPUT_NAME uc_api)\n  TARGET_LINK_LIBRARIES(api_shared ${ZeroMQ_LIBRARIES} ${Boost_LIBRARIES} \n    ${txs_LIBRARY} ${explorer_LIBRARY} ${bitcoin_LIBRARY} ${network_LIBRARY} ${protocol_LIBRARY} ${client_LIBRARY} \n    ${blockchain_LIBRARY} ${jsoncpp_LIBRARY} ${cryptojs_LIBRARY})\n  INSTALL(TARGETS api_shared DESTINATION lib)\nENDIF()\n"
  },
  {
    "path": "src/UChainService/api/command/base_helper.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChainService/api/command/base_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <boost/algorithm/string.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nusing bc::blockchain::validate_tx_engine;\nusing bc::chain::blockchain_message;\n\nutxo_attach_type get_utxo_attach_type(const chain::output &output_)\n{\n    auto &output = const_cast<chain::output &>(output_);\n    if (output.is_ucn())\n    {\n        return utxo_attach_type::ucn;\n    }\n    if (output.is_token_transfer())\n    {\n        return utxo_attach_type::token_transfer;\n    }\n    if (output.is_token_issue())\n    {\n        return utxo_attach_type::token_issue;\n    }\n    if (output.is_token_secondaryissue())\n    {\n        return utxo_attach_type::token_secondaryissue;\n    }\n    if (output.is_token_cert())\n    {\n        return utxo_attach_type::token_cert;\n    }\n    if (output.is_candidate())\n    {\n        return utxo_attach_type::candidate;\n    }\n    if (output.is_uid_register())\n    {\n        return utxo_attach_type::uid_register;\n    }\n    if (output.is_uid_transfer())\n    {\n        return utxo_attach_type::uid_transfer;\n    }\n    if (output.is_message())\n    {\n        return utxo_attach_type::message;\n    }\n    if (output.is_ucn_award())\n    {\n        throw std::logic_error(\"get_utxo_attach_type : Unexpected ucn_award type.\");\n    }\n    throw std::logic_error(\"get_utxo_attach_type : Unkown output type \" + std::to_string(output.attach_data.get_type()));\n}\n\nvoid check_uid_symbol(const std::string &symbol, bool check_sensitive)\n{\n    if (!chain::output::is_valid_uid_symbol(symbol, check_sensitive))\n    {\n        throw uid_symbol_name_exception{\"Uid symbol \" + symbol + \" is not valid.\"};\n    }\n\n    if (check_sensitive)\n    {\n        if (boost::iequals(symbol, \"BLACKHOLE\"))\n        {\n            throw uid_symbol_name_exception{\"Uid symbol cannot be blackhole.\"};\n        }\n    }\n}\n\nvoid check_token_symbol(const std::string &symbol, bool check_sensitive)\n{\n    if (symbol.empty())\n    {\n        throw token_symbol_length_exception{\"Symbol cannot be empty.\"};\n    }\n\n    if (symbol.length() > TOKEN_DETAIL_SYMBOL_FIX_SIZE)\n    {\n        throw token_symbol_length_exception{\"Symbol length must be less than \" + std::to_string(TOKEN_DETAIL_SYMBOL_FIX_SIZE) + \".\"};\n    }\n\n    if (check_sensitive)\n    {\n        if (bc::wallet::symbol::is_sensitive(symbol))\n        {\n            throw token_symbol_name_exception{\"Symbol \" + symbol + \" is forbidden.\"};\n        }\n    }\n}\n\nvoid check_token_symbol_with_miner(const std::string &symbol, const consensus::miner &miner, const std::string &address)\n{\n    if (symbol == UC_VOTE_TOKEN_SYMBOL)\n    {\n        throw token_symbol_name_exception{\"Cannot send 'VOTE' token in this way.Please use vote command.\"};\n    }\n\n    if (symbol == UC_BLOCK_TOKEN_SYMBOL && miner.is_address_inturn(address))\n    {\n        throw token_symbol_name_exception{\"'BLOCK' token cannot be sended when the address is in producing block turn.Please wait several seconds.\"};\n    }\n}\n\nvoid check_token_symbol_with_method(const std::string &symbol)\n{\n    if (symbol == UC_VOTE_TOKEN_SYMBOL)\n    {\n        throw token_symbol_name_exception{\"Cannot send 'VOTE' token in this way.Please use vote command.\"};\n    }\n\n    if (symbol == UC_BLOCK_TOKEN_SYMBOL)\n    {\n        throw token_symbol_name_exception{\"Cannot send 'BLOCK' token in this way.Please use sendtokenfrom command.\"};\n    }\n}\n\nvoid check_candidate_symbol(const std::string &symbol, bool check_sensitive)\n{\n    if (symbol.empty())\n    {\n        throw token_symbol_length_exception{\"Symbol cannot be empty.\"};\n    }\n\n    if (symbol.length() > TOKEN_CANDIDATE_SYMBOL_FIX_SIZE)\n    {\n        throw token_symbol_length_exception{\"Symbol length must be less than \" + std::to_string(TOKEN_CANDIDATE_SYMBOL_FIX_SIZE) + \".\"};\n    }\n\n    // char check\n    for (const auto &i : symbol)\n    {\n        if (!(std::isalnum(i) || i == '.' || i == '@' || i == '_'))\n            throw token_symbol_name_exception(\n                \"Symbol \" + symbol + \" has invalid character.\");\n    }\n\n    if (check_sensitive)\n    {\n        auto upper = boost::to_upper_copy(symbol);\n        if (bc::wallet::symbol::is_sensitive(upper))\n        {\n            throw token_symbol_name_exception{\"Symbol \" + symbol + \" is forbidden.\"};\n        }\n    }\n}\n\nvoid check_candidate_authority(const std::string &symbol)\n{\n    try\n    {\n        const auto authority = libbitcoin::config::authority(symbol);\n        if (!authority.to_network_address().is_routable())\n        {\n            throw address_invalid_exception{\"NODEADDRESS is not routable! \"};\n        }\n    }\n    catch (...)\n    {\n        throw address_invalid_exception{\"NODEADDRESS is invalid! \"};\n    }\n}\n\nstd::string get_address(const std::string &uid_or_address,\n                        bc::blockchain::block_chain_impl &blockchain)\n{\n    std::string address;\n    if (!uid_or_address.empty())\n    {\n        if (blockchain.is_valid_address(uid_or_address))\n        {\n            address = uid_or_address;\n        }\n        else\n        {\n            address = get_address_from_uid(uid_or_address, blockchain);\n        }\n    }\n    return address;\n}\n\nstd::string get_address_from_strict_uid(const std::string &uid_or_address,\n                                        bc::blockchain::block_chain_impl &blockchain)\n{\n    if (!uid_or_address.empty() && blockchain.is_valid_address(uid_or_address))\n    {\n        throw token_symbol_name_exception{\"Address is not supported.\"};\n    }\n    return get_address_from_uid(uid_or_address, blockchain);\n}\n\nstd::string get_address(const std::string &uid_or_address,\n                        asset &attach, bool is_from,\n                        bc::blockchain::block_chain_impl &blockchain)\n{\n    std::string address;\n    if (blockchain.is_valid_address(uid_or_address))\n    {\n        address = uid_or_address;\n    }\n    else\n    {\n        address = get_address_from_uid(uid_or_address, blockchain);\n        if (is_from)\n        {\n            attach.set_from_uid(uid_or_address);\n        }\n        else\n        {\n            attach.set_to_uid(uid_or_address);\n        }\n        attach.set_version(UID_ASSET_VERIFY_VERSION);\n    }\n    return address;\n}\n\nstd::string get_address_from_uid(const std::string &uid,\n                                 bc::blockchain::block_chain_impl &blockchain)\n{\n    check_uid_symbol(uid);\n\n    auto uiddetail = blockchain.get_registered_uid(uid);\n    if (!uiddetail)\n    {\n        throw uid_symbol_notfound_exception{\"uid \" + uid + \" does not exist on the blockchain\"};\n    }\n    return uiddetail->get_address();\n}\n\nstd::string get_random_payment_address(\n    std::shared_ptr<wallet_address::list> sp_addresses,\n    bc::blockchain::block_chain_impl &blockchain)\n{\n    if (sp_addresses && !sp_addresses->empty())\n    {\n        // first, let test 10 times of random\n        for (auto i = 0; i < 10; ++i)\n        {\n            auto random = bc::pseudo_random();\n            auto index = random % sp_addresses->size();\n            auto addr = sp_addresses->at(index).get_address();\n            if (blockchain.is_payment_address(addr))\n            {\n                return addr;\n            }\n        }\n        // then, real bad luck, lets filter only the payment address\n        wallet_address::list filtered_addresses;\n        std::copy_if(sp_addresses->begin(), sp_addresses->end(),\n                     std::back_inserter(filtered_addresses),\n                     [&blockchain](const auto &each) {\n                         return blockchain.is_payment_address(each.get_address());\n                     });\n\n        if (!filtered_addresses.empty())\n        {\n            auto random = bc::pseudo_random();\n            auto index = random % filtered_addresses.size();\n            return filtered_addresses.at(index).get_address();\n        }\n    }\n    return \"\";\n}\n\nvoid sync_fetch_token_cert_balance(const std::string &address, const string &symbol,\n                                   bc::blockchain::block_chain_impl &blockchain,\n                                   std::shared_ptr<token_cert::list> sh_vec,\n                                   token_cert_type cert_type)\n{\n    chain::transaction tx_temp;\n    uint64_t tx_height;\n\n    auto &&rows = blockchain.get_address_history(bc::wallet::payment_address(address));\n    for (auto &row : rows)\n    {\n        // spend unconfirmed (or no spend attempted)\n        if ((row.spend.hash == null_hash) && blockchain.get_transaction(row.output.hash, tx_temp, tx_height))\n        {\n            BITCOIN_ASSERT(row.output.index < tx_temp.outputs.size());\n            const auto &output = tx_temp.outputs.at(row.output.index);\n            if (output.get_script_address() != address)\n            {\n                continue;\n            }\n            if (output.is_token_cert())\n            {\n                auto token_cert = output.get_token_cert();\n                if (!symbol.empty() && symbol != token_cert.get_symbol())\n                {\n                    continue;\n                }\n                if (cert_type != token_cert_ns::none && cert_type != token_cert.get_type())\n                {\n                    continue;\n                }\n\n                sh_vec->push_back(std::move(token_cert));\n            }\n        }\n    }\n}\n\nvoid sync_fetch_token_balance(const std::string &address, bool sum_all,\n                              bc::blockchain::block_chain_impl &blockchain,\n                              std::shared_ptr<token_balances::list> sh_token_vec, uint64_t start_height, uint64_t end_height)\n{\n    auto &&rows = blockchain.get_address_history(bc::wallet::payment_address(address), start_height);\n\n    chain::transaction tx_temp;\n    uint64_t tx_height;\n    uint64_t height = 0;\n    blockchain.get_last_height(height);\n    if (end_height == 0)\n    {\n        end_height = height;\n    }\n\n    for (auto &row : rows)\n    {\n        // spend unconfirmed (or no spend attempted)\n        if ((row.spend.hash == null_hash) && blockchain.get_transaction(row.output.hash, tx_temp, tx_height))\n        {\n            if (row.output_height > end_height)\n            {\n                continue;\n            }\n\n            BITCOIN_ASSERT(row.output.index < tx_temp.outputs.size());\n            const auto &output = tx_temp.outputs.at(row.output.index);\n            if (output.get_script_address() != address)\n            {\n                continue;\n            }\n            if (output.is_token())\n            {\n                const auto &symbol = output.get_token_symbol();\n                if (bc::wallet::symbol::is_forbidden(symbol))\n                {\n                    // swallow forbidden symbol\n                    continue;\n                }\n\n                auto match = [sum_all, &symbol, &address](const token_balances &elem) {\n                    return (symbol == elem.symbol) && (sum_all || (address == elem.address));\n                };\n                auto iter = std::find_if(sh_token_vec->begin(), sh_token_vec->end(), match);\n\n                auto token_amount = output.get_token_amount();\n                uint64_t locked_amount = 0;\n                if (token_amount && operation::is_pay_key_hash_with_attenuation_model_pattern(output.script.operations))\n                {\n                    const auto &attenuation_model_param = output.get_attenuation_model_param();\n                    auto diff_height = row.output_height ? (height - row.output_height) : 0;\n                    auto available_amount = attenuation_model::get_available_token_amount(\n                        token_amount, diff_height, attenuation_model_param);\n                    locked_amount = token_amount - available_amount;\n                }\n                if (iter == sh_token_vec->end())\n                { // new item\n                    sh_token_vec->push_back({symbol, address, token_amount, locked_amount});\n                }\n                else\n                { // exist just add amount\n                    iter->unspent_token += token_amount;\n                    iter->locked_token += locked_amount;\n                }\n            }\n        }\n    }\n}\n\nvoid sync_fetch_token_deposited_balance(const std::string &address,\n                                        bc::blockchain::block_chain_impl &blockchain,\n                                        std::shared_ptr<token_deposited_balance::list> sh_token_vec)\n{\n    auto &&rows = blockchain.get_address_history(bc::wallet::payment_address(address));\n\n    chain::transaction tx_temp;\n    uint64_t tx_height;\n    uint64_t height = 0;\n    blockchain.get_last_height(height);\n\n    for (auto &row : rows)\n    {\n        // spend unconfirmed (or no spend attempted)\n        if ((row.spend.hash == null_hash) && blockchain.get_transaction(row.output.hash, tx_temp, tx_height))\n        {\n            BITCOIN_ASSERT(row.output.index < tx_temp.outputs.size());\n            const auto &output = tx_temp.outputs.at(row.output.index);\n            if (output.is_token())\n            {\n                if (!operation::is_pay_key_hash_with_attenuation_model_pattern(output.script.operations))\n                {\n                    continue;\n                }\n\n                auto token_amount = output.get_token_amount();\n                if (token_amount == 0)\n                {\n                    continue;\n                }\n\n                const auto &symbol = output.get_token_symbol();\n                if (bc::wallet::symbol::is_forbidden(symbol))\n                {\n                    // swallow forbidden symbol\n                    continue;\n                }\n\n                const auto &model_param = output.get_attenuation_model_param();\n                auto diff_height = row.output_height ? (height - row.output_height) : 0;\n                auto available_amount = attenuation_model::get_available_token_amount(\n                    token_amount, diff_height, model_param);\n                uint64_t locked_amount = token_amount - available_amount;\n                if (locked_amount == 0)\n                {\n                    continue;\n                }\n\n                token_deposited_balance deposited(\n                    symbol, address, encode_hash(row.output.hash), row.output_height);\n                deposited.unspent_token = token_amount;\n                deposited.locked_token = locked_amount;\n                deposited.model_param = std::string(model_param.begin(), model_param.end());\n                sh_token_vec->push_back(deposited);\n            }\n        }\n    }\n}\n\nvoid sync_unspend_output(bc::blockchain::block_chain_impl &blockchain, const input_point &input,\n                         std::shared_ptr<output_point::list> &output_list, base_transfer_common::filter filter)\n{\n    auto is_filter = [filter](const output &output_) {\n        if (((filter & base_transfer_common::FILTER_UCN) && output_.is_ucn()) || ((filter & base_transfer_common::FILTER_TOKEN) && output_.is_token()) || ((filter & base_transfer_common::FILTER_IDENTIFIABLE_TOKEN) && output_.is_candidate()) || ((filter & base_transfer_common::FILTER_TOKENCERT) && output_.is_token_cert()) || ((filter & base_transfer_common::FILTER_UID) && output_.is_uid()))\n        {\n            return true;\n        }\n        return false;\n    };\n\n    std::shared_ptr<chain::transaction> tx = blockchain.get_spends_output(input);\n    uint64_t tx_height;\n    chain::transaction tx_temp;\n    if (tx == nullptr && blockchain.get_transaction(input.hash, tx_temp, tx_height))\n    {\n        const auto &output = tx_temp.outputs.at(input.index);\n\n        if (is_filter(output))\n        {\n            output_list->emplace_back(input);\n        }\n    }\n    else if (tx != nullptr)\n    {\n\n        for (uint32_t i = 0; i < tx->outputs.size(); i++)\n        {\n            const auto &output = tx->outputs.at(i);\n            if (is_filter(output))\n            {\n                input_point input_ = {tx->hash(), i};\n                sync_unspend_output(blockchain, input_, output_list, filter);\n            }\n        }\n    }\n}\n\nauto get_token_unspend_utxo(const std::string &symbol,\n                            bc::blockchain::block_chain_impl &blockchain) -> std::shared_ptr<output_point::list>\n{\n    auto blockchain_tokens = blockchain.get_token_register_output(symbol);\n    if (blockchain_tokens == nullptr || blockchain_tokens->empty())\n    {\n        throw token_symbol_existed_exception(std::string(\"token symbol[\") + symbol + \"]does not exist!\");\n    }\n\n    std::shared_ptr<output_point::list> output_list = std::make_shared<output_point::list>();\n    for (auto token : *blockchain_tokens)\n    {\n        auto out_point = token.get_tx_point();\n        sync_unspend_output(blockchain, out_point, output_list, base_transfer_common::FILTER_TOKEN);\n    }\n    if (!output_list->empty())\n    {\n        std::sort(output_list->begin(), output_list->end());\n        output_list->erase(std::unique(output_list->begin(), output_list->end()), output_list->end());\n    }\n    return output_list;\n}\n\nauto sync_fetch_token_deposited_view(const std::string &symbol,\n                                     bc::blockchain::block_chain_impl &blockchain)\n    -> std::shared_ptr<token_deposited_balance::list>\n{\n\n    std::shared_ptr<output_point::list> output_list = get_token_unspend_utxo(symbol, blockchain);\n\n    std::shared_ptr<token_deposited_balance::list> sh_token_vec = std::make_shared<token_deposited_balance::list>();\n\n    chain::transaction tx_temp;\n    uint64_t tx_height;\n    uint64_t height = 0;\n    blockchain.get_last_height(height);\n\n    for (auto &out : *output_list)\n    {\n        // spend unconfirmed (or no spend attempted)\n        if (blockchain.get_transaction(out.hash, tx_temp, tx_height))\n        {\n            BITCOIN_ASSERT(out.index < tx_temp.outputs.size());\n            const auto &output = tx_temp.outputs.at(out.index);\n            if (output.is_token())\n            {\n                std::string address = output.get_script_address();\n\n                const auto &symbol = output.get_token_symbol();\n                if (output.get_token_symbol() != symbol ||\n                    bc::wallet::symbol::is_forbidden(symbol))\n                {\n                    // swallow forbidden symbol\n                    continue;\n                }\n\n                if (!operation::is_pay_key_hash_with_attenuation_model_pattern(output.script.operations))\n                {\n                    continue;\n                }\n\n                auto token_amount = output.get_token_amount();\n                if (token_amount == 0)\n                {\n                    continue;\n                }\n\n                const auto &model_param = output.get_attenuation_model_param();\n                auto diff_height = tx_height ? (height - tx_height) : 0;\n                auto available_amount = attenuation_model::get_available_token_amount(\n                    token_amount, diff_height, model_param);\n                uint64_t locked_amount = token_amount - available_amount;\n                if (locked_amount == 0)\n                {\n                    continue;\n                }\n\n                token_deposited_balance deposited(\n                    symbol, address, encode_hash(out.hash), tx_height);\n                deposited.unspent_token = token_amount;\n                deposited.locked_token = locked_amount;\n                deposited.model_param = std::string(model_param.begin(), model_param.end());\n                sh_token_vec->emplace_back(deposited);\n            }\n        }\n    }\n\n    return sh_token_vec;\n}\n\nauto sync_fetch_token_view(const std::string &symbol,\n                           bc::blockchain::block_chain_impl &blockchain)\n    -> std::shared_ptr<token_balances::list>\n{\n\n    std::shared_ptr<output_point::list> output_list = get_token_unspend_utxo(symbol, blockchain);\n\n    std::shared_ptr<token_balances::list> sh_token_vec = std::make_shared<token_balances::list>();\n\n    chain::transaction tx_temp;\n    uint64_t tx_height;\n    uint64_t height = 0;\n    blockchain.get_last_height(height);\n\n    for (auto &out : *output_list)\n    {\n        // spend unconfirmed (or no spend attempted)\n        if (blockchain.get_transaction(out.hash, tx_temp, tx_height))\n        {\n            BITCOIN_ASSERT(out.index < tx_temp.outputs.size());\n            const auto &output = tx_temp.outputs.at(out.index);\n            if (output.is_token())\n            {\n                std::string address = output.get_script_address();\n\n                const auto &symbol = output.get_token_symbol();\n                if (output.get_token_symbol() != symbol ||\n                    bc::wallet::symbol::is_forbidden(symbol))\n                {\n                    // swallow forbidden symbol\n                    continue;\n                }\n\n                auto token_amount = output.get_token_amount();\n                uint64_t locked_amount = 0;\n                if (token_amount && operation::is_pay_key_hash_with_attenuation_model_pattern(output.script.operations))\n                {\n                    const auto &attenuation_model_param = output.get_attenuation_model_param();\n                    auto diff_height = tx_height ? (height - tx_height) : 0;\n                    auto available_amount = attenuation_model::get_available_token_amount(\n                        token_amount, diff_height, attenuation_model_param);\n                    locked_amount = token_amount - available_amount;\n                }\n\n                sh_token_vec->push_back({symbol, address, token_amount, locked_amount});\n            }\n        }\n    }\n\n    return sh_token_vec;\n}\n\nstatic uint32_t get_domain_cert_count(bc::blockchain::block_chain_impl &blockchain,\n                                      const std::string &wallet_name)\n{\n    auto pvaddr = blockchain.get_wallet_addresses(wallet_name);\n    if (!pvaddr)\n    {\n        return 0;\n    }\n\n    auto sh_vec = std::make_shared<token_cert::list>();\n    for (auto &each : *pvaddr)\n    {\n        sync_fetch_token_cert_balance(each.get_address(), \"\", blockchain, sh_vec, token_cert_ns::domain);\n    }\n\n    return sh_vec->size();\n}\n\nvoid sync_fetch_deposited_balance(bc::wallet::payment_address &address,\n                                  bc::blockchain::block_chain_impl &blockchain, std::shared_ptr<deposited_balance::list> sh_vec)\n{\n    chain::transaction tx_temp;\n    uint64_t tx_height;\n    uint64_t height = 0;\n    blockchain.get_last_height(height);\n\n    auto &&address_str = address.encoded();\n    auto &&rows = blockchain.get_address_history(address, false);\n    for (auto &row : rows)\n    {\n        if (row.output_height == 0)\n        {\n            continue;\n        }\n\n        // spend unconfirmed (or no spend attempted)\n        if ((row.spend.hash == null_hash) && blockchain.get_transaction(row.output.hash, tx_temp, tx_height))\n        {\n            BITCOIN_ASSERT(row.output.index < tx_temp.outputs.size());\n            auto output = tx_temp.outputs.at(row.output.index);\n            if (output.get_script_address() != address.encoded())\n            {\n                continue;\n            }\n\n            if (chain::operation::is_pay_key_hash_with_lock_height_pattern(output.script.operations))\n            {\n                // deposit utxo in block\n                uint64_t deposit_height = chain::operation::\n                    get_lock_height_from_pay_key_hash_with_lock_height(output.script.operations);\n                uint64_t expiration_height = row.output_height + deposit_height;\n\n                if (expiration_height > height)\n                {\n                    auto &&output_hash = encode_hash(row.output.hash);\n                    auto &&tx_hash = encode_hash(tx_temp.hash());\n                    const auto match = [&tx_hash](const deposited_balance &balance) {\n                        return balance.tx_hash == tx_hash;\n                    };\n                    auto iter = std::find_if(sh_vec->begin(), sh_vec->end(), match);\n                    if (iter != sh_vec->end())\n                    {\n                        if (output_hash == tx_hash)\n                        {\n                            iter->balance = row.value;\n                        }\n                        else\n                        {\n                            iter->bonus = row.value;\n                            iter->bonus_hash = output_hash;\n                        }\n                    }\n                    else\n                    {\n\n                        deposited_balance deposited(address_str, tx_hash, deposit_height, expiration_height);\n                        if (output_hash == tx_hash)\n                        {\n                            deposited.balance = row.value;\n                        }\n                        else\n                        {\n                            deposited.bonus = row.value;\n                            deposited.bonus_hash = output_hash;\n                        }\n                        sh_vec->push_back(std::move(deposited));\n                    }\n                }\n            }\n        }\n    }\n}\n\nvoid sync_fetchbalance(bc::wallet::payment_address &address,\n                       bc::blockchain::block_chain_impl &blockchain, balances &addr_balance)\n{\n    auto &&rows = blockchain.get_address_history(address, false);\n\n    uint64_t total_received = 0;\n    uint64_t confirmed_balance = 0;\n    uint64_t unspent_balance = 0;\n    uint64_t frozen_balance = 0;\n\n    chain::transaction tx_temp;\n    uint64_t tx_height;\n    uint64_t height = 0;\n    blockchain.get_last_height(height);\n\n    for (auto &row : rows)\n    {\n        /*if (row.output_height == 0) {\n            continue;\n        }*/\n\n        // spend unconfirmed (or no spend attempted)\n        if ((row.spend.hash == null_hash) && blockchain.get_transaction(row.output.hash, tx_temp, tx_height))\n        {\n            BITCOIN_ASSERT(row.output.index < tx_temp.outputs.size());\n            auto output = tx_temp.outputs.at(row.output.index);\n            if (output.get_script_address() != address.encoded())\n            {\n                continue;\n            }\n\n            if (chain::operation::is_pay_key_hash_with_lock_height_pattern(output.script.operations))\n            {\n                // deposit utxo in block\n                uint64_t lock_height = chain::operation::\n                    get_lock_height_from_pay_key_hash_with_lock_height(output.script.operations);\n                if ((row.output_height + lock_height) > height)\n                {\n                    // utxo already in block but deposit not expire\n                    frozen_balance += row.value;\n                }\n            }\n            else if (tx_temp.is_coinbase())\n            { // coin base ucn maturity ucn check\n                // add not coinbase_maturity ucn into frozen\n                if ((row.output_height + coinbase_maturity) > height)\n                {\n                    frozen_balance += row.value;\n                }\n            }\n\n            unspent_balance += row.value;\n        }\n\n        total_received += row.value;\n\n        if ((row.spend.hash == null_hash || row.spend_height == 0))\n            confirmed_balance += row.value;\n    }\n\n    addr_balance.confirmed_balance = confirmed_balance;\n    addr_balance.total_received = total_received;\n    addr_balance.unspent_balance = unspent_balance;\n    addr_balance.frozen_balance = frozen_balance;\n}\n\nbool base_transfer_common::get_spendable_output(\n    chain::output &output, const chain::history &row, uint64_t height) const\n{\n    // spended\n    if (row.spend.hash != null_hash)\n    {\n        return false;\n    }\n\n    chain::transaction tx_temp;\n    uint64_t tx_height;\n    if (!blockchain_.get_transaction(row.output.hash, tx_temp, tx_height))\n    {\n        return false;\n    }\n\n    BITCOIN_ASSERT(row.output.index < tx_temp.outputs.size());\n    output = tx_temp.outputs.at(row.output.index);\n\n    if (chain::operation::is_pay_key_hash_with_lock_height_pattern(output.script.operations))\n    {\n        if (row.output_height == 0)\n        {\n            // deposit utxo in transaction pool\n            return false;\n        }\n        else\n        {\n            // deposit utxo in block\n            auto lock_height = chain::operation::\n                get_lock_height_from_pay_key_hash_with_lock_height(output.script.operations);\n            if ((row.output_height + lock_height) > height)\n            {\n                // utxo already in block but deposit not expire\n                return false;\n            }\n        }\n    } //else if (tx_temp.is_coinbase()) { // incase readd deposit\n    // coin base ucn maturity ucn check\n    // coinbase_maturity ucn check\n    //if (/*(row.output_height == 0) ||*/ ((row.output_height + coinbase_maturity) > height)) {\n    //    return false;\n    //}\n    //}\n\n    return true;\n}\n\n// only consider ucn and token and cert.\n// specify parameter 'uid' to true to only consider uid\nvoid base_transfer_common::sync_fetchutxo(\n    const std::string &prikey, const std::string &addr, filter filter)\n{\n    auto &&waddr = bc::wallet::payment_address(addr);\n    auto &&rows = blockchain_.get_address_history(waddr, true);\n\n    uint64_t height = 0;\n    blockchain_.get_last_height(height);\n\n    for (auto &row : rows)\n    {\n        // performance improve\n        if (is_payment_satisfied(filter))\n        {\n            break;\n        }\n\n        chain::output output;\n        if (!get_spendable_output(output, row, height))\n        {\n            continue;\n        }\n\n        if (output.get_script_address() != addr)\n        {\n            continue;\n        }\n\n        auto ucn_amount = row.value;\n        auto token_total_amount = output.get_token_amount();\n        auto cert_type = output.get_token_cert_type();\n        auto token_symbol = output.get_token_symbol();\n\n        // filter output\n        if ((filter & FILTER_UCN) && output.is_ucn())\n        { // ucn related\n            BITCOIN_ASSERT(token_total_amount == 0);\n            BITCOIN_ASSERT(token_symbol.empty());\n            if (ucn_amount == 0)\n                continue;\n            // enough ucn to pay\n            if (unspent_ucn_ >= payment_ucn_)\n                continue;\n        }\n        else if ((filter & FILTER_TOKEN) && output.is_token())\n        { // token related\n            BITCOIN_ASSERT(ucn_amount == 0);\n            BITCOIN_ASSERT(cert_type == token_cert_ns::none);\n            if (token_total_amount == 0)\n                continue;\n            // enough token to pay\n            if (unspent_token_ >= payment_token_)\n                continue;\n            // check token symbol\n            if (symbol_ != token_symbol)\n                continue;\n\n            if (bc::wallet::symbol::is_forbidden(token_symbol))\n            {\n                // swallow forbidden symbol\n                continue;\n            }\n        }\n        else if ((filter & FILTER_IDENTIFIABLE_TOKEN) && output.is_candidate())\n        {\n            BITCOIN_ASSERT(ucn_amount == 0);\n            BITCOIN_ASSERT(token_total_amount == 0);\n            BITCOIN_ASSERT(cert_type == token_cert_ns::none);\n\n            if (payment_candidate_ <= unspent_candidate_)\n            {\n                continue;\n            }\n\n            if (symbol_ != output.get_token_symbol())\n                continue;\n\n            ++unspent_candidate_;\n        }\n        else if ((filter & FILTER_TOKENCERT) && output.is_token_cert())\n        { // cert related\n            BITCOIN_ASSERT(ucn_amount == 0);\n            BITCOIN_ASSERT(token_total_amount == 0);\n            // no needed token cert is included in this output\n            if (payment_token_cert_.empty())\n                continue;\n\n            // check cert symbol\n            if (cert_type == token_cert_ns::domain)\n            {\n                auto &&domain = token_cert::get_domain(symbol_);\n                if (domain != token_symbol)\n                    continue;\n            }\n            else\n            {\n                if (symbol_ != token_symbol)\n                    continue;\n            }\n\n            // check cert type\n            if (!token_cert::test_certs(payment_token_cert_, cert_type))\n            {\n                continue;\n            }\n\n            // token cert has already found\n            if (token_cert::test_certs(unspent_token_cert_, payment_token_cert_))\n            {\n                continue;\n            }\n        }\n        else if ((filter & FILTER_UID) &&\n                 (output.is_uid_register() || output.is_uid_transfer()))\n        { // uid related\n            BITCOIN_ASSERT(ucn_amount == 0);\n            BITCOIN_ASSERT(token_total_amount == 0);\n            BITCOIN_ASSERT(cert_type == token_cert_ns::none);\n\n            if (payment_uid_ <= unspent_uid_)\n            {\n                continue;\n            }\n\n            if (symbol_ != output.get_uid_symbol())\n                continue;\n\n            ++unspent_uid_;\n        }\n        else\n        {\n            continue;\n        }\n\n        auto token_amount = token_total_amount;\n        std::shared_ptr<data_chunk> new_model_param_ptr;\n        if (token_total_amount && operation::is_pay_key_hash_with_attenuation_model_pattern(output.script.operations))\n        {\n            const auto &attenuation_model_param = output.get_attenuation_model_param();\n            new_model_param_ptr = std::make_shared<data_chunk>();\n            auto diff_height = row.output_height ? (height - row.output_height) : 0;\n            token_amount = attenuation_model::get_available_token_amount(\n                token_total_amount, diff_height, attenuation_model_param, new_model_param_ptr);\n            if ((token_amount == 0) && !is_locked_token_as_payment())\n            {\n                continue; // all locked, filter out\n            }\n        }\n\n        BITCOIN_ASSERT(token_total_amount >= token_amount);\n\n        // add to from list\n        address_token_record record;\n\n        if (!prikey.empty())\n        { // raw tx has no prikey\n            record.prikey = prikey;\n            record.script = output.script;\n        }\n        record.addr = addr;\n        record.amount = ucn_amount;\n        record.symbol = token_symbol;\n        record.token_amount = token_amount;\n        record.token_cert = cert_type;\n        record.output = row.output;\n        record.type = get_utxo_attach_type(output);\n\n        from_list_.push_back(record);\n\n        unspent_ucn_ += record.amount;\n        unspent_token_ += record.token_amount;\n\n        if (record.token_cert != token_cert_ns::none)\n        {\n            unspent_token_cert_.push_back(record.token_cert);\n        }\n\n        // token_locked_transfer as a special change\n        if (new_model_param_ptr && (token_total_amount > record.token_amount))\n        {\n            auto locked_token = token_total_amount - record.token_amount;\n            std::string model_param(new_model_param_ptr->begin(), new_model_param_ptr->end());\n            receiver_list_.push_back({record.addr, record.symbol,\n                                      0, locked_token, utxo_attach_type::token_locked_transfer,\n                                      asset(0, 0, blockchain_message(std::move(model_param))), record.output});\n            // in secondary issue, locked token can also verify threshold condition\n            if (is_locked_token_as_payment())\n            {\n                payment_token_ = (payment_token_ > locked_token)\n                                     ? (payment_token_ - locked_token)\n                                     : 0;\n            }\n        }\n    }\n\n    rows.clear();\n}\n\nvoid base_transfer_common::check_fee_in_valid_range(uint64_t fee)\n{\n    if ((fee < minimum_fee) || (fee > maximum_fee))\n    {\n        throw token_exchange_poundage_exception{\"fee must in [\" + std::to_string(minimum_fee) + \", \" + std::to_string(maximum_fee) + \"]\"};\n    }\n}\n\nvoid base_transfer_common::check_model_param_initial(std::string &param, uint64_t amount)\n{\n    if (!param.empty())\n    {\n        if (!validate_tx_engine::is_uid_feature_activated(blockchain_))\n        {\n            throw token_attenuation_model_exception(\n                \"attenuation model should be supported after uid feature is activated.\");\n        }\n        if (!attenuation_model::check_model_param_initial(param, amount, true))\n        {\n            throw token_attenuation_model_exception(\"check token attenuation model param failed\");\n        }\n    }\n}\n\nvoid base_transfer_common::sum_payments()\n{\n    for (auto &iter : receiver_list_)\n    {\n        payment_ucn_ += iter.amount;\n        //vote token will be not counted\n        if (symbol_ != UC_VOTE_TOKEN_SYMBOL)\n        {\n            payment_token_ += iter.token_amount;\n        }\n\n        if (iter.token_cert != token_cert_ns::none)\n        {\n            payment_token_cert_.push_back(iter.token_cert);\n        }\n\n        if (iter.type == utxo_attach_type::candidate_transfer)\n        {\n            ++payment_candidate_;\n            if (payment_candidate_ > 1)\n            {\n                throw std::logic_error{\"maximum one candidate can be transfered\"};\n            }\n        }\n        else if (iter.type == utxo_attach_type::uid_transfer)\n        {\n            ++payment_uid_;\n            if (payment_uid_ > 1)\n            {\n                throw std::logic_error{\"maximum one UID can be transfered\"};\n            }\n        }\n    }\n}\n\nvoid base_transfer_common::check_receiver_list_not_empty() const\n{\n    if (receiver_list_.empty())\n    {\n        throw toaddress_empty_exception{\"empty target address\"};\n    }\n}\n\nvoid base_transfer_common::sum_payment_amount()\n{\n    check_receiver_list_not_empty();\n    check_fee_in_valid_range(payment_ucn_);\n    sum_payments();\n}\n\nbool base_transfer_common::is_payment_satisfied(filter filter) const\n{\n    if ((filter & FILTER_UCN) && (unspent_ucn_ < payment_ucn_))\n        return false;\n\n    if ((filter & FILTER_TOKEN) && (unspent_token_ < payment_token_))\n        return false;\n\n    if ((filter & FILTER_IDENTIFIABLE_TOKEN) && (unspent_candidate_ < payment_candidate_))\n        return false;\n\n    if ((filter & FILTER_TOKENCERT) && !token_cert::test_certs(unspent_token_cert_, payment_token_cert_))\n        return false;\n\n    if ((filter & FILTER_UID) && (unspent_uid_ < payment_uid_))\n        return false;\n\n    return true;\n}\n\nvoid base_transfer_common::check_payment_satisfied(filter filter) const\n{\n    if ((filter & FILTER_UCN) && (unspent_ucn_ < payment_ucn_))\n    {\n        throw wallet_balance_lack_exception{\"not enough balance, unspent = \" + std::to_string(unspent_ucn_) + \", payment = \" + std::to_string(payment_ucn_)};\n    }\n\n    if ((filter & FILTER_TOKEN) && (unspent_token_ < payment_token_) && symbol_ != UC_VOTE_TOKEN_SYMBOL)\n    {\n        throw token_lack_exception{\"not enough token amount, unspent = \" + std::to_string(unspent_token_) + \", payment = \" + std::to_string(payment_token_)};\n    }\n\n    if ((filter & FILTER_IDENTIFIABLE_TOKEN) && (unspent_candidate_ < payment_candidate_))\n    {\n        throw token_lack_exception{\"not enough candidate amount, unspent = \" + std::to_string(unspent_candidate_) + \", payment = \" + std::to_string(payment_candidate_)};\n    }\n\n    if ((filter & FILTER_TOKENCERT) && !token_cert::test_certs(unspent_token_cert_, payment_token_cert_))\n    {\n        std::string payment(\" \");\n        for (auto &cert_type : payment_token_cert_)\n        {\n            payment += token_cert::get_type_name(cert_type);\n            payment += \" \";\n        }\n        std::string unspent(\" \");\n        for (auto &cert_type : unspent_token_cert_)\n        {\n            unspent += token_cert::get_type_name(cert_type);\n            unspent += \" \";\n        }\n\n        throw token_cert_exception{\"not enough token cert, unspent = (\" + unspent + \"), payment = (\" + payment + \")\"};\n    }\n\n    if ((filter & FILTER_UID) && (unspent_uid_ < payment_uid_))\n    {\n        throw tx_source_exception{\"no uid named \" + symbol_ + \" is found\"};\n    }\n}\n\nvoid base_transfer_common::populate_change()\n{\n    // only ucn utxo, others in derived class\n    populate_ucn_change();\n}\n\nstd::string base_transfer_common::get_mychange_address(filter filter) const\n{\n    if (!mychange_.empty())\n    {\n        return mychange_;\n    }\n\n    if ((filter & FILTER_PAYFROM) && !from_.empty())\n    {\n        return from_;\n    }\n\n    const auto match = [filter](const address_token_record &record) {\n        if (filter & FILTER_UCN)\n        {\n            return (record.type == utxo_attach_type::ucn);\n        }\n        if (filter & FILTER_TOKEN)\n        {\n            return (record.type == utxo_attach_type::token_transfer) || (record.type == utxo_attach_type::token_issue) || (record.type == utxo_attach_type::token_secondaryissue);\n        }\n        throw std::logic_error{\"get_mychange_address: unknown/wrong filter for mychange\"};\n    };\n\n    // reverse find the lates matched unspent\n    auto it = from_list_.crbegin();\n    for (; it != from_list_.crend(); ++it)\n    {\n        if (match(*it))\n        {\n            return it->addr;\n        }\n    }\n    BITCOIN_ASSERT(it != from_list_.crend());\n\n    return from_list_.begin()->addr;\n}\n\nvoid base_transfer_common::populate_ucn_change(const std::string &address)\n{\n    // ucn utxo\n    if (unspent_ucn_ > payment_ucn_)\n    {\n        auto addr = address;\n        if (addr.empty())\n        {\n            addr = get_mychange_address(FILTER_UCN);\n        }\n        BITCOIN_ASSERT(!addr.empty());\n\n        if (blockchain_.is_valid_address(addr))\n        {\n            receiver_list_.push_back(\n                {addr, \"\", unspent_ucn_ - payment_ucn_, 0, utxo_attach_type::ucn, asset()});\n        }\n        else\n        {\n            if (addr.length() > UID_DETAIL_SYMBOL_FIX_SIZE)\n            {\n                throw uid_symbol_length_exception{\n                    \"mychange uid symbol \" + addr + \" length must be less than 64.\"};\n            }\n\n            auto uiddetail = blockchain_.get_registered_uid(addr);\n            if (!uiddetail)\n            {\n                throw uid_symbol_notfound_exception{\n                    \"mychange uid symbol \" + addr + \"does not exist on the blockchain\"};\n            }\n\n            asset attach;\n            attach.set_version(UID_ASSET_VERIFY_VERSION);\n            attach.set_to_uid(addr);\n            receiver_list_.push_back(\n                {uiddetail->get_address(), \"\", unspent_ucn_ - payment_ucn_, 0, utxo_attach_type::ucn, attach});\n        }\n    }\n}\n\nvoid base_transfer_common::populate_token_change(const std::string &address)\n{\n    // token utxo\n    if (unspent_token_ > payment_token_)\n    {\n        auto addr = address;\n        if (addr.empty())\n        {\n            addr = get_mychange_address(FILTER_TOKEN);\n        }\n        BITCOIN_ASSERT(!addr.empty());\n\n        if (blockchain_.is_valid_address(addr))\n        {\n            receiver_list_.push_back({addr, symbol_, 0, unspent_token_ - payment_token_,\n                                      utxo_attach_type::token_transfer, asset()});\n        }\n        else\n        {\n            if (addr.length() > UID_DETAIL_SYMBOL_FIX_SIZE)\n            {\n                throw uid_symbol_length_exception{\n                    \"mychange uid symbol \" + addr + \" length must be less than 64.\"};\n            }\n\n            auto uiddetail = blockchain_.get_registered_uid(addr);\n            if (!uiddetail)\n            {\n                throw uid_symbol_notfound_exception{\n                    \"mychange uid symbol \" + addr + \"does not exist on the blockchain\"};\n            }\n\n            asset attach;\n            attach.set_version(UID_ASSET_VERIFY_VERSION);\n            attach.set_to_uid(addr);\n            receiver_list_.push_back({uiddetail->get_address(), symbol_, 0, unspent_token_ - payment_token_,\n                                      utxo_attach_type::token_transfer, attach});\n        }\n    }\n}\n\nchain::operation::stack\nbase_transfer_common::get_script_operations(const receiver_record &record) const\n{\n    chain::operation::stack payment_ops;\n\n    // complicated script and token should be implemented in subclass\n    // generate script\n    const bc::wallet::payment_address payment(record.target);\n    if (!payment)\n        throw toaddress_invalid_exception{\"invalid target address\"};\n\n    const auto &hash = payment.hash();\n    if (blockchain_.is_blackhole_address(record.target))\n    {\n        payment_ops = chain::operation::to_pay_blackhole_pattern(hash);\n    }\n    else if (payment.version() == bc::wallet::payment_address::mainnet_p2kh)\n    {\n        if (record.type == utxo_attach_type::token_locked_transfer)\n        { // for token locked change only\n            const auto &attenuation_model_param =\n                boost::get<blockchain_message>(record.attach_elem.get_attach()).get_content();\n            if (!attenuation_model::check_model_param_format(to_chunk(attenuation_model_param)))\n            {\n                throw token_attenuation_model_exception(\n                    \"check token locked transfer attenuation model param failed: \" + attenuation_model_param);\n            }\n            payment_ops = chain::operation::to_pay_key_hash_with_attenuation_model_pattern(\n                hash, attenuation_model_param, record.input_point);\n        }\n        else\n        {\n            payment_ops = chain::operation::to_pay_key_hash_pattern(hash);\n        }\n    }\n    else if (payment.version() == bc::wallet::payment_address::mainnet_p2sh)\n    {\n        payment_ops = chain::operation::to_pay_script_hash_pattern(hash);\n    }\n    else\n    {\n        throw toaddress_unrecognized_exception{\"unrecognized target address : \" + payment.encoded()};\n    }\n\n    return payment_ops;\n}\n\nchain::operation::stack\nbase_transfer_common::get_pay_key_hash_with_attenuation_model_operations(\n    const std::string &model_param, const receiver_record &record)\n{\n    if (model_param.empty())\n    {\n        throw token_attenuation_model_exception(\"attenuation model param is empty.\");\n    }\n\n    const bc::wallet::payment_address payment(record.target);\n    if (!payment)\n    {\n        throw toaddress_invalid_exception{\"invalid target address\"};\n    }\n\n    if (payment.version() == bc::wallet::payment_address::mainnet_p2kh)\n    {\n        return chain::operation::to_pay_key_hash_with_attenuation_model_pattern(\n            payment.hash(), model_param, record.input_point);\n    }\n\n    throw toaddress_invalid_exception{std::string(\"not supported version target address \") + record.target};\n}\n\nvoid base_transfer_common::populate_tx_outputs()\n{\n    for (const auto &iter : receiver_list_)\n    {\n        if (iter.is_empty())\n        {\n            continue;\n        }\n\n        if (tx_item_idx_ >= (tx_limit + 10))\n        {\n            throw tx_validate_exception{\"Too many inputs/outputs,tx too large, canceled.\"};\n        }\n        tx_item_idx_++;\n\n        auto &&payment_script = chain::script{get_script_operations(iter)};\n\n        // generate token info\n        auto &&output_att = populate_output_asset(iter);\n        set_uid_verify_asset(iter, output_att);\n\n        if (!output_att.is_valid())\n        {\n            throw tx_validate_exception{\"validate transaction failure, invalid output asset.\"};\n        }\n\n        // fill output\n        tx_.outputs.push_back({iter.amount, payment_script, output_att});\n    }\n}\n\nvoid base_transfer_common::populate_tx_inputs()\n{\n    // input args\n    tx_input_type input;\n\n    for (auto &fromeach : from_list_)\n    {\n        if (tx_item_idx_ >= tx_limit)\n        {\n            auto &&response = \"Too many inputs, suggest less than \" + std::to_string(tx_limit) + \" inputs.\";\n            throw tx_validate_exception(response);\n        }\n\n        tx_item_idx_++;\n        input.sequence = max_input_sequence;\n        input.previous_output.hash = fromeach.output.hash;\n        input.previous_output.index = fromeach.output.index;\n        tx_.inputs.push_back(input);\n    }\n}\n\nvoid base_transfer_common::set_uid_verify_asset(const receiver_record &record, asset &attach)\n{\n    if (record.attach_elem.get_version() == UID_ASSET_VERIFY_VERSION)\n    {\n        attach.set_version(UID_ASSET_VERIFY_VERSION);\n        attach.set_to_uid(record.attach_elem.get_to_uid());\n        attach.set_from_uid(record.attach_elem.get_from_uid());\n    }\n}\n\nasset base_transfer_common::populate_output_asset(const receiver_record &record)\n{\n    if ((record.type == utxo_attach_type::ucn) || (record.type == utxo_attach_type::deposit) || ((record.type == utxo_attach_type::token_transfer) && ((record.amount > 0) && (!record.token_amount))))\n    { // ucn\n        return asset(UCN_TYPE, attach_version, chain::ucn(record.amount));\n    }\n    else if (record.type == utxo_attach_type::token_issue || record.type == utxo_attach_type::token_secondaryissue)\n    {\n        return asset(UC_TOKEN_TYPE, attach_version, token(/*set on subclass*/));\n    }\n    else if (record.type == utxo_attach_type::token_transfer || record.type == utxo_attach_type::token_locked_transfer || record.type == utxo_attach_type::token_attenuation_transfer)\n    {\n        auto transfer = chain::token_transfer(record.symbol, record.token_amount);\n        auto ass = token(TOKEN_TRANSFERABLE_TYPE, transfer);\n        if (!ass.is_valid())\n        {\n            throw tx_asset_value_exception{\"invalid token transfer asset\"};\n        }\n        return asset(UC_TOKEN_TYPE, attach_version, ass);\n    }\n    else if (record.type == utxo_attach_type::message)\n    {\n        auto msg = boost::get<blockchain_message>(record.attach_elem.get_attach());\n        if (msg.get_content().size() > 128)\n        {\n            throw tx_asset_value_exception{\"memo text length should be less than 128\"};\n        }\n        if (!msg.is_valid())\n        {\n            throw tx_asset_value_exception{\"invalid message asset\"};\n        }\n        return asset(MESSAGE_TYPE, attach_version, msg);\n    }\n    else if (record.type == utxo_attach_type::uid_register)\n    {\n        uid_detail uiddetail(symbol_, record.target);\n        auto ass = uid(UID_DETAIL_TYPE, uiddetail);\n        if (!ass.is_valid())\n        {\n            throw tx_asset_value_exception{\"invalid uid register asset\"};\n        }\n        return asset(UID_TYPE, attach_version, ass);\n    }\n    else if (record.type == utxo_attach_type::uid_transfer)\n    {\n        auto sh_uid = blockchain_.get_registered_uid(symbol_);\n        if (!sh_uid)\n            throw uid_symbol_notfound_exception{symbol_ + \" not found\"};\n\n        sh_uid->set_address(record.target);\n        auto ass = uid(UID_TRANSFERABLE_TYPE, *sh_uid);\n        if (!ass.is_valid())\n        {\n            throw tx_asset_value_exception{\"invalid uid transfer asset\"};\n        }\n        return asset(UID_TYPE, attach_version, ass);\n    }\n    else if (record.type == utxo_attach_type::token_cert || record.type == utxo_attach_type::token_cert_autoissue || record.type == utxo_attach_type::token_cert_issue || record.type == utxo_attach_type::token_cert_transfer)\n    {\n        if (record.token_cert == token_cert_ns::none)\n        {\n            throw token_cert_exception(\"token cert is none\");\n        }\n\n        auto to_uid = record.attach_elem.get_to_uid();\n        auto to_address = get_address_from_uid(to_uid, blockchain_);\n        if (to_address != record.target)\n        {\n            throw token_cert_exception(\"address \" + to_address + \" dismatch uid \" + to_uid);\n        }\n\n        auto cert_info = chain::token_cert(record.symbol, to_uid, to_address, record.token_cert);\n        if (record.type == utxo_attach_type::token_cert_issue)\n        {\n            cert_info.set_status(TOKEN_CERT_ISSUE_TYPE);\n        }\n        else if (record.type == utxo_attach_type::token_cert_transfer)\n        {\n            cert_info.set_status(TOKEN_CERT_TRANSFER_TYPE);\n        }\n        else if (record.type == utxo_attach_type::token_cert_autoissue)\n        {\n            cert_info.set_status(TOKEN_CERT_AUTOISSUE_TYPE);\n        }\n\n        if (!cert_info.is_valid())\n        {\n            throw tx_asset_value_exception{\"invalid cert asset\"};\n        }\n        return asset(TOKEN_CERT_TYPE, attach_version, cert_info);\n    }\n    else if (record.type == utxo_attach_type::candidate || record.type == utxo_attach_type::candidate_transfer)\n    {\n        return asset(TOKEN_CANDIDATE_TYPE, attach_version, candidate(/*set on subclass*/));\n    }\n\n    throw tx_asset_value_exception{\n        \"invalid utxo_attach_type value in receiver_record : \" + std::to_string((uint32_t)record.type)};\n}\n\nbool base_transfer_common::filter_out_address(const std::string &address) const\n{\n    return blockchain_.is_script_address(address);\n}\n\nvoid base_transfer_helper::populate_unspent_list()\n{\n    // get address list\n    auto pvaddr = blockchain_.get_wallet_addresses(name_);\n    if (!pvaddr)\n    {\n        throw address_list_nullptr_exception{\"nullptr for address list\"};\n    }\n\n    if (!from_.empty() && filter_out_address(from_))\n    {\n        throw tx_source_exception{\"from address cannot be multi-signed. \"};\n    }\n\n    // get from address balances\n    for (auto &each : *pvaddr)\n    {\n        const auto &address = each.get_address();\n        // filter script address\n        if (filter_out_address(address))\n        {\n            continue;\n        }\n\n        const auto priv_key = each.get_prv_key(passwd_);\n\n        if (from_.empty())\n        {\n            sync_fetchutxo(priv_key, address);\n        }\n        else if (from_ == address)\n        {\n            sync_fetchutxo(priv_key, address);\n            // select ucn/token utxo only in from_ address\n            check_payment_satisfied(FILTER_PAYFROM);\n        }\n        else\n        {\n            sync_fetchutxo(priv_key, address, FILTER_ALL_BUT_PAYFROM);\n        }\n\n        // performance improve\n        if (is_payment_satisfied())\n        {\n            break;\n        }\n    }\n\n    //vote specify\n    if (from_list_.empty() && symbol_ != UC_VOTE_TOKEN_SYMBOL)\n    {\n        throw tx_source_exception{\"not enough ucn or token in from address\"\n                                  \", or you do not own the from address!(multisig address balance cannot be used in this way)\"};\n    }\n\n    check_payment_satisfied();\n\n    populate_change();\n}\n\nbool receiver_record::is_empty() const\n{\n    // has ucn amount\n    if (amount != 0)\n    {\n        return false;\n    }\n\n    // ucn business , ucn == 0\n    if ((type == utxo_attach_type::ucn) ||\n        (type == utxo_attach_type::deposit))\n    {\n        return true;\n    }\n\n    // has token amount\n    if (token_amount != 0)\n    {\n        return false;\n    }\n\n    // token transfer business, ucn == 0 && token_amount == 0\n    if ((type == utxo_attach_type::token_transfer) ||\n        (type == utxo_attach_type::token_locked_transfer))\n    {\n        return true;\n    }\n\n    // other business\n    return false;\n}\n\nvoid base_transfer_common::check_tx()\n{\n    if (tx_.is_locktime_conflict())\n    {\n        throw tx_locktime_exception{\"The specified lock time is ineffective because all sequences\"\n                                    \" are set to the maximum value.\"};\n    }\n\n    if (tx_.inputs.empty())\n    {\n        throw tx_validate_exception{\"validate transaction failure, empty inputs.\"};\n    }\n\n    if (tx_.outputs.empty())\n    {\n        throw tx_validate_exception{\"validate transaction failure, empty outputs.\"};\n    }\n}\n\nstd::string base_transfer_common::get_sign_tx_multisig_script(const address_token_record &from) const\n{\n    return \"\";\n}\n\nvoid base_transfer_common::sign_tx_inputs()\n{\n    uint32_t index = 0;\n    for (auto &fromeach : from_list_)\n    {\n        bc::chain::script ss;\n\n        // paramaters\n        explorer::config::hashtype sign_type;\n        uint8_t hash_type = (signature_hash_algorithm)sign_type;\n\n        bc::explorer::config::ec_private config_private_key(fromeach.prikey);\n        const ec_secret &private_key = config_private_key;\n\n        std::string multisig_script = get_sign_tx_multisig_script(fromeach);\n        if (!multisig_script.empty())\n        {\n            bc::explorer::config::script config_contract(multisig_script);\n            const bc::chain::script &contract = config_contract;\n\n            // gen sign\n            bc::endorsement endorse;\n            if (!bc::chain::script::create_endorsement(endorse, private_key,\n                                                       contract, tx_, index, hash_type))\n            {\n                throw tx_sign_exception{\"get_input_sign sign failure\"};\n            }\n\n            // do script\n            data_chunk data;\n            ss.operations.push_back({bc::chain::opcode::zero, data});\n            ss.operations.push_back({bc::chain::opcode::special, endorse});\n\n            chain::script script_encoded;\n            script_encoded.from_string(multisig_script);\n\n            ss.operations.push_back({bc::chain::opcode::pushdata1, script_encoded.to_data(false)});\n        }\n        else\n        {\n            bc::explorer::config::script config_contract(fromeach.script);\n            const bc::chain::script &contract = config_contract;\n\n            // gen sign\n            bc::endorsement endorse;\n            if (!bc::chain::script::create_endorsement(endorse, private_key,\n                                                       contract, tx_, index, hash_type))\n            {\n                throw tx_sign_exception{\"get_input_sign sign failure\"};\n            }\n\n            // do script\n            bc::wallet::ec_private ec_private_key(private_key, 0u, true);\n            auto &&public_key = ec_private_key.to_public();\n            data_chunk public_key_data;\n            public_key.to_data(public_key_data);\n\n            ss.operations.push_back({bc::chain::opcode::special, endorse});\n            ss.operations.push_back({bc::chain::opcode::special, public_key_data});\n\n            // if pre-output script is deposit tx.\n            if (contract.pattern() == bc::chain::script_pattern::pay_key_hash_with_lock_height)\n            {\n                uint64_t lock_height = chain::operation::get_lock_height_from_pay_key_hash_with_lock_height(\n                    contract.operations);\n                ss.operations.push_back({bc::chain::opcode::special, script_number(lock_height).data()});\n            }\n        }\n\n        // set input script of this tx\n        tx_.inputs[index].script = ss;\n        index++;\n    }\n}\n\nvoid base_transfer_common::send_tx()\n{\n    if (blockchain_.validate_tx_engine(tx_))\n    {\n#ifdef UC_DEBUG\n        throw tx_validate_exception{\"validate transaction failure. \" + tx_.to_string(1)};\n#endif\n        throw tx_validate_exception{\"validate transaction failure\"};\n    }\n    if (blockchain_.broadcast_transaction(tx_))\n        throw tx_broadcast_exception{\"broadcast transaction failure\"};\n}\n\nvoid base_transfer_common::populate_tx_header()\n{\n    tx_.locktime = 0;\n    if (validate_tx_engine::is_uid_feature_activated(blockchain_))\n    {\n        tx_.version = transaction_version::check_uid_feature;\n    }\n    else\n    {\n        tx_.version = transaction_version::check_output_script;\n    }\n}\n\nvoid base_transfer_common::exec()\n{\n    // prepare\n    sum_payment_amount();\n    populate_unspent_list();\n\n    // construct tx\n    populate_tx_header();\n    populate_tx_inputs();\n    populate_tx_outputs();\n\n    // check tx\n    check_tx();\n\n    // sign tx\n    sign_tx_inputs();\n\n    // send tx\n    send_tx();\n}\n\nvoid base_multisig_transfer_helper::send_tx()\n{\n    auto from_address = multisig_.get_address();\n    if (from_address.empty())\n    {\n        base_transfer_common::send_tx();\n    }\n    else\n    {\n        // no operation in exec for transferring multisig token cert\n    }\n}\n\nbool base_multisig_transfer_helper::filter_out_address(const std::string &address) const\n{\n    auto multisig_address = multisig_.get_address();\n    if (multisig_address.empty())\n    {\n        return base_transfer_common::filter_out_address(address);\n    }\n    else\n    {\n        return address != multisig_address;\n    }\n}\n\nstd::string base_multisig_transfer_helper::get_sign_tx_multisig_script(const address_token_record &from) const\n{\n    return multisig_.get_multisig_script();\n}\n\nvoid base_transaction_constructor::sum_payment_amount()\n{\n    base_transfer_common::sum_payment_amount();\n    if (from_vec_.empty())\n    {\n        throw fromaddress_empty_exception{\"empty from address\"};\n    }\n}\n\nvoid base_transaction_constructor::populate_change()\n{\n    // ucn utxo\n    populate_ucn_change();\n\n    // token utxo\n    populate_token_change();\n\n    if (!message_.empty())\n    { // ucn transfer/token transfer  -- with message\n        auto addr = !mychange_.empty() ? mychange_ : from_list_.begin()->addr;\n        receiver_list_.push_back({addr, \"\", 0, 0,\n                                  utxo_attach_type::message,\n                                  asset(0, 0, blockchain_message(message_))});\n    }\n}\n\nvoid base_transaction_constructor::populate_unspent_list()\n{\n    // get from address balances\n    for (auto &each : from_vec_)\n    {\n        sync_fetchutxo(\"\", each);\n        if (is_payment_satisfied())\n        {\n            break;\n        }\n    }\n\n    if (from_list_.empty())\n    {\n        throw tx_source_exception{\"not enough ucn or token in the from address!\"};\n    }\n\n    check_payment_satisfied();\n\n    // change\n    populate_change();\n}\n\nconst std::vector<uint16_t> depositing_ucn::vec_cycle{10, 45, 120, 240, 540};\n\nuint32_t depositing_ucn::get_reward_lock_height() const\n{\n    int index = 0;\n    auto it = std::find(vec_cycle.begin(), vec_cycle.end(), deposit_cycle_);\n    if (it != vec_cycle.end())\n    { // found cycle\n        index = std::distance(vec_cycle.begin(), it);\n    }\n\n    return (uint32_t)bc::consensus::lock_heights[index];\n}\n\nchain::operation::stack\ndepositing_ucn::get_script_operations(const receiver_record &record) const\n{\n    chain::operation::stack payment_ops;\n\n    // complicated script and token should be implemented in subclass\n    // generate script\n    const bc::wallet::payment_address payment(record.target);\n    if (!payment)\n        throw toaddress_invalid_exception{\"invalid target address\"};\n\n    if (payment.version() == bc::wallet::payment_address::mainnet_p2kh)\n    {\n        const auto &hash = payment.hash();\n        if ((from_ == record.target) && (utxo_attach_type::deposit == record.type))\n        {\n            payment_ops = chain::operation::to_pay_key_hash_with_lock_height_pattern(hash, get_reward_lock_height());\n        }\n        else\n        {\n            payment_ops = chain::operation::to_pay_key_hash_pattern(hash); // common payment script\n        }\n    }\n    else\n    {\n        throw toaddress_invalid_exception{std::string(\"not supported version target address \") + record.target};\n    }\n\n    return payment_ops;\n}\n\nconst std::vector<uint16_t> depositing_ucn_transaction::vec_cycle{10, 45, 120, 240, 540};\n\nuint32_t depositing_ucn_transaction::get_reward_lock_height() const\n{\n    int index = 0;\n    auto it = std::find(vec_cycle.begin(), vec_cycle.end(), deposit_);\n    if (it != vec_cycle.end())\n    { // found cycle\n        index = std::distance(vec_cycle.begin(), it);\n    }\n\n    return (uint32_t)bc::consensus::lock_heights[index];\n}\n\nchain::operation::stack\ndepositing_ucn_transaction::get_script_operations(const receiver_record &record) const\n{\n    chain::operation::stack payment_ops;\n\n    // complicated script and token should be implemented in subclass\n    // generate script\n    const bc::wallet::payment_address payment(record.target);\n    if (!payment)\n        throw toaddress_invalid_exception{\"invalid target address\"};\n\n    if (payment.version() == bc::wallet::payment_address::mainnet_p2kh)\n    {\n        const auto &hash = payment.hash();\n        if ((utxo_attach_type::deposit == record.type))\n        {\n            payment_ops = chain::operation::to_pay_key_hash_with_lock_height_pattern(\n                hash, get_reward_lock_height());\n        }\n        else\n        {\n            payment_ops = chain::operation::to_pay_key_hash_pattern(hash); // common payment script\n        }\n    }\n    else\n    {\n        throw toaddress_invalid_exception{std::string(\"not supported version target address \") + record.target};\n    }\n\n    return payment_ops;\n}\n\nuint32_t voting_token::get_reward_lock_height() const\n{\n    return 48 * 60 * 60 * 2; //48h\n}\n\nchain::operation::stack\nvoting_token::get_script_operations(const receiver_record &record) const\n{\n    chain::operation::stack payment_ops;\n\n    // complicated script and token should be implemented in subclass\n    // generate script\n    const bc::wallet::payment_address payment(record.target);\n    if (!payment)\n        throw toaddress_invalid_exception{\"invalid target address\"};\n    if (blockchain_.is_blackhole_address(record.target))\n    {\n        payment_ops = chain::operation::to_pay_blackhole_pattern(payment.hash());\n    }\n    else if (payment.version() == wallet::payment_address::mainnet_p2kh)\n    {\n        const auto &hash = payment.hash();\n        if ((from_ == record.target) && (utxo_attach_type::deposit == record.type))\n        {\n            payment_ops = chain::operation::to_pay_key_hash_with_lock_height_pattern(hash, get_reward_lock_height());\n        }\n        else\n        {\n            payment_ops = chain::operation::to_pay_key_hash_pattern(hash); // common payment script\n        }\n    }\n    else\n    {\n        throw toaddress_invalid_exception{std::string(\"not supported version target address \") + record.target};\n    }\n\n    return payment_ops;\n}\n\nuint32_t registering_candidate::get_reward_lock_height() const\n{\n    return 240 * 24 * 60 * 60 * 2; //48h\n}\n\nchain::operation::stack\nregistering_candidate::get_script_operations(const receiver_record &record) const\n{\n    chain::operation::stack payment_ops;\n\n    // complicated script and token should be implemented in subclass\n    // generate script\n    const bc::wallet::payment_address payment(record.target);\n    if (!payment)\n        throw toaddress_invalid_exception{\"invalid target address\"};\n\n    if (payment.version() == bc::wallet::payment_address::mainnet_p2kh)\n    {\n        const auto &hash = payment.hash();\n        if ((from_ == record.target) && (utxo_attach_type::deposit == record.type))\n        {\n            payment_ops = chain::operation::to_pay_key_hash_with_lock_height_pattern(hash, get_reward_lock_height());\n        }\n        else\n        {\n            payment_ops = chain::operation::to_pay_key_hash_pattern(hash); // common payment script\n        }\n    }\n    else\n    {\n        throw toaddress_invalid_exception{std::string(\"not supported version target address \") + record.target};\n    }\n\n    return payment_ops;\n}\n\nvoid sending_multisig_tx::populate_change()\n{\n    // ucn utxo\n    populate_ucn_change();\n\n    // token utxo\n    populate_token_change();\n}\n\nvoid issuing_token::sum_payments()\n{\n    for (auto &iter : receiver_list_)\n    {\n        payment_ucn_ += iter.amount;\n        payment_token_ += iter.token_amount;\n\n        if (iter.token_cert == token_cert_ns::domain)\n        {\n            auto &&domain = token_cert::get_domain(symbol_);\n            if (!token_cert::is_valid_domain(domain))\n            {\n                throw token_cert_domain_exception{\"no valid domain exists for token : \" + symbol_};\n            }\n            if (blockchain_.is_token_cert_exist(domain, token_cert_ns::domain))\n            {\n                payment_token_cert_.clear();\n                payment_token_cert_.push_back(token_cert_ns::domain); // will verify by input\n            }\n        }\n        else if (iter.token_cert == token_cert_ns::naming)\n        {\n            auto &&domain = token_cert::get_domain(symbol_);\n            if (!token_cert::is_valid_domain(domain))\n            {\n                throw token_cert_domain_exception{\"no valid domain exists for token : \" + symbol_};\n            }\n\n            if (blockchain_.is_token_cert_exist(symbol_, token_cert_ns::naming))\n            {\n                payment_token_cert_.clear();\n                payment_token_cert_.push_back(token_cert_ns::naming); // will verify by input\n            }\n            else\n            {\n                throw token_cert_notfound_exception{\"no naming cert exists for token : \" + symbol_};\n            }\n        }\n    }\n}\n\nvoid issuing_token::sum_payment_amount()\n{\n    base_transfer_common::sum_payment_amount();\n\n    unissued_token_ = blockchain_.get_wallet_unissued_token(name_, symbol_);\n    if (!unissued_token_)\n    {\n        throw token_symbol_notfound_exception{symbol_ + \" not created\"};\n    }\n\n    uint64_t min_fee = bc::min_fee_to_issue_token;\n    if (payment_ucn_ < min_fee)\n    {\n        throw token_issue_poundage_exception(\"fee must at least \" + std::to_string(min_fee) + \" satoshi == \" + std::to_string(min_fee / 100000000) + \" ucn\");\n    }\n\n    if (!attenuation_model_param_.empty())\n    {\n        check_model_param_initial(attenuation_model_param_, unissued_token_->get_maximum_supply());\n    }\n\n    uint64_t amount = (uint64_t)std::floor(payment_ucn_ * ((100 - fee_percentage_to_miner_) / 100.0));\n    if (amount > 0)\n    {\n        auto &&address = bc::get_developer_community_address(blockchain_.chain_settings().use_testnet_rules);\n        auto &&uid = blockchain_.get_uid_from_address(address);\n        receiver_list_.push_back({address, \"\", amount, 0, utxo_attach_type::ucn, asset(\"\", uid)});\n    }\n}\n\nchain::operation::stack\nissuing_token::get_script_operations(const receiver_record &record) const\n{\n    if (!attenuation_model_param_.empty() && (utxo_attach_type::token_issue == record.type))\n    {\n        return get_pay_key_hash_with_attenuation_model_operations(attenuation_model_param_, record);\n    }\n\n    return base_transfer_helper::get_script_operations(record);\n}\n\nasset issuing_token::populate_output_asset(const receiver_record &record)\n{\n    asset &&attach = base_transfer_common::populate_output_asset(record);\n\n    if (record.type == utxo_attach_type::token_issue)\n    {\n        unissued_token_->set_address(record.target);\n        auto ass = token(TOKEN_DETAIL_TYPE, *unissued_token_);\n        if (!ass.is_valid())\n        {\n            throw tx_asset_value_exception{\"invalid token issue asset\"};\n        }\n\n        attach.set_attach(ass);\n    }\n\n    return attach;\n}\n\nvoid sending_token::sum_payment_amount()\n{\n    base_transfer_common::sum_payment_amount();\n\n    if (!attenuation_model_param_.empty())\n    {\n        check_model_param_initial(attenuation_model_param_, payment_token_);\n    }\n}\n\nvoid sending_token::populate_change()\n{\n    // ucn utxo\n    populate_ucn_change();\n\n    // token utxo\n    populate_token_change();\n\n    // token transfer  -- with message\n    if (!message_.empty())\n    {\n        auto addr = !mychange_.empty() ? mychange_ : from_list_.begin()->addr;\n        receiver_list_.push_back({addr, \"\", 0, 0,\n                                  utxo_attach_type::message,\n                                  asset(0, 0, blockchain_message(message_))});\n    }\n}\n\nchain::operation::stack\nsending_token::get_script_operations(const receiver_record &record) const\n{\n    if (!attenuation_model_param_.empty() && (utxo_attach_type::token_attenuation_transfer == record.type))\n    { // for sending token only\n        return get_pay_key_hash_with_attenuation_model_operations(attenuation_model_param_, record);\n    }\n\n    return base_transfer_helper::get_script_operations(record);\n}\n\nchain::operation::stack\nsecondary_issuing_token::get_script_operations(const receiver_record &record) const\n{\n    if (!attenuation_model_param_.empty() && (utxo_attach_type::token_secondaryissue == record.type))\n    {\n        return get_pay_key_hash_with_attenuation_model_operations(attenuation_model_param_, record);\n    }\n\n    return base_transfer_helper::get_script_operations(record);\n}\n\nvoid secondary_issuing_token::sum_payment_amount()\n{\n    base_transfer_common::sum_payment_amount();\n\n    target_address_ = receiver_list_.begin()->target;\n\n    issued_token_ = blockchain_.get_issued_token(symbol_);\n    if (!issued_token_)\n    {\n        throw token_symbol_notfound_exception{\"token symbol does not exist on the blockchain\"};\n    }\n\n    auto total_volume = blockchain_.get_token_volume(symbol_);\n    if (total_volume > max_uint64 - volume_)\n    {\n        throw token_amount_exception{\"secondaryissue, volume cannot exceed maximum value\"};\n    }\n\n    if (!token_cert::test_certs(payment_token_cert_, token_cert_ns::issue))\n    {\n        throw token_cert_exception(\"no token cert of issue right is provided.\");\n    }\n\n    if (blockchain_.chain_settings().use_testnet_rules && !blockchain_.is_token_cert_exist(symbol_, token_cert_ns::issue))\n    {\n        payment_token_cert_.clear();\n    }\n\n    if (!attenuation_model_param_.empty())\n    {\n        check_model_param_initial(attenuation_model_param_, volume_);\n    }\n}\n\nvoid secondary_issuing_token::populate_change()\n{\n    // ucn utxo\n    populate_ucn_change();\n\n    // token utxo\n    if (payment_token_ > 0)\n    {\n        receiver_list_.push_back({target_address_, symbol_,\n                                  0, payment_token_,\n                                  utxo_attach_type::token_transfer, asset()});\n    }\n    populate_token_change(target_address_);\n}\n\nasset secondary_issuing_token::populate_output_asset(const receiver_record &record)\n{\n    auto &&attach = base_transfer_common::populate_output_asset(record);\n\n    if (record.type == utxo_attach_type::token_secondaryissue)\n    {\n        auto token_detail = *issued_token_;\n        token_detail.set_address(record.target);\n        token_detail.set_token_secondaryissue();\n        token_detail.set_maximum_supply(volume_);\n        token_detail.set_issuer(record.attach_elem.get_to_uid());\n        auto ass = token(TOKEN_DETAIL_TYPE, token_detail);\n        if (!ass.is_valid())\n        {\n            throw tx_asset_value_exception{\"invalid token secondary issue asset\"};\n        }\n\n        attach.set_attach(ass);\n    }\n\n    return attach;\n}\n\nvoid issuing_token_cert::sum_payment_amount()\n{\n    base_transfer_common::sum_payment_amount();\n\n    if (token_cert::test_certs(payment_token_cert_, token_cert_ns::naming))\n    {\n        if (!token_cert::test_certs(payment_token_cert_, token_cert_ns::domain))\n        {\n            throw token_cert_exception(\"no token cert of domain right.\");\n        }\n\n        payment_token_cert_.clear();\n        payment_token_cert_.push_back(token_cert_ns::domain);\n    }\n    else\n    {\n        payment_token_cert_.clear();\n    }\n}\n\nvoid registering_uid::sum_payment_amount()\n{\n    base_transfer_common::sum_payment_amount();\n\n    uint64_t min_fee = bc::min_fee_to_register_uid;\n    if (payment_ucn_ < min_fee)\n    {\n        throw uid_register_poundage_exception(\"fee must at least \" + std::to_string(min_fee) + \" satoshi == \" + std::to_string(min_fee / 100000000) + \" ucn\");\n    }\n\n    uint64_t amount = (uint64_t)std::floor(payment_ucn_ * ((100 - fee_percentage_to_miner_) / 100.0));\n    if (amount > 0)\n    {\n        auto &&address = bc::get_developer_community_address(blockchain_.chain_settings().use_testnet_rules);\n        auto &&uid = blockchain_.get_uid_from_address(address);\n        receiver_list_.push_back({address, \"\", amount, 0, utxo_attach_type::ucn, asset(\"\", uid)});\n    }\n}\n\nstd::string sending_multisig_uid::get_sign_tx_multisig_script(const address_token_record &from) const\n{\n    std::string multisig_script;\n    if (from.addr == multisig_from_.get_address())\n    {\n        multisig_script = multisig_from_.get_multisig_script();\n    }\n    else if (from.addr == multisig_to_.get_address())\n    {\n        multisig_script = multisig_to_.get_multisig_script();\n    }\n    return multisig_script;\n}\n\nvoid sending_multisig_uid::sum_payment_amount()\n{\n    base_transfer_common::sum_payment_amount();\n    if (fromfee.empty())\n    {\n        throw fromaddress_empty_exception{\"empty fromfee address\"};\n    }\n}\n\nvoid sending_multisig_uid::populate_change()\n{\n    // ucn utxo\n    populate_ucn_change(fromfee);\n}\n\nvoid sending_multisig_uid::populate_unspent_list()\n{\n    // get address list\n    auto pvaddr = blockchain_.get_wallet_addresses(name_);\n    if (!pvaddr)\n    {\n        throw address_list_nullptr_exception{\"nullptr for address list\"};\n    }\n\n    // get from address balances\n    for (auto &each : *pvaddr)\n    {\n\n        if (fromfee == each.get_address())\n        {\n            // pay fee\n            sync_fetchutxo(each.get_prv_key(passwd_), each.get_address(), FILTER_UCN);\n            check_payment_satisfied(FILTER_UCN);\n        }\n\n        if (from_ == each.get_address())\n        {\n            // pay uid\n            sync_fetchutxo(each.get_prv_key(passwd_), each.get_address(), FILTER_UID);\n            check_payment_satisfied(FILTER_UID);\n        }\n\n        if (is_payment_satisfied())\n        {\n            break;\n        }\n    }\n\n    if (from_list_.empty())\n    {\n        throw tx_source_exception{\"not enough ucn or token in from address\"\n                                  \", or you do not own the from address!\"};\n    }\n\n    check_payment_satisfied();\n\n    populate_change();\n}\n\nvoid sending_uid::sum_payment_amount()\n{\n    base_transfer_common::sum_payment_amount();\n    if (fromfee.empty())\n    {\n        throw fromaddress_empty_exception{\"empty fromfee address\"};\n    }\n}\n\nvoid sending_uid::populate_change()\n{\n    // ucn utxo\n    populate_ucn_change(fromfee);\n}\n\nvoid sending_uid::populate_unspent_list()\n{\n    // get address list\n    auto pvaddr = blockchain_.get_wallet_addresses(name_);\n    if (!pvaddr)\n    {\n        throw address_list_nullptr_exception{\"nullptr for address list\"};\n    }\n\n    // get from address balances\n    for (auto &each : *pvaddr)\n    {\n        // filter script address\n        if (blockchain_.is_script_address(each.get_address()))\n            continue;\n\n        if (fromfee == each.get_address())\n        {\n            // pay fee\n            sync_fetchutxo(each.get_prv_key(passwd_), each.get_address(), FILTER_UCN);\n            check_payment_satisfied(FILTER_UCN);\n        }\n\n        if (from_ == each.get_address())\n        {\n            // pay uid\n            sync_fetchutxo(each.get_prv_key(passwd_), each.get_address(), FILTER_UID);\n            check_payment_satisfied(FILTER_UID);\n        }\n\n        if (is_payment_satisfied())\n        {\n            break;\n        }\n    }\n\n    if (from_list_.empty())\n    {\n        throw tx_source_exception{\"not enough ucn or token in from address\"\n                                  \", or you do not own the from address!\"};\n    }\n\n    check_payment_satisfied();\n\n    populate_change();\n}\n\nasset registering_candidate::populate_output_asset(const receiver_record &record)\n{\n    auto &&attach = base_transfer_common::populate_output_asset(record);\n\n    if (record.type == utxo_attach_type::candidate)\n    {\n        auto iter = candidate_map_.find(record.symbol);\n        if (iter == candidate_map_.end())\n        {\n            throw tx_asset_value_exception{\"invalid candidate issue asset\"};\n        }\n\n        auto ass = candidate(record.symbol, record.target, iter->second);\n        ass.set_status(CANDIDATE_STATUS_REGISTER);\n        if (!ass.is_valid())\n        {\n            throw tx_asset_value_exception{\"invalid candidate issue asset\"};\n        }\n\n        attach.set_attach(ass);\n    }\n\n    return attach;\n}\n\nasset transferring_candidate::populate_output_asset(const receiver_record &record)\n{\n    auto &&attach = base_transfer_common::populate_output_asset(record);\n\n    if (record.type == utxo_attach_type::candidate_transfer)\n    {\n        auto ass = candidate(record.symbol, record.target, \"\");\n        ass.set_status(CANDIDATE_STATUS_TRANSFER);\n        if (!ass.is_valid())\n        {\n            throw tx_asset_value_exception{\"invalid candidate transfer asset\"};\n        }\n\n        attach.set_attach(ass);\n    }\n\n    return attach;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/command_assistant.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n// ---------------------------------------------------------------------------\nstd::string ec_to_xxx_impl(const std::string &cmd, const std::string &fromkey)\n{\n    if (cmd == \"ec-to-public\")\n    {\n\n        explorer::config::ec_private secret{fromkey};\n        ec_compressed point;\n        bc::secret_to_public(point, secret);\n        bc::wallet::ec_public ec_pubkey(point, true); // compressed for UC always\n\n        return ec_pubkey.encoded();\n    }\n\n    if (cmd == \"ec-to-address\")\n    {\n\n        bc::wallet::ec_public point{fromkey};\n        bc::wallet::payment_address pay_addr(point, bc::wallet::payment_address::mainnet_p2kh);\n\n        return pay_addr.encoded();\n    }\n\n    return \"\";\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/command_extension_func.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <functional>\n#include <memory>\n#include <string>\n#include <array>\n\n#include <UChain/explorer/command.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/command_extension.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/commands/shutdown.hpp>\n#include <UChainService/api/command/commands/stopmining.hpp>\n#include <UChainService/api/command/commands/startmining.hpp>\n#include <UChainService/api/command/commands/showinfo.hpp>\n#include <UChainService/api/command/commands/showblockheight.hpp>\n#include <UChainService/api/command/commands/showpeers.hpp>\n#include <UChainService/api/command/commands/showaddressucn.hpp>\n#include <UChainService/api/command/commands/addpeer.hpp>\n#include <UChainService/api/command/commands/showmininginfo.hpp>\n#include <UChainService/api/command/commands/showblockheader.hpp>\n#include <UChainService/api/command/commands/showblockheaders.hpp>\n#include <UChainService/api/command/commands/showheaderext.hpp>\n#include <UChainService/api/command/commands/showtx.hpp>\n#include <UChainService/api/command/commands/exportkeyfile.hpp>\n#include <UChainService/api/command/commands/importkeyfile.hpp>\n#include <UChainService/api/command/commands/importwallet.hpp>\n#include <UChainService/api/command/commands/createwallet.hpp>\n#include <UChainService/api/command/commands/checkwalletinfo.hpp>\n#include <UChainService/api/command/commands/deletewallet.hpp>\n#include <UChainService/api/command/commands/showaddresses.hpp>\n#include <UChainService/api/command/commands/showminers.hpp>\n#include <UChainService/api/command/commands/addaddress.hpp>\n#include <UChainService/api/command/commands/showblock.hpp>\n#include <UChainService/api/command/commands/validateaddress.hpp>\n#include <UChainService/api/command/commands/showbalances.hpp>\n#include <UChainService/api/command/commands/showbalance.hpp>\n#include <UChainService/api/command/commands/showtxs.hpp>\n#include <UChainService/api/command/commands/deposit.hpp>\n#include <UChainService/api/command/commands/showtokens.hpp>\n#include <UChainService/api/command/commands/showtoken.hpp>\n#include <UChainService/api/command/commands/registersecondarytoken.hpp>\n#include <UChainService/api/command/commands/showaddresstoken.hpp>\n#include <UChainService/api/command/commands/showwallettoken.hpp>\n#include <UChainService/api/command/commands/showtokenview.hpp>\n#include <UChainService/api/command/commands/createtoken.hpp>\n#include <UChainService/api/command/commands/registercandidate.hpp>\n#include <UChainService/api/command/commands/transfercandidate.hpp>\n#include <UChainService/api/command/commands/showcandidates.hpp>\n#include <UChainService/api/command/commands/showcandidate.hpp>\n#include <UChainService/api/command/commands/registeruid.hpp>\n#include <UChainService/api/command/commands/sendto.hpp>\n#include <UChainService/api/command/commands/sendfrom.hpp>\n#include <UChainService/api/command/commands/sendtomulti.hpp>\n#include <UChainService/api/command/commands/sendtokento.hpp>\n#include <UChainService/api/command/commands/sendtokenfrom.hpp>\n#include <UChainService/api/command/commands/swaptoken.hpp>\n#include <UChainService/api/command/commands/vote.hpp>\n#include <UChainService/api/command/commands/showuids.hpp>\n#include <UChainService/api/command/commands/deletetoken.hpp>\n#include <UChainService/api/command/commands/registertoken.hpp>\n#include <UChainService/api/command/commands/destroy.hpp>\n#include <UChainService/api/command/commands/transfercert.hpp>\n#include <UChainService/api/command/commands/registercert.hpp>\n#include <UChainService/api/command/commands/showwork.hpp>\n#include <UChainService/api/command/commands/submitwork.hpp>\n#include <UChainService/api/command/commands/setminingwallet.hpp>\n#include <UChainService/api/command/commands/changepass.hpp>\n#include <UChainService/api/command/commands/showtxpool.hpp>\n#include <UChainService/api/command/commands/createmultisigtx.hpp>\n#include <UChainService/api/command/commands/createrawtx.hpp>\n#include <UChainService/api/command/commands/decoderawtx.hpp>\n#include <UChainService/api/command/commands/deletemultisigaddress.hpp>\n#include <UChainService/api/command/commands/createmultisigaddress.hpp>\n#include <UChainService/api/command/commands/checkpublickey.hpp>\n#include <UChainService/api/command/commands/showmultisigaddresses.hpp>\n#include <UChainService/api/command/commands/sendrawtx.hpp>\n#include <UChainService/api/command/commands/signmultisigtx.hpp>\n#include <UChainService/api/command/commands/signrawtx.hpp>\n#include <UChainService/api/command/commands/transferuid.hpp>\n#include <UChainService/api/command/commands/showuid.hpp>\n#include <UChainService/api/command/commands/showvote.hpp>\n#include <UChain/explorer/commands/send-tx.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\n\nvoid broadcast_extension(const function<void(shared_ptr<command>)> func, std::ostream &os)\n{\n    using namespace std;\n    using namespace commands;\n\n    os << \"uc-cli:\\r\\n\";\n    os << \"  -c <uc.config path>\\r\\n\";\n\n    os << \"system:\\r\\n\";\n    // system\n    func(make_shared<shutdown>());\n    func(make_shared<showinfo>());\n    func(make_shared<addpeer>());\n    func(make_shared<showpeers>());\n\n    os << \"wallet:\\r\\n\";\n    // wallet\n    func(make_shared<createwallet>());\n    func(make_shared<checkwalletinfo>());\n    func(make_shared<deletewallet>());\n    func(make_shared<importwallet>());\n    func(make_shared<changepass>());\n    func(make_shared<addaddress>());\n    func(make_shared<validateaddress>());\n    func(make_shared<showaddresses>());\n    func(make_shared<exportkeyfile>());\n    func(make_shared<importkeyfile>());\n\n    // ucn\n    os << \"ucn:\\r\\n\";\n    func(make_shared<sendto>());\n    func(make_shared<sendtomulti>());\n    func(make_shared<sendfrom>());\n    func(make_shared<deposit>());\n    func(make_shared<showbalances>());\n    func(make_shared<showbalance>());\n    func(make_shared<showaddressucn>());\n\n    os << \"miming:\\r\\n\";\n    // miming\n    func(make_shared<startmining>());\n    func(make_shared<stopmining>());\n    //func(make_shared<showmininginfo>());\n    //func(make_shared<setminingwallet>());\n    func(make_shared<showminers>());\n    //func(make_shared<showwork>());\n    //func(make_shared<submitwork>());\n\n    os << \"block & tx:\\r\\n\";\n    // block & tx\n    func(make_shared<showblockheight>());\n    func(make_shared<showblock>());\n    func(make_shared<showblockheader>());\n    func(make_shared<showblockheaders>());\n    func(make_shared<showheaderext>());\n    func(make_shared<showtxpool>());\n    func(make_shared<showtx>());\n    func(make_shared<showtxs>());\n\n    // token\n    os << \"token:\\r\\n\";\n    func(make_shared<createtoken>());\n    func(make_shared<deletetoken>());\n    func(make_shared<registertoken>());\n    /*func(make_shared<registersecondarytoken>());*/\n    func(make_shared<sendtokento>());\n    func(make_shared<sendtokenfrom>());\n    func(make_shared<showtokens>());\n    func(make_shared<showtoken>());\n    func(make_shared<showwallettoken>());\n    // func(make_shared<showtokenview>());\n    func(make_shared<showaddresstoken>());\n    func(make_shared<destroy>());\n    //func(make_shared<swaptoken>());\n    func(make_shared<vote>());\n    func(make_shared<showvote>());\n\n    // raw tx and multi-sig\n    os << \"raw tx and multi-sig:\\r\\n\";\n    func(make_shared<createrawtx>());\n    func(make_shared<decoderawtx>());\n    func(make_shared<signrawtx>());\n    func(make_shared<sendrawtx>());\n    func(make_shared<checkpublickey>());\n    func(make_shared<createmultisigtx>());\n    func(make_shared<createmultisigaddress>());\n    func(make_shared<showmultisigaddresses>());\n    func(make_shared<deletemultisigaddress>());\n    func(make_shared<signmultisigtx>());\n\n    //os <<\"\\r\\n\";\n    // cert\n    /*func(make_shared<registercert>());\n    func(make_shared<transfercert>());*/\n\n    os << \"uids:\\r\\n\";\n    //uid\n    func(make_shared<registeruid>());\n    func(make_shared<transferuid>());\n    func(make_shared<showuids>());\n    func(make_shared<showuid>());\n\n    os << \"candidates:\\r\\n\";\n    // candidate\n    func(make_shared<registercandidate>());\n    func(make_shared<transfercandidate>());\n    func(make_shared<showcandidates>());\n    func(make_shared<showcandidate>());\n}\n\nshared_ptr<command> find_extension(const string &symbol)\n{\n    using namespace std;\n    using namespace commands;\n\n    // wallet\n    if (symbol == createwallet::symbol())\n        return make_shared<createwallet>();\n    if (symbol == checkwalletinfo::symbol())\n        return make_shared<checkwalletinfo>();\n    if (symbol == deletewallet::symbol())\n        return make_shared<deletewallet>();\n    if (symbol == changepass::symbol())\n        return make_shared<changepass>();\n    if (symbol == validateaddress::symbol())\n        return make_shared<validateaddress>();\n    if (symbol == addaddress::symbol())\n        return make_shared<addaddress>();\n    if (symbol == showaddresses::symbol())\n        return make_shared<showaddresses>();\n    if (symbol == importwallet::symbol())\n        return make_shared<importwallet>();\n    if (symbol == exportkeyfile::symbol() || symbol == \"exportwalletasfile\")\n        return make_shared<exportkeyfile>();\n    if (symbol == importkeyfile::symbol() || symbol == \"importwalletfromfile\")\n        return make_shared<importkeyfile>();\n\n    // system\n    if (symbol == shutdown::symbol())\n        return make_shared<shutdown>();\n    if (symbol == showinfo::symbol())\n        return make_shared<showinfo>();\n    if (symbol == addpeer::symbol())\n        return make_shared<addpeer>();\n    if (symbol == showpeers::symbol())\n        return make_shared<showpeers>();\n\n    // mining\n    if (symbol == stopmining::symbol() || symbol == \"stop\")\n        return make_shared<stopmining>();\n    if (symbol == startmining::symbol() || symbol == \"start\")\n        return make_shared<startmining>();\n    /*if (symbol == setminingwallet::symbol())\n        return make_shared<setminingwallet>();\n    if (symbol == showmininginfo::symbol())\n        return make_shared<showmininginfo>();\n    if ((symbol == showwork::symbol()) || (symbol == \"eth_showwork\"))\n        return make_shared<showwork>();\n    if ((symbol == submitwork::symbol()) || ( symbol == \"eth_submitWork\"))\n        return make_shared<submitwork>();*/\n    if (symbol == showminers::symbol())\n        return make_shared<showminers>();\n\n    // block & tx\n    if (symbol == showblockheight::symbol())\n        return make_shared<showblockheight>();\n    if (symbol == \"fetch-height\")\n        return make_shared<showblockheight>(symbol);\n    if (symbol == showblock::symbol())\n        return make_shared<showblock>();\n    if (symbol == \"getbestblockhash\")\n        return make_shared<showblockheader>(symbol);\n    if (symbol == showblockheader::symbol() || symbol == \"fetch-header\" || symbol == \"getbestblockheader\")\n        return make_shared<showblockheader>();\n    if (symbol == showblockheaders::symbol())\n        return make_shared<showblockheaders>();\n    if (symbol == showheaderext::symbol())\n        return make_shared<showheaderext>();\n    if (symbol == showtxpool::symbol())\n        return make_shared<showtxpool>();\n    if (symbol == showtx::symbol() || symbol == \"gettransaction\")\n        return make_shared<showtx>();\n    if (symbol == \"fetch-tx\")\n        return make_shared<showtx>(symbol);\n    if (symbol == showtxs::symbol())\n        return make_shared<showtxs>();\n\n    // raw tx\n    if (symbol == createrawtx::symbol())\n        return make_shared<createrawtx>();\n    if (symbol == decoderawtx::symbol())\n        return make_shared<decoderawtx>();\n    if (symbol == signrawtx::symbol())\n        return make_shared<signrawtx>();\n    if (symbol == sendrawtx::symbol())\n        return make_shared<sendrawtx>();\n\n    // multi-sig\n    if (symbol == checkpublickey::symbol())\n        return make_shared<checkpublickey>();\n    if (symbol == createmultisigaddress::symbol())\n        return make_shared<createmultisigaddress>();\n    if (symbol == showmultisigaddresses::symbol())\n        return make_shared<showmultisigaddresses>();\n    if (symbol == deletemultisigaddress::symbol())\n        return make_shared<deletemultisigaddress>();\n    if (symbol == createmultisigtx::symbol())\n        return make_shared<createmultisigtx>();\n    if (symbol == signmultisigtx::symbol())\n        return make_shared<signmultisigtx>();\n\n    // ucn\n    if (symbol == showbalances::symbol())\n        return make_shared<showbalances>();\n    if (symbol == showbalance::symbol())\n        return make_shared<showbalance>();\n    if (symbol == showaddressucn::symbol() || symbol == \"fetch-balance\")\n        return make_shared<showaddressucn>();\n    if (symbol == deposit::symbol())\n        return make_shared<deposit>();\n    if (symbol == sendto::symbol() || symbol == \"uidsendto\")\n        return make_shared<sendto>();\n    if (symbol == sendtomulti::symbol() || symbol == \"uidsendtomulti\")\n        return make_shared<sendtomulti>();\n    if (symbol == sendfrom::symbol() || symbol == \"uidsendfrom\")\n        return make_shared<sendfrom>();\n\n    // token\n    if (symbol == createtoken::symbol())\n        return make_shared<createtoken>();\n    if (symbol == deletetoken::symbol() || symbol == \"deletetoken\")\n        return make_shared<deletetoken>();\n    if (symbol == showtokens::symbol())\n        return make_shared<showtokens>();\n    if (symbol == showtoken::symbol())\n        return make_shared<showtoken>();\n    if (symbol == showwallettoken::symbol())\n        return make_shared<showwallettoken>();\n    // if (symbol == showtokenview::symbol())\n    //     return make_shared<showtokenview>();\n    if (symbol == showaddresstoken::symbol())\n        return make_shared<showaddresstoken>();\n    if (symbol == registertoken::symbol())\n        return make_shared<registertoken>();\n    /*if (symbol == registersecondarytoken::symbol() || (symbol == \"additionalissue\") )\n        return make_shared<registersecondarytoken>();*/\n    if (symbol == sendtokento::symbol() || symbol == \"uidsendtokento\")\n        return make_shared<sendtokento>();\n    if (symbol == sendtokenfrom::symbol() || symbol == \"uidsendtokenfrom\")\n        return make_shared<sendtokenfrom>();\n    if (symbol == destroy::symbol())\n        return make_shared<destroy>();\n    /*if (symbol == swaptoken::symbol())\n        return make_shared<swaptoken>();*/\n    if (symbol == vote::symbol())\n        return make_shared<vote>();\n    if (symbol == showvote::symbol())\n        return make_shared<showvote>();\n\n    // cert\n    /*if (symbol == transfercert::symbol())\n        return make_shared<transfercert>();\n    if (symbol == registercert::symbol())\n        return make_shared<registercert>();*/\n\n    // candidate\n    if (symbol == registercandidate::symbol())\n        return make_shared<registercandidate>();\n    if (symbol == transfercandidate::symbol())\n        return make_shared<transfercandidate>();\n    if (symbol == showcandidates::symbol())\n        return make_shared<showcandidates>();\n    if (symbol == showcandidate::symbol())\n        return make_shared<showcandidate>();\n\n    // uid\n    if (symbol == registeruid::symbol())\n        return make_shared<registeruid>();\n    if (symbol == transferuid::symbol())\n        return make_shared<transferuid>();\n    if (symbol == showuids::symbol())\n        return make_shared<showuids>();\n    if (symbol == showuid::symbol())\n        return make_shared<showuid>();\n\n    return nullptr;\n}\n\nstd::string formerly_extension(const string &former)\n{\n    return \"\";\n}\n\nbool check_read_only(const string &symbol)\n{\n    using namespace commands;\n    const vector<std::string> limit_command = {send_tx::symbol(), createwallet::symbol(), deletewallet::symbol(), changepass::symbol(), addaddress::symbol(),\n                                               importwallet::symbol(), exportkeyfile::symbol(), \"exportwalletasfile\", importkeyfile::symbol(), \"importwalletfromfile\",\n                                               shutdown::symbol(), addpeer::symbol(), stopmining::symbol(), \"stop\", startmining::symbol(), \"start\", createrawtx::symbol(),\n                                               signrawtx::symbol(), sendrawtx::symbol(), createmultisigaddress::symbol(), deletemultisigaddress::symbol(), createmultisigtx::symbol(),\n                                               signmultisigtx::symbol(), deposit::symbol(), sendto::symbol(), \"uidsendto\", sendtomulti::symbol(), \"uidsendtomulti\",\n                                               sendfrom::symbol(), \"uidsendfrom\", createtoken::symbol(), deletetoken::symbol(), \"deletetoken\", registertoken::symbol(),\n                                               sendtokento::symbol(), \"uidsendtokento\", sendtokenfrom::symbol(), \"uidsendtokenfrom\", destroy::symbol(), vote::symbol(),\n                                               registercandidate::symbol(), transfercandidate::symbol(), registeruid::symbol(), transferuid::symbol(), checkwalletinfo::symbol(),\n                                               showaddresses::symbol(), showbalances::symbol(), showbalance::symbol(), showwallettoken::symbol(), decoderawtx::symbol(),\n                                               checkpublickey::symbol()};\n    auto it = std::find(limit_command.begin(), limit_command.end(), symbol);\n    if (it != limit_command.end())\n    {\n        throw invalid_command_exception{\"This command is not permitted!\"};\n    }\n}\n\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/addaddress.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/addaddress.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ addaddress *************************/\n\nconsole_result addaddress::invoke(Json::Value &jv_output,\n                                  libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    auto acc = blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    if (!option_.count || (option_.count & 0xfff00000))\n    {\n        throw address_amount_exception(\"invalid address number parameter\");\n    }\n    //operation\n    if (option_.operation == \"del\")\n    {\n        blockchain.delete_n_wallet_address(auth_.name, option_.count);\n        acc->set_hd_index(acc->get_hd_index() - option_.count);\n        blockchain.safe_store_wallet(*acc, std::vector<std::shared_ptr<wallet_address>>{});\n        jv_output[\"status\"] = \"address removed successfully\";\n    }\n    else if ((option_.operation == \"add\") || (option_.operation == \"\"))\n    {\n        std::string mnemonic;\n        acc->get_mnemonic(auth_.auth, mnemonic);\n        if (mnemonic.empty())\n        {\n            throw mnemonicwords_empty_exception(\"mnemonic empty\");\n        }\n\n        //split mnemonic to vector words\n        auto &&words = bc::split(mnemonic, \" \", true); // with trim\n\n        if ((words.size() % bc::wallet::mnemonic_word_multiple) != 0)\n        {\n            throw mnemonicwords_amount_exception{\"invalid size of backup words.\"};\n        }\n\n        Json::Value addresses;\n\n        std::vector<std::shared_ptr<wallet_address>> wallet_addresses;\n        wallet_addresses.reserve(option_.count);\n        const auto seed = decode_mnemonic(words);\n        libbitcoin::config::base16 bs(seed);\n        const data_chunk &ds = static_cast<const data_chunk &>(bs);\n        const auto prefixes = bc::wallet::hd_private::to_prefixes(76066276, 0); //76066276 is HD private key version\n        const bc::wallet::hd_private private_key(ds, prefixes);\n\n        // mainnet payment address version\n        auto payment_version = 68;\n        if (blockchain.chain_settings().use_testnet_rules)\n        {\n            // testnucnayment address version\n            payment_version = 127;\n        }\n\n        for (uint32_t idx = 0; idx < option_.count; idx++)\n        {\n\n            auto addr = std::make_shared<bc::chain::wallet_address>();\n            addr->set_name(auth_.name);\n\n            const auto child_private_key = private_key.derive_private(acc->get_hd_index());\n            auto hk = child_private_key.encoded();\n\n            // Create the private key from hd_key and the public version.\n            const auto derive_private_key = bc::wallet::hd_private(hk, prefixes);\n            auto pk = encode_base16(derive_private_key.secret());\n\n            addr->set_prv_key(pk.c_str(), auth_.auth);\n            // not store public key now\n            ec_compressed point;\n            libbitcoin::secret_to_public(point, derive_private_key.secret());\n\n            // Serialize to the original compression state.\n            auto ep = ec_public(point, true);\n\n            payment_address pa(ep, payment_version);\n\n            addr->set_address(pa.encoded());\n            addr->set_status(1); // 1 -- enable address\n\n            acc->increase_hd_index();\n            addr->set_hd_index(acc->get_hd_index());\n            wallet_addresses.push_back(addr);\n\n            addresses.append(addr->get_address());\n        }\n\n        blockchain.safe_store_wallet(*acc, wallet_addresses);\n\n        // write to output json\n\n        if (addresses.isNull())\n            addresses.resize(0);\n        jv_output = addresses;\n    }\n    else\n    {\n        jv_output = string(\"Invalid operation [\") + option_.operation + \"].\";\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/addpeer.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/addpeer.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/node_method_wrapper.hpp>\n#include <UChain/coin/config/authority.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChain/network/channel.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ addpeer *************************/\n\nconsole_result addpeer::invoke(Json::Value &jv_output,\n                               libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n\n    if (!auth_.name.empty() && !administrator_required_checker(node, auth_.name, auth_.auth))\n    {\n        throw address_invalid_exception{\"You can only add one address at a time.\"};\n    }\n\n    try\n    {\n        const auto authority = libbitcoin::config::authority(argument_.address);\n\n        code errcode;\n        auto handler = [&errcode](const code &ec) {\n            errcode = ec;\n        };\n\n        if (option_.operation == \"ban\")\n        {\n            network::channel::manual_ban(authority);\n            node.connections_ptr()->stop(authority);\n        }\n        else if ((option_.operation == \"add\") || (option_.operation == \"\"))\n        {\n            network::channel::manual_unban(authority);\n            node.store(authority.to_network_address(), handler);\n        }\n        else\n        {\n            jv_output = string(\"Invalid operation [\") + option_.operation + \"].\";\n            return console_result::okay;\n        }\n        jv_output = errcode.message();\n    }\n    catch (...)\n    {\n        throw address_invalid_exception{\"NODEADDRESS is not valid! \"};\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/changepass.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/changepass.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nconsole_result changepass::invoke(Json::Value &jv_output,\n                                  libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    auto acc = blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    std::string mnemonic;\n    acc->get_mnemonic(auth_.auth, mnemonic);\n\n    acc->set_passwd(option_.passwd);\n    acc->set_mnemonic(mnemonic, option_.passwd);\n\n    blockchain.store_wallet(acc);\n\n    // reencry address\n    auto pvaddr = blockchain.get_wallet_addresses(auth_.name);\n    if (!pvaddr)\n        throw address_list_nullptr_exception{\"empty address list\"};\n\n    std::string prv_key;\n    for (auto &each : *pvaddr)\n    {\n        prv_key = each.get_prv_key(auth_.auth);\n        each.set_prv_key(prv_key, option_.passwd);\n    }\n    // delete all old address\n    blockchain.delete_wallet_address(auth_.name);\n    // restore address\n    for (auto &each : *pvaddr)\n    {\n        auto addr = std::make_shared<bc::chain::wallet_address>(each);\n        blockchain.store_wallet_address(addr);\n    }\n\n    auto &jv = jv_output;\n    jv[\"name\"] = auth_.name;\n    jv[\"status\"] = \"changed successfully\";\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/checkpublickey.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/checkpublickey.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\nconsole_result checkpublickey::invoke(Json::Value &jv_output,\n                                      libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n    if (!argument_.address.empty() && !blockchain.is_valid_address(argument_.address))\n        throw address_invalid_exception{\"invalid address parameter!\"};\n\n    auto addr = bc::wallet::payment_address(argument_.address);\n    if (addr.version() == bc::wallet::payment_address::mainnet_p2sh) // for multisig address\n        throw argument_legality_exception{\"script address parameter not allowed!\"};\n\n    auto pvaddr = blockchain.get_wallet_addresses(auth_.name);\n    if (!pvaddr)\n        throw address_list_nullptr_exception{\"nullptr for address list\"};\n\n    // set random address\n    if (argument_.address.empty())\n    {\n        argument_.address = get_random_payment_address(pvaddr, blockchain);\n    }\n\n    // get public key\n    std::string prv_key;\n    std::string pub_key;\n    auto found = false;\n    for (auto &each : *pvaddr)\n    {\n        if (each.get_address() == argument_.address)\n        {\n            prv_key = each.get_prv_key(auth_.auth);\n            pub_key = ec_to_xxx_impl(\"ec-to-public\", prv_key);\n\n            found = true;\n            break;\n        }\n    }\n\n    if (!found)\n    {\n        throw wallet_address_get_exception{pub_key};\n    }\n\n    auto &root = jv_output;\n    if (get_api_version() <= 2)\n    {\n        root[\"public-key\"] = pub_key;\n        root[\"address\"] = argument_.address;\n    }\n    else\n    {\n        root[\"public_key\"] = pub_key;\n        root[\"address\"] = argument_.address;\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/checkwalletinfo.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/checkwalletinfo.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\n/************************ checkwalletinfo *************************/\n\nconsole_result checkwalletinfo::invoke(Json::Value &jv_output,\n                                       libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    auto acc = blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    //auto&& mnemonic = acc->get_mnemonic(auth_.auth);\n    std::string &&mnemonic = blockchain.is_wallet_lastwd_valid(*acc, auth_.auth, argument_.last_word);\n\n    auto &root = jv_output;\n\n    root[\"name\"] = acc->get_name();\n    root[\"mnemonic\"] = mnemonic;\n    root[\"address_count\"] = acc->get_hd_index();\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/createmultisigaddresses.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/createmultisigaddress.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\nconsole_result createmultisigaddress::invoke(\n    Json::Value &jv_output,\n    libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n\n    // check auth\n    auto wallet = blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    auto &pubkey_vec = option_.public_keys;\n    if (pubkey_vec.empty())\n    {\n        throw multisig_cosigne_exception{\"multisig cosigner public key needed.\"};\n    }\n\n    std::set<std::string> unique_keys(pubkey_vec.begin(), pubkey_vec.end());\n    if (unique_keys.size() != pubkey_vec.size())\n    {\n        throw multisig_cosigne_exception{\"multisig cosigner public key has duplicated items.\"};\n    }\n\n    // check m & n\n    if (option_.m < 1)\n    {\n        throw signature_amount_exception{\"signature number less than 1.\"};\n    }\n    if (option_.n < 1 || option_.n > 20)\n    {\n        throw pubkey_amount_exception{\n            \"public key number \" + std::to_string(option_.n) + \" less than 1 or bigger than 20.\"};\n    }\n    if (option_.m > option_.n)\n    {\n        throw signature_amount_exception{\n            \"signature number \" + std::to_string(option_.m) + \" is bigger than public key number \" + std::to_string(option_.n)};\n    }\n\n    // check self public key\n    auto self_pubkey = option_.self_publickey;\n    if (self_pubkey.empty())\n    {\n        throw pubkey_notfound_exception{\"self pubkey key not found!\"};\n    }\n\n    // if self public key not in public keys then add it.\n    auto iter = std::find(pubkey_vec.begin(), pubkey_vec.end(), self_pubkey);\n    if (iter == pubkey_vec.end())\n    {\n        pubkey_vec.push_back(self_pubkey);\n    }\n\n    // check public key size\n    if (option_.n != pubkey_vec.size())\n    {\n        throw pubkey_amount_exception{\"public key number does not match with n.\"};\n    }\n\n    // get private key according public key\n    auto pvaddr = blockchain.get_wallet_addresses(auth_.name);\n    if (!pvaddr)\n    {\n        throw address_list_nullptr_exception{\"nullptr for address list\"};\n    }\n\n    std::string self_prvkey;\n    auto found = false;\n    for (auto &each : *pvaddr)\n    {\n        self_prvkey = each.get_prv_key(auth_.auth);\n        auto &&target_pub_key = ec_to_xxx_impl(\"ec-to-public\", self_prvkey);\n        if (target_pub_key == self_pubkey)\n        {\n            found = true;\n            break;\n        }\n    }\n\n    if (!found)\n    {\n        throw pubkey_dismatch_exception{self_pubkey + \" does not belongs to this wallet\"};\n    }\n\n    // generate multisig wallet\n    wallet_multisig acc_multisig;\n    acc_multisig.set_hd_index(0);\n    acc_multisig.set_m(option_.m);\n    acc_multisig.set_n(option_.n);\n    acc_multisig.set_pub_key(self_pubkey);\n    acc_multisig.set_cosigner_pubkeys(std::move(pubkey_vec));\n    acc_multisig.set_description(option_.description);\n\n    // check same multisig wallet not exists\n    if (wallet->is_multisig_exist(acc_multisig))\n        throw multisig_exist_exception{\"multisig already exists.\"};\n\n    // update index\n    acc_multisig.set_index(wallet->get_multisig_vec().size() + 1);\n\n    // change wallet type\n    wallet->set_type(wallet_type::multisignature);\n\n    // create wallet address\n    auto wallet_address = std::make_shared<bc::chain::wallet_address>();\n    wallet_address->set_name(auth_.name);\n    wallet_address->set_prv_key(self_prvkey, auth_.auth);\n\n    // create payment script and address\n    auto multisig_script = acc_multisig.get_multisig_script();\n    chain::script payment_script;\n    payment_script.from_string(multisig_script);\n    if (script_pattern::pay_multisig != payment_script.pattern())\n        throw multisig_script_exception{std::string(\"invalid multisig script : \") + multisig_script};\n\n    payment_address address(payment_script, payment_address::mainnet_p2sh);\n    auto hash_address = address.encoded();\n\n    // update wallet and multisig wallet\n    // wallet_address->set_status(1); // 1 -- enable address\n    wallet_address->set_address(hash_address);\n    wallet_address->set_status(wallet_address_status::multisig_addr);\n\n    acc_multisig.set_address(hash_address);\n    wallet->set_multisig(acc_multisig);\n\n    // store them\n    blockchain.store_wallet(wallet);\n    blockchain.store_wallet_address(wallet_address);\n\n    // output json\n    jv_output = config::json_helper(get_api_version()).prop_list(acc_multisig);\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/createmultisigtx.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/createmultisigtx.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nusing namespace bc::explorer::config;\n\nconsole_result createmultisigtx::invoke(\n    Json::Value &jv_output,\n    libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    auto wallet = blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    // check from address\n    if (!blockchain.is_valid_address(argument_.from))\n    {\n        throw fromaddress_invalid_exception{\"invalid from address!\"};\n    }\n\n    auto addr = bc::wallet::payment_address(argument_.from);\n    if (addr.version() != bc::wallet::payment_address::mainnet_p2sh)\n    {\n        throw fromaddress_invalid_exception{\"from address is not a script address.\"};\n    }\n\n    auto multisig_vec = wallet->get_multisig(argument_.from);\n    if (!multisig_vec || multisig_vec->empty())\n    {\n        throw multisig_notfound_exception{\"multisig of from address not found.\"};\n    }\n\n    wallet_multisig acc_multisig = *(multisig_vec->begin());\n\n    // check to address\n    if (!blockchain.is_valid_address(argument_.to))\n    {\n        throw toaddress_invalid_exception{\"invalid to address!\"};\n    }\n\n    // receiver\n    std::vector<receiver_record> receiver;\n\n    auto type = static_cast<utxo_attach_type>(option_.type);\n    switch (type)\n    {\n    case utxo_attach_type::ucn:\n    {\n        receiver.push_back({argument_.to, \"\", argument_.amount, 0, type, asset()});\n        break;\n    }\n\n    case utxo_attach_type::token_transfer:\n    {\n        blockchain.uppercase_symbol(option_.symbol);\n        check_token_symbol(option_.symbol);\n        if (option_.symbol == UC_VOTE_TOKEN_SYMBOL)\n        {\n            throw token_symbol_name_exception{\"Cannot send 'VOTE' token in this way.Please use vote command.\"};\n        }\n        receiver.push_back({argument_.to, option_.symbol, 0, argument_.amount, type, asset()});\n        break;\n    }\n\n    default:\n    {\n        throw argument_legality_exception{\"invalid transaction type.\"};\n    }\n    break;\n    }\n\n    auto sp_send_helper = std::make_shared<sending_multisig_tx>(*this, blockchain,\n                                                                std::move(auth_.name), std::move(auth_.auth),\n                                                                std::move(argument_.from), std::move(receiver),\n                                                                argument_.fee, acc_multisig, std::move(option_.symbol));\n\n    sp_send_helper->exec();\n\n    // output json\n    auto &&tx = sp_send_helper->get_transaction();\n    jv_output = config::json_helper(get_api_version()).prop_list_of_rawtx(tx, false, true);\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/createrawtx.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/createrawtx.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nconsole_result createrawtx::invoke(Json::Value &jv_output,\n                                   libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    blockchain.uppercase_symbol(option_.symbol);\n\n    if (!option_.mychange_address.empty() && !blockchain.is_valid_address(option_.mychange_address))\n        throw toaddress_invalid_exception{\"invalid address \" + option_.mychange_address};\n\n    // check senders\n    if (option_.senders.empty())\n    {\n        throw fromaddress_invalid_exception{\"senders can not be empty!\"};\n    }\n\n    for (auto &each : option_.senders)\n    {\n        if (!blockchain.is_valid_address(each))\n        {\n            throw fromaddress_invalid_exception{\"invalid sender address \" + each};\n        }\n\n        // filter script address\n        if (blockchain.is_script_address(each))\n        {\n            throw fromaddress_invalid_exception{\"invalid sender address \" + each};\n        }\n    }\n\n    auto type = static_cast<utxo_attach_type>(option_.type);\n\n    if (type == utxo_attach_type::deposit)\n    {\n        if (!option_.symbol.empty())\n        {\n            throw argument_legality_exception{\"not deposit token \" + option_.symbol};\n        }\n\n        if (option_.receivers.size() != 1)\n        {\n            throw argument_legality_exception{\"only support deposit on one address!\"};\n        }\n    }\n    else if (type == utxo_attach_type::token_transfer)\n    {\n        blockchain.uppercase_symbol(option_.symbol);\n\n        // check token symbol\n        check_token_symbol(option_.symbol);\n    }\n\n    // receiver\n    receiver_record record;\n    std::vector<receiver_record> receivers;\n    for (auto &each : option_.receivers)\n    {\n        colon_delimited2_item<std::string, uint64_t> item(each);\n        record.target = item.first();\n        // address check\n        if (!blockchain.is_valid_address(record.target))\n        {\n            throw toaddress_invalid_exception{\"invalid receiver address \" + record.target};\n        }\n\n        record.symbol = option_.symbol;\n        if (record.symbol.empty())\n        {\n            record.amount = item.second(); // ucn amount\n            record.token_amount = 0;\n            if (!record.amount)\n                throw argument_legality_exception{\"invalid amount parameter \" + each};\n        }\n        else\n        {\n            record.amount = 0;\n            record.token_amount = item.second();\n            if (!record.token_amount)\n                throw argument_legality_exception{\"invalid token amount parameter \" + each};\n        }\n\n        record.type = type;\n        receivers.push_back(record);\n    }\n\n    if (receivers.empty())\n    {\n        throw toaddress_invalid_exception{\"receivers can not be empty!\"};\n    }\n\n    std::shared_ptr<base_transfer_common> sp_send_helper;\n\n    switch (type)\n    {\n    case utxo_attach_type::ucn:\n    case utxo_attach_type::token_transfer:\n    {\n        check_token_symbol_with_method(option_.symbol);\n\n        sp_send_helper = std::make_shared<base_transaction_constructor>(blockchain, type,\n                                                                        std::move(option_.senders), std::move(receivers),\n                                                                        std::move(option_.symbol), std::move(option_.mychange_address),\n                                                                        std::move(option_.message), option_.fee);\n        break;\n    }\n\n    case utxo_attach_type::deposit:\n    {\n        sp_send_helper = std::make_shared<depositing_ucn_transaction>(blockchain, type,\n                                                                      std::move(option_.senders), std::move(receivers),\n                                                                      option_.deposit, std::move(option_.mychange_address),\n                                                                      std::move(option_.message), option_.fee);\n        break;\n    }\n\n    default:\n    {\n        throw argument_legality_exception{\"invalid transaction type.\"};\n        break;\n    }\n    }\n\n    sp_send_helper->exec();\n\n    auto &&tx = sp_send_helper->get_transaction();\n\n    // output json\n    jv_output = config::json_helper(get_api_version()).prop_list_of_rawtx(tx, false);\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/createtoken.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/createtoken.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin {\nnamespace explorer {\nnamespace commands {\nusing namespace bc::explorer::config;\n/************************ createtoken *************************/\n\nvoid validate(boost::any& v,\n    const std::vector<std::string>& values, non_negative_uint64*, int)\n{\n    using namespace boost::program_options;\n    validators::check_first_occurrence(v);\n\n    std::string const& s = validators::get_single_string(values);\n    if (s[0] == '-') {\n        throw argument_legality_exception{\"volume cannot be anegative number.\"};\n    }\n    v = boost::any(non_negative_uint64 { boost::lexical_cast<uint64_t>(s) } );\n}\n\nconsole_result createtoken::invoke(Json::Value& jv_output,\n    libbitcoin::server::server_node& node)\n{\n    auto& blockchain = node.chain_impl();\n    blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n    blockchain.uppercase_symbol(option_.symbol);\n\n    // check token symbol\n    check_token_symbol(option_.symbol, true);\n\n    // check uid symbol\n    auto issued_uid = option_.issuer;\n    check_uid_symbol(issued_uid);\n\n    if (option_.description.length() > TOKEN_DETAIL_DESCRIPTION_FIX_SIZE)\n        throw token_description_length_exception{\"token description length must be less than 64.\"};\n    auto threshold = option_.registersecondarytoken_threshold;\n    if ((threshold < -1) || (threshold > 100)) {\n        throw token_secondaryissue_threshold_exception{\n            \"registersecondarytoken threshold value error, it must be -1 or in the interval 0 to 100.\"};\n    }\n\n    if (option_.decimal_number > 19u)\n        throw token_amount_exception{\"token decimal number must less than 20.\"};\n    if (option_.maximum_supply.volume == 0u)\n        throw argument_legality_exception{\"volume cannot be zero.\"};\n\n    // check uid exists\n    if (!blockchain.is_uid_exist(issued_uid)) {\n        throw uid_symbol_notfound_exception{\n            \"The uid '\" + issued_uid + \"' does not exist on the blockchain, maybe you should registeruid first\"};\n    }\n\n    // check uid is owned by the wallet\n    if (!blockchain.is_wallet_owned_uid(auth_.name, issued_uid)) {\n        throw uid_symbol_notowned_exception{\n            \"The uid '\" + issued_uid + \"' is not owned by \" + auth_.name};\n    }\n\n    // check token exists\n    if (blockchain.is_token_exist(option_.symbol, true))\n        throw token_symbol_existed_exception{\"symbol is already used.\"};\n\n    // local database token check\n    auto sh_token = blockchain.get_wallet_unissued_token(auth_.name, option_.symbol);\n    if (sh_token) {\n        throw token_symbol_duplicate_exception{option_.symbol\n            + \" already created, you can delete and recreate it.\"};\n    }\n\n    auto acc = std::make_shared<token_detail>();\n    acc->set_symbol(option_.symbol);\n    acc->set_maximum_supply(option_.maximum_supply.volume);\n    acc->set_decimal_number(static_cast<uint8_t>(option_.decimal_number));\n    acc->set_issuer(issued_uid);\n    acc->set_description(option_.description);\n    // use 127 to represent freely secondary issue, and 255 for its secondary issued status.\n    acc->set_secondaryissue_threshold((threshold == -1) ?\n        token_detail::freely_secondaryissue_threshold : static_cast<uint8_t>(threshold));\n\n    blockchain.store_wallet_token(acc, auth_.name);\n\n    if (get_api_version() <= 2) {\n        Json::Value token_data = config::json_helper(get_api_version()).prop_list(*acc, true);\n        token_data[\"status\"] = \"unissued\";\n        jv_output[\"token\"] = token_data;\n    }\n    else {\n        jv_output = config::json_helper(get_api_version()).prop_list(*acc, true);\n        jv_output[\"status\"] = \"unissued\";\n    }\n\n    return console_result::okay;\n}\n\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n\n"
  },
  {
    "path": "src/UChainService/api/command/commands/createwallet.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/createwallet.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChain/explorer/commands/offline_commands_impl.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\n/************************ createwallet *************************/\n\nconsole_result createwallet::invoke(Json::Value &jv_output,\n                                    libbitcoin::server::server_node &node)\n{\n#ifdef NDEBUG\n    if (auth_.name.length() > 128 || auth_.name.length() < 3 ||\n        auth_.auth.length() > 128 || auth_.auth.length() < 6)\n        throw argument_legality_exception{\"name length in [3, 128], password length in [6, 128]\"};\n#endif\n\n    auto &blockchain = node.chain_impl();\n    if (blockchain.is_wallet_exist(auth_.name))\n    {\n        throw wallet_existed_exception{\"wallet already exist\"};\n    }\n\n    auto acc = std::make_shared<bc::chain::wallet>();\n    acc->set_name(auth_.name);\n    acc->set_passwd(auth_.auth);\n\n    bc::explorer::config::language opt_language(option_.language);\n    auto &&seed = get_seed();\n    auto &&words_list = get_mnemonic_new(opt_language, seed);\n    auto &&words = bc::join(words_list);\n\n    acc->set_mnemonic(words, auth_.auth);\n\n    // flush to db\n    auto ret = blockchain.store_wallet(acc);\n\n    // get 1 new sub-address by default\n    std::stringstream sout(\"\");\n    Json::Value jv_temp;\n    const char *cmds2[]{\"addaddress\", auth_.name.c_str(), auth_.auth.c_str()};\n\n    if (dispatch_command(3, cmds2, jv_temp, node, get_api_version()) != console_result::okay)\n    {\n        throw address_generate_exception(sout.str());\n    }\n\n    {\n        config::json_helper::wallet_info acc(auth_.name, words, jv_temp);\n        jv_output = config::json_helper(get_api_version()).prop_list(acc);\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/decoderawtx.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/decoderawtx.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nconsole_result decoderawtx::invoke(Json::Value &jv_output,\n                                   libbitcoin::server::server_node &node)\n{\n    tx_type tx_ = argument_.transaction;\n    jv_output = config::json_helper(get_api_version()).prop_tree(tx_, true);\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/deletemultisigaddress.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/deletemultisigaddress.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nusing namespace bc::explorer::config;\n\nconsole_result deletemultisigaddress::invoke(Json::Value &jv_output,\n                                             libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    auto acc = blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    if (!blockchain.is_valid_address(option_.address))\n    {\n        throw fromaddress_invalid_exception(\"invalid address! \" + option_.address);\n    }\n\n    auto addr = bc::wallet::payment_address(option_.address);\n    if (addr.version() != bc::wallet::payment_address::mainnet_p2sh)\n    {\n        throw fromaddress_invalid_exception(\"address \" + option_.address + \" is not a script address.\");\n    }\n\n    // get multisig\n    auto multisig_vec = acc->get_multisig(option_.address);\n    if (!multisig_vec || multisig_vec->empty())\n    {\n        throw multisig_notfound_exception(\" multisig of address \" + option_.address + \" is not found.\");\n    }\n\n    // remove multisig\n    for (auto &acc_multisig : *multisig_vec)\n    {\n        acc->remove_multisig(acc_multisig);\n    }\n\n    // change wallet type\n    if (acc->get_multisig_vec().empty())\n    {\n        acc->set_type(wallet_type::common);\n    }\n\n    // flush to db\n    blockchain.store_wallet(acc);\n\n    // delete wallet address\n    auto vaddr = blockchain.get_wallet_addresses(auth_.name);\n    if (!vaddr)\n    {\n        throw address_list_empty_exception{\"empty address list for this wallet\"};\n    }\n\n    blockchain.delete_wallet_address(auth_.name);\n    for (auto it = vaddr->begin(); it != vaddr->end();)\n    {\n        if (it->get_address() == option_.address)\n        {\n            it = vaddr->erase(it);\n        }\n        else\n        {\n            ++it;\n        }\n    }\n\n    // restore address\n    for (auto &each : *vaddr)\n    {\n        auto addr = std::make_shared<bc::chain::wallet_address>(each);\n        blockchain.store_wallet_address(addr);\n    }\n\n    // output json\n    jv_output.resize(0);\n    auto helper = config::json_helper(get_api_version());\n    if (get_api_version() <= 2)\n    {\n        auto &acc_multisig = *(multisig_vec->begin());\n        jv_output = helper.prop_list(acc_multisig);\n    }\n    else\n    {\n        Json::Value nodes;\n        for (auto &acc_multisig : *multisig_vec)\n        {\n            Json::Value node = helper.prop_list(acc_multisig);\n            nodes.append(node);\n        }\n\n        jv_output = nodes;\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/deletetoken.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/deletetoken.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <boost/algorithm/string.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n/************************ deletetoken *************************/\n\nconsole_result deletetoken::invoke(Json::Value &jv_output,\n                                   libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n    // maybe throw\n    blockchain.uppercase_symbol(option_.symbol);\n\n    if (blockchain.get_issued_token(option_.symbol))\n        throw token_issued_not_delete{\"Cannot delete token \" + option_.symbol + \" which has been issued.\"};\n\n    std::promise<code> p;\n    std::vector<libbitcoin::blockchain::tx_pool::transaction_ptr> txs;\n    blockchain.pool().fetch([&txs, &p](const code &ec,\n                                       const std::vector<libbitcoin::blockchain::tx_pool::transaction_ptr> &tx) {\n        if (!ec)\n        {\n            txs = tx;\n        }\n\n        p.set_value(ec);\n    });\n    p.get_future().get();\n\n    for (auto &tx : txs)\n    {\n        for (auto &output : tx->outputs)\n        {\n            if (output.is_token_issue() && output.get_token_symbol() == option_.symbol)\n            {\n                throw token_issued_not_delete{\"Cannot delete token \" + option_.symbol + \" which has been issued.\"};\n            }\n        }\n    }\n\n    std::vector<business_address_token> tokens = *blockchain.get_wallet_unissued_tokens(auth_.name);\n    bool found = false;\n    for (auto it = tokens.begin(); it != tokens.end(); ++it)\n    {\n        if (it->detail.get_symbol() == option_.symbol)\n        {\n            if (blockchain.delete_wallet_token(auth_.name) == console_result::failure)\n            {\n                throw token_delete_fail{\"token \" + option_.symbol + \" delete fail.\"};\n            }\n\n            tokens.erase(it);\n            for (auto token : tokens)\n            {\n                blockchain.store_wallet_token(token.detail, auth_.name);\n            }\n\n            found = true;\n            break;\n        }\n    }\n\n    if (!found)\n    {\n        throw token_notfound_exception{\"token \" + option_.symbol + \" does not existed or do not belong to \" + auth_.name + \".\"};\n    }\n\n    if (get_api_version() <= 2)\n    {\n        jv_output[\"symbol\"] = option_.symbol;\n        jv_output[\"operate\"] = \"delete\";\n        jv_output[\"result\"] = \"success\";\n    }\n    else\n    {\n        jv_output[\"symbol\"] = option_.symbol;\n        jv_output[\"status\"] = \"deleted successfully\";\n    }\n\n    return console_result::okay;\n}\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/deletewallet.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChainService/api/command/commands/deletewallet.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ deletewallet *************************/\n\nconsole_result deletewallet::invoke(Json::Value &jv_output,\n                                    libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    auto acc = blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    blockchain.is_wallet_lastwd_valid(*acc, auth_.auth, argument_.last_word);\n\n    // delete wallet addresses\n    blockchain.delete_wallet_address(acc->get_name());\n\n    // delete wallet token\n    blockchain.delete_wallet_token(acc->get_name());\n    // delete wallet\n    blockchain.delete_wallet(acc->get_name());\n\n    jv_output[\"name\"] = acc->get_name();\n    jv_output[\"status\"] = \"removed successfully\";\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/deposit.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/deposit.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nconsole_result deposit::invoke(Json::Value &jv_output,\n                               libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    if (argument_.deposit != 10 && argument_.deposit != 45 && argument_.deposit != 120 && argument_.deposit != 240 && argument_.deposit != 540)\n    {\n        throw wallet_deposit_period_exception{\"deposit must be one in [10, 45, 120, 240, 540].\"};\n    }\n\n    auto pvaddr = blockchain.get_wallet_addresses(auth_.name);\n    if (!pvaddr || pvaddr->empty())\n        throw address_list_nullptr_exception{\"nullptr for address list\"};\n\n    std::string addr = argument_.uid;\n    if (addr.empty())\n    {\n        addr = get_random_payment_address(pvaddr, blockchain);\n    }\n    else\n    {\n        addr = get_address_from_strict_uid(argument_.uid, blockchain);\n        auto acc_addr = blockchain.get_wallet_address(auth_.name, addr);\n        if (!acc_addr)\n            throw argument_legality_exception{\"You don't own address \" + addr};\n    }\n\n    // receiver\n    std::vector<receiver_record> receiver{\n        {addr, \"\", argument_.amount, 0, utxo_attach_type::deposit, asset{\"\", argument_.uid}}};\n    auto deposit_helper = depositing_ucn(*this, blockchain, std::move(auth_.name), std::move(auth_.auth),\n                                         std::move(addr), std::move(receiver), argument_.deposit, argument_.fee);\n\n    deposit_helper.exec();\n\n    // json output\n    auto tx = deposit_helper.get_transaction();\n    jv_output = config::json_helper(get_api_version()).prop_tree(tx, true);\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/destroy.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/destroy.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nconsole_result destroy::invoke(Json::Value &jv_output,\n                               libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    std::string blackhole_uid = UC_BLACKHOLE_UID_SYMBOL;\n\n    if (option_.is_candidate)\n    {\n        const char *cmds[]{\n            \"transfercandidate\", auth_.name.c_str(), auth_.auth.c_str(),\n            blackhole_uid.c_str(), argument_.symbol.c_str()};\n\n        return dispatch_command(5, cmds, jv_output, node, get_api_version());\n    }\n    else if (!option_.cert_type.empty())\n    {\n        const char *cmds[]{\n            \"transfercert\", auth_.name.c_str(), auth_.auth.c_str(),\n            blackhole_uid.c_str(), argument_.symbol.c_str(), option_.cert_type.c_str()};\n\n        return dispatch_command(6, cmds, jv_output, node, get_api_version());\n    }\n    else\n    {\n        if (argument_.amount <= 0)\n        {\n            throw argument_legality_exception{\"invalid amount parameter!\"};\n        }\n\n        auto &&amount = std::to_string(argument_.amount);\n        const char *cmds[]{\n            \"sendtokento\", auth_.name.c_str(), auth_.auth.c_str(),\n            blackhole_uid.c_str(), argument_.symbol.c_str(), amount.c_str()};\n\n        return dispatch_command(6, cmds, jv_output, node, get_api_version());\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/exportkeyfile.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChainService/api/command/commands/exportkeyfile.hpp>\n#include <UChainService/api/command/wallet_info.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChain/coin/formats/base_64.hpp>\n#include <cryptojs/cryptojs_impl.h>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nnamespace fs = boost::filesystem;\nusing namespace bc::explorer::config;\n/************************ exportwalletasfile *************************/\n\nconsole_result exportkeyfile::invoke(Json::Value &jv_output,\n                                     libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    auto acc = blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    std::string &&mnemonic = blockchain.is_wallet_lastwd_valid(*acc, auth_.auth, argument_.last_word);\n\n    std::string keyfile_name = \"uc_keystore_\" + auth_.name + \".json\";\n\n    // wallet address info\n    auto pvaddr = blockchain.get_wallet_addresses(auth_.name);\n    if (!pvaddr)\n        throw address_list_nullptr_exception{\"nullptr for address list\"};\n\n    Json::Value file_root;\n    //light-wallet version no,\n    //Shared by full-wallet from now on. 2018-04-01\n    file_root[\"version\"] = \"0.2.1\";\n    file_root[\"algo\"] = \"aes\";\n    file_root[\"index\"] = uint32_t(pvaddr->size() - acc->get_multisig_vec().size());\n    file_root[\"mnemonic\"] = libbitcoin::encode_base64(cryptojs::encrypt(\"\\\"\" + mnemonic + \"\\\"\", auth_.auth));\n    //file_root[\"wallets\"] =  ss.str();\n\n    Json::Value multisig_lst;\n    multisig_lst.resize(0);\n    for (auto ms : acc->get_multisig_vec())\n    {\n        Json::Value multisig;\n        multisig[\"m\"] = ms.get_m();\n        multisig[\"n\"] = ms.get_n();\n        multisig[\"s\"] = ms.get_pub_key();\n        multisig[\"d\"] = ms.get_description();\n        for (const auto &cosigner_pubkey : ms.get_cosigner_pubkeys())\n        {\n            multisig[\"k\"].append(cosigner_pubkey);\n        }\n        multisig_lst.append(multisig);\n    }\n    file_root[\"multisigs\"] = multisig_lst;\n\n    Json::Value result;\n\n    if (!option_.is_data)\n    {\n        if (argument_.dst.empty())\n        {\n            // default path. provides download.\n            if (!boost::filesystem::exists(webpage_path()))\n            {\n                fs::create_directory(webpage_path());\n            }\n\n            argument_.dst = webpage_path() / \"keys\";\n            fs::create_directory(argument_.dst);\n            argument_.dst /= keyfile_name;\n        }\n        else\n        {\n            string dstpath = argument_.dst.string();\n            if (dstpath.length() > 0 && dstpath[0] == '~')\n            {\n                char *home_dir = getenv(\"HOME\");\n                if (home_dir && strlen(home_dir) != 0)\n                {\n                    dstpath.replace(0, 1, home_dir);\n                    argument_.dst = fs::path(dstpath);\n                }\n            }\n\n            fs::file_status status = fs::status(argument_.dst);\n            if (fs::is_directory(status)) // not process filesystem exception here\n                argument_.dst /= keyfile_name;\n\n            fs::file_status status2 = fs::status(argument_.dst.parent_path());\n            if (!fs::exists(status2))\n                throw argument_legality_exception{\n                    argument_.dst.parent_path().string() + std::string(\" directory does not exist.\")};\n        }\n\n        // store encrypted data to file\n        bc::ofstream file_output(argument_.dst.string(), std::ofstream::out);\n        file_output << file_root.toStyledString() << std::flush;\n        file_output.close();\n\n        result = argument_.dst.string();\n    }\n    else\n    {\n        result = file_root;\n    }\n\n    auto &root = jv_output;\n    if (get_api_version() == 1)\n        root[\"result\"] = result;\n    else\n        root = result;\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/importkeyfile.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/dispatch.hpp>\n#include <UChain/explorer/json_helper.hpp>\n#include <UChainService/api/command/commands/importkeyfile.hpp>\n#include <UChainService/api/command/wallet_info.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChain/coin/formats/base_64.hpp>\n#include <cryptojs/cryptojs_impl.h>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nnamespace fs = boost::filesystem;\nusing namespace bc::explorer::config;\n\n/************************ importkeyfile *************************/\n\nconsole_result importkeyfile::invoke(Json::Value &jv_output,\n                                     libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n\n    if (blockchain.is_wallet_exist(auth_.name))\n    {\n        throw wallet_existed_exception{auth_.name + \" wallet already exist\"};\n    }\n\n    auto acc = std::make_shared<bc::chain::wallet>();\n\n    //wallet name and password\n    acc->set_name(auth_.name);\n    acc->set_passwd(auth_.auth);\n\n    std::string file_content;\n    if (option_.content != \"\")\n    {\n        file_content = option_.content;\n    }\n    else\n    {\n        fs::file_status status = fs::status(option_.file);\n        if (!fs::exists(status)) // not process filesystem exception here\n            throw argument_legality_exception{option_.file.string() + std::string(\" not exist.\")};\n        if (fs::is_directory(status)) // directory not allowed\n            throw argument_legality_exception{option_.file.string() + std::string(\" is directory not a file.\")};\n        if (!fs::is_regular_file(status))\n            throw argument_legality_exception{option_.file.string() + std::string(\" not a regular file.\")};\n\n        std::ifstream file_input(option_.file.string(), std::ofstream::in);\n        file_content.assign(std::istreambuf_iterator<char>(file_input),\n                            std::istreambuf_iterator<char>());\n        file_input.close();\n    }\n\n    Json::Reader reader;\n    Json::Value file_root;\n    if (file_content.length() && (file_content[0] == '{') && reader.parse(file_content, file_root))\n    {\n        //mnemonic\n        {\n            const std::string encoded_mnemonic = file_root[\"mnemonic\"].asString();\n            data_chunk decoded_mnemonic;\n            if (!libbitcoin::decode_base64(decoded_mnemonic, encoded_mnemonic))\n            {\n                throw encode_exception{encoded_mnemonic + std::string(\" invalid for decode_base64.\")};\n            }\n            std::string mnemonic;\n            if (!cryptojs::decrypt(decoded_mnemonic, auth_.auth, mnemonic))\n            {\n                throw encode_exception{std::string(\"Failed to decrypt mnemonic with password.\")};\n            }\n\n            if ((mnemonic[0] != '\"') || (mnemonic[mnemonic.size() - 1] != '\"'))\n            {\n                throw encode_exception{std::string(\"decrypted mnemonic format error.\")};\n            }\n\n            acc->set_mnemonic(mnemonic.substr(1, mnemonic.size() - 2), auth_.auth);\n        }\n\n        if (blockchain.store_wallet(acc) != console_result::okay)\n        {\n            throw address_generate_exception{std::string(\"Failed to store wallet.\")};\n        }\n\n        //address\n        {\n            const std::string address_count = file_root[\"index\"].asString();\n\n            // get n new sub-address\n            Json::Value jv_temp;\n            const char *cmds2[]{\"addaddress\", auth_.name.c_str(), auth_.auth.c_str(), \"--number\",\n                                address_count.c_str()};\n\n            if (dispatch_command(5, cmds2, jv_temp, node, get_api_version()) != console_result::okay)\n            {\n                throw address_generate_exception{std::string(\"Failed to generate address.\")};\n            }\n        }\n\n        //multisig\n        {\n            const auto &multisigs = file_root[\"multisigs\"];\n            const int multisigs_size = multisigs.size();\n            for (int i = 0; i < multisigs_size; ++i)\n            {\n                std::string d = multisigs[i][\"d\"].asString();\n                std::string m = multisigs[i][\"m\"].asString();\n                std::string n = multisigs[i][\"n\"].asString();\n                std::string s = multisigs[i][\"s\"].asString();\n\n                std::vector<std::string> vec_k;\n\n                const auto &k = multisigs[i][\"k\"];\n                for (unsigned int j = 0; j < k.size(); ++j)\n                {\n                    std::string d = k[j].asString();\n                    vec_k.push_back(d);\n                }\n\n                // get n new sub-address\n                Json::Value jv_temp;\n                std::vector<const char *> vec_cmds = {\"createmultisigaddress\", auth_.name.c_str(), auth_.auth.c_str(),\n                                                      \"-s\", s.c_str(),\n                                                      \"-m\", m.c_str(),\n                                                      \"-n\", n.c_str(),\n                                                      \"-d\", d.c_str()};\n                for (const auto &s : vec_k)\n                {\n                    vec_cmds.push_back(\"-k\");\n                    vec_cmds.push_back(s.c_str());\n                }\n\n                if (dispatch_command(vec_cmds.size(), vec_cmds.data(), jv_temp, node, get_api_version()) != console_result::okay)\n                {\n                    throw address_generate_exception{std::string(\"Failed to generate address.\")};\n                }\n            }\n        }\n\n        Json::Value jv_temp;\n        std::vector<const char *> vec_cmds = {\"showaddresses\", auth_.name.c_str(), auth_.auth.c_str()};\n        if (dispatch_command(vec_cmds.size(), vec_cmds.data(), jv_temp, node, get_api_version()) != console_result::okay)\n        {\n            throw wallet_address_get_exception{std::string(\"Failed to list wallet addresses.\")};\n        }\n\n        auto &root = jv_output;\n        config::json_helper::wallet_info acc(auth_.name, \"\", jv_temp);\n        root = config::json_helper(get_api_version()).prop_list(acc);\n\n        return console_result::okay;\n    }\n    else\n    {\n        wallet_info all_info(blockchain, auth_.auth);\n        std::stringstream ss(file_content);\n        // decrypt wallet info file first\n        ss >> all_info;\n\n        // name check\n        auto acc = all_info.get_wallet();\n        auto name = acc.get_name();\n        auto mnemonic = acc.get_mnemonic();\n        if (blockchain.is_wallet_exist(name))\n            throw wallet_existed_exception{name + std::string(\" wallet is already exist\")};\n\n        // store wallet info to db\n        all_info.store(name, auth_.auth);\n\n        auto &root = jv_output;\n        root[\"name\"] = name;\n\n        if (get_api_version() == 1)\n        {\n            root[\"address-count\"] += acc.get_hd_index();\n            root[\"unissued-token-count\"] += all_info.get_wallet_token().size();\n        }\n        else if (get_api_version() <= 2)\n        {\n            root[\"address-count\"] = acc.get_hd_index();\n            root[\"unissued-token-count\"] = static_cast<uint64_t>(all_info.get_wallet_token().size());\n        }\n        else\n        {\n            root[\"address_count\"] = acc.get_hd_index();\n            root[\"unissued_token_count\"] = static_cast<uint64_t>(all_info.get_wallet_token().size());\n        }\n\n        return console_result::okay;\n    }\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/importwallet.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <boost/algorithm/string.hpp>\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/importwallet.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChain/explorer/commands/offline_commands_impl.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\nconsole_result importwallet::invoke(Json::Value &jv_output,\n                                    libbitcoin::server::server_node &node)\n{\n\n    // parameter wallet name check\n    auto &blockchain = node.chain_impl();\n    if (blockchain.is_wallet_exist(auth_.name))\n        throw wallet_existed_exception{\"wallet already exist\"};\n\n#ifdef NDEBUG\n    if (auth_.name.length() > 128 || auth_.name.length() < 3 ||\n        option_.passwd.length() > 128 || option_.passwd.length() < 6)\n        throw argument_exceed_limit_exception{\"name length in [3, 128], password length in [6, 128]\"};\n#endif\n\n    if (argument_.words.size() == 1)\n    {\n        argument_.words = bc::split(argument_.words[0], \" \", true);\n    }\n\n    // are vliad mnemonic words.\n    auto &&seed = get_mnemonic_to_seed(option_.language, argument_.words);\n    // is vliad seed.\n    auto &&hd_pri_key = get_hd_new(seed);\n\n    auto &&mnemonic = bc::join(argument_.words);\n\n    // create wallet\n    auto acc = std::make_shared<bc::chain::wallet>();\n    acc->set_name(auth_.name);\n    acc->set_passwd(option_.passwd);\n    acc->set_mnemonic(mnemonic, option_.passwd);\n    //acc->set_hd_index(option_.hd_index); // hd_index updated in addaddress\n\n    // flush to db\n    blockchain.store_wallet(acc);\n\n    // generate all wallet address\n    auto &&str_idx = std::to_string(option_.hd_index);\n    const char *cmds2[]{\"addaddress\", auth_.name.c_str(), option_.passwd.c_str(), \"-n\", str_idx.c_str()};\n    Json::Value addresses;\n\n    if (dispatch_command(5, cmds2, addresses, node, get_api_version()) != console_result::okay)\n    {\n        throw address_generate_exception{\"addaddress got exception.\"};\n    }\n\n    if (get_api_version() <= 2)\n    {\n        if (get_api_version() == 1)\n        {\n            jv_output[\"hd_index\"] += option_.hd_index;\n            if (option_.hd_index == 1)\n            {\n                Json::Value addr;\n                addr.append(addresses.asString());\n                jv_output[\"addresses\"] = addr;\n            }\n            else\n            {\n                jv_output[\"addresses\"] = addresses[\"addresses\"];\n            }\n        }\n        else if (get_api_version() == 2)\n        {\n            jv_output[\"hd_index\"] = option_.hd_index;\n            jv_output[\"addresses\"] = addresses[\"addresses\"];\n        }\n\n        jv_output[\"name\"] = auth_.name;\n        jv_output[\"mnemonic\"] = mnemonic;\n    }\n    else\n    {\n        config::json_helper::wallet_info acc(auth_.name, mnemonic, addresses);\n        jv_output = config::json_helper(get_api_version()).prop_list(acc);\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/registercandidate.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChainService/api/command/commands/registercandidate.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n#include <UChain/coin/config/authority.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nvoid registercandidate::check_symbol_content(const std::string &symbol, const std::string &content)\n{\n    // check symbol\n    if (symbol.size() == 0)\n    {\n        throw token_symbol_length_exception{\"Symbol can not be empty.\"};\n    }\n\n    // reserve 4 bytes\n    if (symbol.size() > (TOKEN_CANDIDATE_SYMBOL_FIX_SIZE - 4))\n    {\n        throw token_symbol_length_exception{\"Symbol length must be less than \" + std::to_string(TOKEN_CANDIDATE_SYMBOL_FIX_SIZE - 4) + \". \" + symbol};\n    }\n\n    // check symbol\n    check_candidate_symbol(symbol, true);\n\n    // check content\n    if (content.size() > TOKEN_CANDIDATE_CONTENT_FIX_SIZE)\n    {\n        throw argument_size_invalid_exception(\n            \"Content length must be less than \" + std::to_string(TOKEN_CANDIDATE_CONTENT_FIX_SIZE) + \". \" + content);\n    }\n\n    //check_candidate_authority(content);\n}\n\nconsole_result registercandidate::invoke(Json::Value &jv_output,\n                                         libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    std::map<std::string, std::string> candidate_map;\n\n    bool use_unified_content = false;\n    // check single symbol and content\n    if (argument_.symbol.size() > 0)\n    {\n        check_symbol_content(argument_.symbol, argument_.content);\n\n        // check symbol not registered\n        if (blockchain.get_registered_candidate(argument_.symbol))\n        {\n            throw token_symbol_existed_exception{\"candidate already exists in blockchain. \" + argument_.symbol};\n        }\n\n        candidate_map[argument_.symbol] = argument_.content;\n    }\n    else\n    {\n        if (argument_.content.size() > 0)\n        {\n            // check content\n            if (argument_.content.size() > TOKEN_CANDIDATE_CONTENT_FIX_SIZE)\n            {\n                throw argument_size_invalid_exception(\n                    \"Content length must be less than \" + std::to_string(TOKEN_CANDIDATE_CONTENT_FIX_SIZE) + \". \" + argument_.content);\n            }\n\n            use_unified_content = true;\n        }\n    }\n\n    // check multi symbol and content\n    /*for (const auto& candidate : option_.multicandidates) {\n        std::string symbol, content;\n        auto pos = candidate.find_first_of(\":\");\n        if (pos == std::string::npos) {\n            symbol = candidate;\n\n            if (use_unified_content) {\n                content = argument_.content;\n            }\n            else {\n                content = \"\";\n            }\n        }\n        else {\n            symbol = candidate.substr(0, pos);\n            content = candidate.substr(pos + 1);\n        }\n\n        check_symbol_content(symbol, content);\n\n        if (candidate_map.find(symbol) != candidate_map.end()) {\n            throw token_symbol_existed_exception{\"Duplicate symbol: \" + symbol};\n        }\n\n        // check symbol not registered\n        if (blockchain.get_registered_candidate(symbol)) {\n            throw token_symbol_existed_exception{\"candidate already exists in blockchain. \" + symbol};\n        }\n\n        candidate_map[symbol] = content;\n    }*/\n\n    if (candidate_map.empty())\n    {\n        throw argument_legality_exception{\"No symbol provided.\"};\n    }\n\n    /*try {\n        const auto authority = libbitcoin::config::authority(argument_.symbol);\n        if (!authority.to_network_address().is_routable()) {\n            throw address_invalid_exception{\"NODEADDRESS is not routable! \"};\n        }\n    }\n    catch (...)\n    {\n        throw address_invalid_exception{\"NODEADDRESS is not valid! \"};\n    }*/\n\n    // check to uid\n    auto to_uid = argument_.to;\n\n    auto to_address = get_address_from_uid(to_uid, blockchain);\n    if (!blockchain.is_valid_address(to_address))\n    {\n        throw address_invalid_exception{\"invalid uid parameter! \" + to_uid};\n    }\n    if (!blockchain.get_wallet_address(auth_.name, to_address))\n    {\n        throw address_dismatch_wallet_exception{\"target uid does not match wallet. \" + to_uid};\n    }\n\n    // receiver\n    std::vector<receiver_record> receiver;\n    for (auto &pair : candidate_map)\n    {\n        receiver.push_back(\n            {to_address, pair.first, 0, 0, 0,\n             utxo_attach_type::candidate, asset(to_uid, to_uid)});\n    }\n\n    receiver.push_back({to_address, \"\", bc::min_lock_to_issue_candidate, 0, utxo_attach_type::deposit, asset{\"\", to_uid}});\n\n    auto helper = registering_candidate(\n        *this, blockchain,\n        std::move(auth_.name), std::move(auth_.auth),\n        std::move(to_address),\n        \"\", std::move(candidate_map),\n        std::move(receiver), argument_.fee);\n\n    helper.exec();\n\n    // json output\n    auto tx = helper.get_transaction();\n    jv_output = config::json_helper(get_api_version()).prop_tree(tx, true);\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/registercert.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChainService/api/command/commands/registercert.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\ntemplate <typename ElemT>\nstruct HexTo\n{\n    ElemT value;\n    operator ElemT() const { return value; }\n    friend std::istream &operator>>(std::istream &in, HexTo &out)\n    {\n        in >> std::hex >> out.value;\n        return in;\n    }\n};\n\nconsole_result registercert::invoke(Json::Value &jv_output,\n                                    libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    blockchain.uppercase_symbol(argument_.symbol);\n    boost::to_lower(argument_.cert);\n\n    // check token symbol\n    check_token_symbol(argument_.symbol);\n\n    auto to_uid = argument_.to;\n    auto to_address = get_address_from_uid(to_uid, blockchain);\n    if (!blockchain.is_valid_address(to_address))\n    {\n        throw address_invalid_exception{\"invalid uid parameter! \" + to_uid};\n    }\n    if (!blockchain.get_wallet_address(auth_.name, to_address))\n    {\n        throw address_dismatch_wallet_exception{\"target uid does not match wallet. \" + to_uid};\n    }\n\n    // check token cert types\n    auto certs_create = token_cert_ns::none;\n    std::map<std::string, token_cert_type> cert_map = {\n        {\"naming\", token_cert_ns::naming},\n        {\"marriage\", token_cert_ns::marriage},\n        {\"kyc\", token_cert_ns::kyc}};\n    auto iter = cert_map.find(argument_.cert);\n    if (iter != cert_map.end())\n    {\n        certs_create = iter->second;\n    }\n    else\n    {\n        try\n        {\n            if (argument_.cert.compare(0, 2, \"0x\") == 0)\n            {\n                certs_create = boost::lexical_cast<HexTo<token_cert_type>>(argument_.cert.c_str());\n            }\n            else\n            {\n                certs_create = boost::lexical_cast<token_cert_type>(argument_.cert.c_str());\n            }\n\n            if (certs_create < token_cert_ns::custom)\n            {\n                throw token_cert_exception(\"invalid token cert type \" + argument_.cert);\n            }\n        }\n        catch (boost::bad_lexical_cast const &)\n        {\n            throw token_cert_exception(\"invalid token cert type \" + argument_.cert);\n        }\n    }\n\n    if (certs_create == token_cert_ns::naming)\n    {\n        // check symbol is valid.\n        auto pos = argument_.symbol.find(\".\");\n        if (pos == std::string::npos)\n        {\n            throw token_symbol_name_exception(\"invalid naming cert symbol \" + argument_.symbol + \", it should contain a dot '.'\");\n        }\n\n        auto &&domain = token_cert::get_domain(argument_.symbol);\n        if (!token_cert::is_valid_domain(domain))\n        {\n            throw token_symbol_name_exception(\"invalid naming cert symbol \" + argument_.symbol + \", it should contain a valid domain!\");\n        }\n\n        // check domain naming cert not exist.\n        if (blockchain.is_token_cert_exist(argument_.symbol, token_cert_ns::naming))\n        {\n            throw token_cert_existed_exception(\n                \"naming cert '\" + argument_.symbol + \"' already exists on the blockchain!\");\n        }\n\n        // check token not exist.\n        if (blockchain.is_token_exist(argument_.symbol, false))\n        {\n            throw token_symbol_existed_exception(\n                \"token symbol '\" + argument_.symbol + \"' already exists on the blockchain!\");\n        }\n\n        // check domain cert belong to this wallet.\n        bool exist = blockchain.is_token_cert_exist(domain, token_cert_ns::domain);\n        if (!exist)\n        {\n            throw token_cert_notfound_exception(\"no domain cert '\" + domain + \"' found!\");\n        }\n\n        auto cert = blockchain.get_wallet_token_cert(auth_.name, domain, token_cert_ns::domain);\n        if (!cert)\n        {\n            throw token_cert_notowned_exception(\"no domain cert '\" + domain + \"' owned by \" + auth_.name);\n        }\n    }\n\n    // receiver\n    std::vector<receiver_record> receiver{\n        {to_address, argument_.symbol, 0, 0,\n         certs_create, utxo_attach_type::token_cert_issue,\n         asset(\"\", to_uid)}};\n\n    if (certs_create == token_cert_ns::naming)\n    {\n        auto &&domain = token_cert::get_domain(argument_.symbol);\n        receiver.push_back(\n            {to_address, domain, 0, 0,\n             token_cert_ns::domain, utxo_attach_type::token_cert,\n             asset(\"\", to_uid)});\n    }\n\n    auto helper = issuing_token_cert(*this, blockchain,\n                                     std::move(auth_.name), std::move(auth_.auth),\n                                     std::move(to_address), std::move(argument_.symbol),\n                                     std::move(receiver), argument_.fee);\n\n    helper.exec();\n\n    // json output\n    auto tx = helper.get_transaction();\n    jv_output = config::json_helper(get_api_version()).prop_tree(tx, true);\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/registersecondarytoken.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/registersecondarytoken.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\n/************************ registersecondarytoken *************************/\nconsole_result registersecondarytoken::invoke(Json::Value &jv_output,\n                                              libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n\n    blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n    blockchain.uppercase_symbol(argument_.symbol);\n\n    // check token symbol\n    check_token_symbol(argument_.symbol);\n\n    auto to_uid = argument_.to;\n    auto to_address = get_address_from_uid(to_uid, blockchain);\n    if (!blockchain.is_valid_address(to_address))\n        throw address_invalid_exception{\"invalid uid parameter! \" + to_uid};\n\n    if (!blockchain.get_wallet_address(auth_.name, to_address))\n        throw address_dismatch_wallet_exception{\"target uid does not match wallet. \" + to_uid};\n\n    auto token = blockchain.get_issued_token(argument_.symbol);\n    if (!token)\n    {\n        throw token_symbol_notfound_exception{\"token symbol does not exist on the blockchain\"};\n    }\n\n    auto secondaryissue_threshold = token->get_secondaryissue_threshold();\n    if (!token_detail::is_secondaryissue_legal(secondaryissue_threshold))\n        throw token_secondaryissue_threshold_exception{\"token is not allowed to do secondary issue, or the threshold is illegal.\"};\n\n    if (blockchain.is_token_cert_exist(argument_.symbol, token_cert_ns::issue))\n    {\n        // check whether it belongs to the wallet.\n        auto cert = blockchain.get_wallet_token_cert(auth_.name, argument_.symbol, token_cert_ns::issue);\n        if (!cert)\n        {\n            throw token_cert_notowned_exception(\"no issue cert \" + argument_.symbol + \" owned by \" + auth_.name);\n        }\n    }\n    else if (blockchain.chain_settings().use_testnet_rules)\n    {\n        // if not exist, then issue one. only happen in testnet.\n    }\n    else\n    {\n        throw token_cert_notfound_exception{\"no issue cert '\" + argument_.symbol + \"' found!\"};\n    }\n\n    auto total_volume = blockchain.get_token_volume(argument_.symbol);\n    if (total_volume > max_uint64 - argument_.volume)\n        throw token_amount_exception{\"secondaryissue volume cannot exceed maximum value\"};\n\n    uint64_t token_volume_of_threshold = 0;\n    if (!token_detail::is_secondaryissue_freely(secondaryissue_threshold))\n    {\n        token_volume_of_threshold = (uint64_t)(((double)total_volume) / 100 * secondaryissue_threshold);\n    }\n\n    // receiver\n    std::vector<receiver_record> receiver{\n        {to_address, argument_.symbol, 0, token_volume_of_threshold,\n         utxo_attach_type::token_secondaryissue, asset(\"\", to_uid)},\n        {to_address, argument_.symbol, 0, 0, token_cert_ns::issue,\n         utxo_attach_type::token_cert, asset(\"\", to_uid)}};\n\n    auto issue_helper = secondary_issuing_token(*this, blockchain,\n                                                std::move(auth_.name), std::move(auth_.auth),\n                                                std::move(to_address), std::move(argument_.symbol),\n                                                std::move(option_.attenuation_model_param),\n                                                std::move(receiver), argument_.fee, argument_.volume);\n\n    issue_helper.exec();\n\n    // json output\n    auto tx = issue_helper.get_transaction();\n    jv_output = config::json_helper(get_api_version()).prop_tree(tx, true);\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/registertoken.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/registertoken.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n#include <UChainService/txs/token/token_detail.hpp>\n\nusing std::placeholders::_1;\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nconsole_result registertoken::invoke(Json::Value &jv_output,\n                                     libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n\n    blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n    blockchain.uppercase_symbol(argument_.symbol);\n\n    // check token symbol\n    check_token_symbol(argument_.symbol);\n\n    // check fee\n    if (argument_.fee < bc::min_fee_to_issue_token)\n    {\n        throw token_issue_poundage_exception{\n            \"issue token fee less than \" + std::to_string(bc::min_fee_to_issue_token) + \" that's \" + std::to_string(bc::min_fee_to_issue_token / 100000000) + \" UCNs\"};\n    }\n\n    if (argument_.percentage < bc::min_fee_percentage_to_miner || argument_.percentage > 100)\n    {\n        throw token_issue_poundage_exception{\n            \"issue token minimum percentage of fee to miner less than \" + std::to_string(bc::min_fee_percentage_to_miner) + \" or greater than 100.\"};\n    }\n\n    // fail if token is already in blockchain\n    if (blockchain.is_token_exist(argument_.symbol, false))\n    {\n        throw token_symbol_existed_exception{\n            \"token \" + argument_.symbol + \" already exists in blockchain\"};\n    }\n\n    // local database token check\n    auto sh_token = blockchain.get_wallet_unissued_token(auth_.name, argument_.symbol);\n    if (!sh_token)\n    {\n        throw token_symbol_notfound_exception{\"token \" + argument_.symbol + \" not found,createtoken first\"};\n    }\n\n    auto to_uid = sh_token->get_issuer();\n    auto to_address = get_address_from_uid(to_uid, blockchain);\n    if (!blockchain.is_valid_address(to_address))\n    {\n        throw address_invalid_exception{\"invalid token issuer \" + to_uid};\n    }\n\n    std::string cert_symbol;\n    token_cert_type cert_type = token_cert_ns::none;\n    bool is_domain_cert_exist = false;\n\n    // domain cert check\n    auto &&domain = token_cert::get_domain(argument_.symbol);\n    if (token_cert::is_valid_domain(domain))\n    {\n        bool exist = blockchain.is_token_cert_exist(domain, token_cert_ns::domain);\n        if (!exist)\n        {\n            // domain cert does not exist, issue new domain cert to this address\n            is_domain_cert_exist = false;\n            cert_type = token_cert_ns::domain;\n            cert_symbol = domain;\n        }\n        else\n        {\n            // if domain cert exists then check whether it belongs to the wallet.\n            is_domain_cert_exist = true;\n            auto cert = blockchain.get_wallet_token_cert(auth_.name, domain, token_cert_ns::domain);\n            if (cert)\n            {\n                cert_symbol = domain;\n                cert_type = cert->get_type();\n            }\n            else\n            {\n                // if domain cert does not belong to the wallet then check naming cert\n                exist = blockchain.is_token_cert_exist(argument_.symbol, token_cert_ns::naming);\n                if (!exist)\n                {\n                    throw token_cert_notfound_exception{\n                        \"Domain cert \" + argument_.symbol + \" exists on the blockchain and is not owned by \" + auth_.name};\n                }\n                else\n                {\n                    cert = blockchain.get_wallet_token_cert(auth_.name, argument_.symbol, token_cert_ns::naming);\n                    if (!cert)\n                    {\n                        throw token_cert_notowned_exception{\n                            \"No domain cert or naming cert owned by \" + auth_.name};\n                    }\n\n                    cert_symbol = argument_.symbol;\n                    cert_type = cert->get_type();\n                }\n            }\n        }\n    }\n\n    // receiver\n    std::vector<receiver_record> receiver{\n        {to_address, argument_.symbol, 0, 0, utxo_attach_type::token_issue, asset(\"\", to_uid)}};\n\n    // token_cert utxo\n    auto certs = sh_token->get_token_cert_mask();\n    if (!certs.empty())\n    {\n        for (auto each_cert_type : certs)\n        {\n            receiver.push_back(\n                {to_address, argument_.symbol, 0, 0,\n                 each_cert_type, utxo_attach_type::token_cert_autoissue, asset(\"\", to_uid)});\n        }\n    }\n\n    // domain cert or naming cert\n    if (token_cert::is_valid_domain(domain))\n    {\n        receiver.push_back(\n            {to_address, cert_symbol, 0, 0, cert_type,\n             (is_domain_cert_exist ? utxo_attach_type::token_cert : utxo_attach_type::token_cert_autoissue),\n             asset(\"\", to_uid)});\n    }\n\n    auto issue_helper = issuing_token(\n        *this, blockchain,\n        std::move(auth_.name), std::move(auth_.auth),\n        \"\", std::move(argument_.symbol),\n        std::move(option_.attenuation_model_param),\n        std::move(receiver), argument_.fee, argument_.percentage);\n\n    issue_helper.exec();\n\n    // json output\n    auto tx = issue_helper.get_transaction();\n    jv_output = config::json_helper(get_api_version()).prop_tree(tx, true);\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/registeruid.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChainService/api/command/commands/registeruid.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nconsole_result registeruid::invoke(Json::Value &jv_output,\n                                   libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    auto acc = blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    // check uid symbol\n    check_uid_symbol(argument_.symbol, true);\n\n    if (blockchain.is_valid_address(argument_.symbol))\n    {\n        throw address_invalid_exception{\"symbol cannot be an address!\"};\n    }\n\n    // check fee\n    if (argument_.fee < bc::min_fee_to_register_uid)\n    {\n        throw uid_register_poundage_exception{\n            \"register uid: fee less than \" + std::to_string(bc::min_fee_to_register_uid) + \" that's \" + std::to_string(bc::min_fee_to_register_uid / 100000000) + \" UCNs\"};\n    }\n\n    if (argument_.percentage < bc::min_fee_percentage_to_miner || argument_.percentage > 100)\n    {\n        throw uid_register_poundage_exception{\n            \"register uid minimum percentage of fee to miner less than \" + std::to_string(bc::min_fee_percentage_to_miner) + \" or greater than 100.\"};\n    }\n\n    // check address\n    if (!blockchain.is_valid_address(argument_.address))\n    {\n        throw address_invalid_exception{\"invalid address parameter!\"};\n    }\n\n    if (!blockchain.get_wallet_address(auth_.name, argument_.address))\n    {\n        throw address_dismatch_wallet_exception{\n            \"address \" + argument_.address + \" is not owned by \" + auth_.name};\n    }\n\n    // fail if uid is already in blockchain\n    if (blockchain.is_uid_exist(argument_.symbol))\n        throw uid_symbol_existed_exception{\"uid symbol already exists on the blockchain\"};\n\n    // fail if address is already binded with uid in blockchain\n    if (blockchain.is_address_registered_uid(argument_.address))\n        throw uid_symbol_existed_exception{\"address is already binded with some uid on the blockchain\"};\n\n    wallet_multisig acc_multisig;\n    bool is_multisig_address = blockchain.is_script_address(argument_.address);\n    if (is_multisig_address)\n    {\n        auto multisig_vec = acc->get_multisig(argument_.address);\n        if (!multisig_vec || multisig_vec->empty())\n        {\n            throw multisig_notfound_exception{\"multisig of address does not found.\"};\n        }\n\n        acc_multisig = *(multisig_vec->begin());\n    }\n\n    // receiver\n    std::vector<receiver_record> receiver{\n        {argument_.address, argument_.symbol, 0, 0, utxo_attach_type::uid_register, asset()}};\n\n    auto register_helper = registering_uid(\n        *this, blockchain, std::move(auth_.name), std::move(auth_.auth),\n        std::move(argument_.address), std::move(argument_.symbol),\n        std::move(receiver), argument_.fee, argument_.percentage,\n        std::move(acc_multisig));\n\n    register_helper.exec();\n\n    // output json\n    auto &&tx = register_helper.get_transaction();\n    if (is_multisig_address)\n    {\n        jv_output = config::json_helper(get_api_version()).prop_list_of_rawtx(tx, false, true);\n    }\n    else\n    {\n        jv_output = config::json_helper(get_api_version()).prop_tree(tx, true);\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/sendfrom.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/sendfrom.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nconsole_result sendfrom::invoke(Json::Value &jv_output,\n                                libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    asset attach;\n    std::string from_address = get_address(argument_.from, attach, true, blockchain);\n    std::string to_address = get_address(argument_.to, attach, false, blockchain);\n    std::string change_address = get_address(option_.change, blockchain);\n\n    if (argument_.amount <= 0)\n    {\n        throw argument_legality_exception(\"invalid amount parameter!\");\n    }\n\n    //should own the address\n    if (!change_address.empty() && !blockchain.get_wallet_address(auth_.name, change_address))\n        throw wallet_authority_exception{\"change address not belongs to you.\"};\n\n    // receiver\n    std::vector<receiver_record> receiver{\n        {to_address, \"\", argument_.amount, 0, utxo_attach_type::ucn, attach}};\n\n    if (!option_.memo.empty())\n    {\n        if (option_.memo.size() >= 255)\n        {\n            throw argument_size_invalid_exception{\"memo length out of bounds.\"};\n        }\n\n        receiver.push_back({to_address, \"\", 0, 0, utxo_attach_type::message,\n                            asset(0, 0, blockchain_message(option_.memo))});\n    }\n\n    auto send_helper = sending_ucn(*this, blockchain,\n                                   std::move(auth_.name), std::move(auth_.auth),\n                                   std::move(from_address), std::move(receiver),\n                                   std::move(change_address), option_.fee);\n\n    send_helper.exec();\n\n    // json output\n    auto tx = send_helper.get_transaction();\n    jv_output = config::json_helper(get_api_version()).prop_tree(tx, true);\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/sendrawtx.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChainService/api/command/commands/sendrawtx.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\nconsole_result sendrawtx::invoke(Json::Value &jv_output,\n                                 libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    tx_type tx_ = argument_.transaction;\n\n    uint64_t outputs_ucn_val = tx_.total_output_value();\n    uint64_t inputs_ucn_val = 0;\n    if (!blockchain.get_tx_inputs_ucn_value(tx_, inputs_ucn_val))\n        throw tx_validate_exception{\"get transaction inputs ucn value error!\"};\n\n    // check raw tx fee range\n    if (inputs_ucn_val <= outputs_ucn_val)\n        throw tx_validate_exception{\"no enough transaction fee\"};\n    base_transfer_common::check_fee_in_valid_range(inputs_ucn_val - outputs_ucn_val);\n\n    if (blockchain.validate_tx_engine(tx_))\n        throw tx_validate_exception{\"validate transaction failure\"};\n\n    if (blockchain.broadcast_transaction(tx_))\n        throw tx_broadcast_exception{\"broadcast transaction failure\"};\n\n    if (get_api_version() <= 2)\n    {\n        jv_output[\"hash\"] = encode_hash(tx_.hash());\n    }\n    else\n    {\n        jv_output = encode_hash(tx_.hash());\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/sendto.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/sendto.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nconsole_result sendto::invoke(Json::Value &jv_output,\n                              libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    asset attach;\n    std::string to_address = get_address(argument_.to, attach, false, blockchain);\n    std::string change_address = get_address(option_.change, blockchain);\n\n    if (argument_.amount <= 0)\n    {\n        throw argument_legality_exception(\"invalid amount parameter!\");\n    }\n\n    //should own the address\n    if (!change_address.empty() && !blockchain.get_wallet_address(auth_.name, change_address))\n        throw wallet_authority_exception{\"change address not belongs to you.\"};\n\n    // receiver\n    std::vector<receiver_record> receiver{\n        {to_address, \"\", argument_.amount, 0, utxo_attach_type::ucn, attach}};\n\n    if (!option_.memo.empty())\n    {\n        if (option_.memo.size() >= 255)\n        {\n            throw argument_size_invalid_exception{\"memo length out of bounds.\"};\n        }\n\n        receiver.push_back({to_address, \"\", 0, 0, utxo_attach_type::message,\n                            asset(0, 0, blockchain_message(option_.memo))});\n    }\n\n    auto send_helper = sending_ucn(*this, blockchain,\n                                   std::move(auth_.name), std::move(auth_.auth),\n                                   \"\", std::move(receiver),\n                                   std::move(change_address), option_.fee);\n\n    send_helper.exec();\n\n    // json output\n    auto tx = send_helper.get_transaction();\n    jv_output = config::json_helper(get_api_version()).prop_tree(tx, true);\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/sendtokenfrom.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/sendtokenfrom.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nconsole_result sendtokenfrom::invoke(Json::Value &jv_output,\n                                     libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n    blockchain.uppercase_symbol(argument_.symbol);\n\n    // check token symbol\n    check_token_symbol(argument_.symbol);\n\n    asset attach;\n    std::string from_address = get_address(argument_.from, attach, true, blockchain);\n\n    check_token_symbol_with_miner(argument_.symbol, node.miner(), from_address);\n    std::string to_address = get_address(argument_.to, attach, false, blockchain);\n    std::string change_address = get_address(option_.change, blockchain);\n\n    if (argument_.amount <= 0)\n    {\n        throw token_amount_exception(\"invalid amount parameter!\");\n    }\n\n    if (!option_.memo.empty() && option_.memo.size() >= 255)\n    {\n        throw argument_size_invalid_exception{\"memo length out of bounds.\"};\n    }\n\n    if (!change_address.empty() && !blockchain.get_wallet_address(auth_.name, change_address))\n        throw wallet_authority_exception{\"change address not belongs to you.\"};\n\n    // receiver\n    utxo_attach_type attach_type = option_.attenuation_model_param.empty()\n                                       ? utxo_attach_type::token_transfer\n                                       : utxo_attach_type::token_attenuation_transfer;\n    std::vector<receiver_record> receiver{\n        {to_address, argument_.symbol, 0, argument_.amount, attach_type, attach}};\n    auto send_helper = sending_token(*this, blockchain,\n                                     std::move(auth_.name), std::move(auth_.auth),\n                                     std::move(from_address), std::move(argument_.symbol),\n                                     std::move(option_.attenuation_model_param),\n                                     std::move(receiver), option_.fee,\n                                     std::move(option_.memo), std::move(change_address));\n\n    send_helper.exec();\n\n    // json output\n    auto tx = send_helper.get_transaction();\n    jv_output = config::json_helper(get_api_version()).prop_tree(tx, true);\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/sendtokento.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChainService/api/command/commands/sendtokento.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nconsole_result sendtokento::invoke(Json::Value &jv_output,\n                                   libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n    blockchain.uppercase_symbol(argument_.symbol);\n\n    if (!option_.memo.empty() && option_.memo.size() >= 255)\n    {\n        throw argument_size_invalid_exception{\"memo length out of bounds.\"};\n    }\n\n    // check token symbol\n    check_token_symbol(argument_.symbol);\n\n    check_token_symbol_with_method(argument_.symbol);\n\n    if (!argument_.amount)\n    {\n        throw token_amount_exception{\"invalid token amount parameter!\"};\n    }\n\n    asset attach;\n    std::string to_address = get_address(argument_.to, attach, false, blockchain);\n    std::string change_address = get_address(option_.change, blockchain);\n\n    // receiver\n    utxo_attach_type attach_type = option_.attenuation_model_param.empty()\n                                       ? utxo_attach_type::token_transfer\n                                       : utxo_attach_type::token_attenuation_transfer;\n    std::vector<receiver_record> receiver{\n        {to_address, argument_.symbol, 0, argument_.amount, attach_type, attach}};\n    auto send_helper = sending_token(*this, blockchain,\n                                     std::move(auth_.name), std::move(auth_.auth),\n                                     \"\", std::move(argument_.symbol),\n                                     std::move(option_.attenuation_model_param),\n                                     std::move(receiver), option_.fee,\n                                     std::move(option_.memo),\n                                     std::move(change_address));\n\n    send_helper.exec();\n\n    // json output\n    auto tx = send_helper.get_transaction();\n    jv_output = config::json_helper(get_api_version()).prop_tree(tx, true);\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/sendtomulti.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/sendtomulti.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nconsole_result sendtomulti::invoke(Json::Value &jv_output,\n                                   libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    // receiver\n    std::vector<receiver_record> receiver;\n\n    for (auto &each : argument_.receivers)\n    {\n        colon_delimited2_item<std::string, uint64_t> item(each);\n\n        asset attach;\n        std::string address = get_address(item.first(), attach, false, blockchain);\n        if (item.second() <= 0)\n        {\n            throw argument_legality_exception(\"invalid amount parameter for \" + item.first());\n        }\n\n        receiver.push_back({address, \"\", item.second(), 0, utxo_attach_type::ucn, attach});\n    }\n\n    // change address\n    std::string change_address = get_address(option_.change, blockchain);\n    //should own the address\n    if (!change_address.empty() && !blockchain.get_wallet_address(auth_.name, change_address))\n        throw wallet_authority_exception{\"change address not belongs to you.\"};\n\n    auto send_helper = sending_ucn(*this, blockchain,\n                                   std::move(auth_.name), std::move(auth_.auth),\n                                   \"\", std::move(receiver),\n                                   std::move(change_address), option_.fee);\n\n    send_helper.exec();\n\n    // json output\n    auto tx = send_helper.get_transaction();\n    jv_output = config::json_helper(get_api_version()).prop_tree(tx, true);\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/setminingwallet.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/setminingwallet.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ setminingwallet *************************/\n\nconsole_result setminingwallet::invoke(Json::Value &jv_output,\n                                       libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    auto &miner = node.miner();\n\n    blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    auto pvaddr = blockchain.get_wallet_addresses(auth_.name);\n    if (!pvaddr)\n        throw address_list_nullptr_exception{\"nullptr for address list\"};\n\n#if 0 // no random address required for miner\n    auto pubkey = pvaddr->begin()->get_pub_key();\n#else\n    auto is_found = blockchain.get_wallet_address(auth_.name, argument_.payment_address.encoded());\n    if (!is_found)\n        throw address_dismatch_wallet_exception{\"address does not match wallet.\"};\n#endif\n\n    auto ret = miner.set_miner_payment_address(argument_.payment_address);\n    if (ret)\n    {\n        jv_output = \"Address [\" + argument_.payment_address.encoded() + \"] setted.\";\n    }\n    else\n    {\n        throw unknown_error_exception{\"set mining wallet solo mining got an error\"};\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showaddresses.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/showaddresses.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\n/************************ showaddresses *************************/\n\nconsole_result showaddresses::invoke(Json::Value &jv_output,\n                                     libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    auto &aroot = jv_output;\n    Json::Value addresses;\n\n    auto vaddr = blockchain.get_wallet_addresses(auth_.name);\n    if (!vaddr)\n        throw address_list_nullptr_exception{\"nullptr for address list\"};\n\n    for (auto &it : *vaddr)\n    {\n        addresses.append(it.get_address());\n    }\n\n    if (get_api_version() == 1 && addresses.isNull())\n    { // compatible for v1\n        aroot[\"addresses\"] = \"\";\n    }\n    else if (get_api_version() <= 2)\n    {\n        aroot[\"addresses\"] = addresses;\n    }\n    else\n    {\n        if (addresses.isNull())\n            addresses.resize(0);\n\n        aroot = addresses;\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showaddresstoken.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/showaddresstoken.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\n/************************ showaddresstoken *************************/\n\nconsole_result showaddresstoken::invoke(Json::Value &jv_output,\n                                        libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    if (!blockchain.is_valid_address(argument_.address))\n        throw address_invalid_exception{\"invalid address!\"};\n\n    if (!option_.symbol.empty())\n    {\n        // check token symbol\n        check_token_symbol(option_.symbol);\n    }\n\n    std::string json_key;\n    Json::Value json_value;\n    auto json_helper = config::json_helper(get_api_version());\n    ;\n\n    if (option_.is_cert)\n    { // only get token certs\n        json_key = \"tokencerts\";\n\n        auto sh_vec = std::make_shared<token_cert::list>();\n        sync_fetch_token_cert_balance(argument_.address, \"\", blockchain, sh_vec);\n        std::sort(sh_vec->begin(), sh_vec->end());\n        for (auto &elem : *sh_vec)\n        {\n            if (!option_.symbol.empty() && option_.symbol != elem.get_symbol())\n                continue;\n\n            Json::Value token_cert = json_helper.prop_list(elem);\n            json_value.append(token_cert);\n        }\n    }\n    else if (option_.deposited)\n    {\n        json_key = \"tokens\";\n\n        auto sh_vec = std::make_shared<token_deposited_balance::list>();\n        sync_fetch_token_deposited_balance(argument_.address, blockchain, sh_vec);\n        std::sort(sh_vec->begin(), sh_vec->end());\n\n        for (auto &elem : *sh_vec)\n        {\n            if (!option_.symbol.empty() && option_.symbol != elem.symbol)\n                continue;\n\n            auto issued_token = blockchain.get_issued_token(elem.symbol);\n            if (!issued_token)\n            {\n                continue;\n            }\n\n            Json::Value token_data = json_helper.prop_list(elem, *issued_token);\n            token_data[\"status\"] = \"unspent\";\n            json_value.append(token_data);\n        }\n    }\n    else\n    {\n        json_key = \"tokens\";\n\n        auto sh_vec = std::make_shared<token_balances::list>();\n        sync_fetch_token_balance(argument_.address, true, blockchain, sh_vec);\n        std::sort(sh_vec->begin(), sh_vec->end());\n        for (auto &elem : *sh_vec)\n        {\n            if (!option_.symbol.empty() && option_.symbol != elem.symbol)\n                continue;\n\n            auto issued_token = blockchain.get_issued_token(elem.symbol);\n            if (!issued_token)\n            {\n                continue;\n            }\n            Json::Value token_data = json_helper.prop_list(elem, *issued_token);\n            token_data[\"status\"] = \"unspent\";\n            json_value.append(token_data);\n        }\n    }\n\n    if (get_api_version() == 1 && json_value.isNull())\n    { //compatible for v1\n        jv_output[json_key] = \"\";\n    }\n    else if (get_api_version() <= 2)\n    {\n        jv_output[json_key] = json_value;\n    }\n    else\n    {\n        if (json_value.isNull())\n            json_value.resize(0);\n\n        jv_output = json_value;\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showaddressucn.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <jsoncpp/json/json.h>\n#include <UChainService/api/command/base_helper.hpp>\n#include <UChainService/api/command/commands/showaddressucn.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\n/************************ showaddressucn *************************/\n\nconsole_result showaddressucn::invoke(Json::Value &jv_output,\n                                      libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    auto &addr = argument_.address;\n    bc::explorer::commands::balances addr_balance{0, 0, 0, 0};\n\n    sync_fetchbalance(addr, blockchain, addr_balance);\n\n    Json::Value jv;\n    jv[\"address\"] = addr.encoded();\n    if (get_api_version() == 1)\n    {\n        // compatible for version 1: as string value\n        jv[\"confirmed\"] = std::to_string(addr_balance.confirmed_balance);\n        jv[\"received\"] = std::to_string(addr_balance.total_received);\n        jv[\"unspent\"] = std::to_string(addr_balance.unspent_balance);\n        jv[\"frozen\"] = std::to_string(addr_balance.frozen_balance);\n    }\n    else\n    {\n        jv[\"confirmed\"] = addr_balance.confirmed_balance;\n        jv[\"received\"] = addr_balance.total_received;\n        jv[\"unspent\"] = addr_balance.unspent_balance;\n        jv[\"frozen\"] = addr_balance.frozen_balance;\n    }\n\n    if (get_api_version() <= 2)\n    {\n        jv_output[\"balance\"] = jv;\n    }\n    else\n    {\n        jv_output = jv;\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showbalance.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/showbalance.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\n/************************ showbalance *************************/\n\nconsole_result showbalance::invoke(Json::Value &jv_output,\n                                   libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    auto &aroot = jv_output;\n\n    auto vaddr = blockchain.get_wallet_addresses(auth_.name);\n    if (!vaddr)\n        throw address_list_nullptr_exception{\"nullptr for address list\"};\n\n    uint64_t total_confirmed = 0;\n    uint64_t total_received = 0;\n    uint64_t total_unspent = 0;\n    uint64_t total_frozen = 0;\n\n    for (auto &i : *vaddr)\n    {\n        balances addr_balance{0, 0, 0, 0};\n        auto waddr = bc::wallet::payment_address(i.get_address());\n        sync_fetchbalance(waddr, blockchain, addr_balance);\n\n        total_confirmed += addr_balance.confirmed_balance;\n        total_received += addr_balance.total_received;\n        total_unspent += addr_balance.unspent_balance;\n        total_frozen += addr_balance.frozen_balance;\n    }\n\n    aroot[\"total_confirmed\"] = total_confirmed;\n    aroot[\"total_received\"] = total_received;\n    aroot[\"total_unspent\"] = total_unspent;\n    aroot[\"total_available\"] = (total_unspent - total_frozen);\n    aroot[\"total_frozen\"] = total_frozen;\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showbalances.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/showbalances.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nusing namespace bc::explorer::config;\n\n/************************ showbalances *************************/\n\nconsole_result showbalances::invoke(Json::Value &jv_output,\n                                    libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    Json::Value all_balances;\n\n    auto vaddr = blockchain.get_wallet_addresses(auth_.name);\n    if (!vaddr)\n    {\n        throw address_list_nullptr_exception{\"nullptr for address list\"};\n    }\n\n    if (!option_.greater && option_.non_zero)\n    {\n        option_.greater = 1;\n    }\n\n    if (option_.deposited)\n    {\n        auto deposited_balances = std::make_shared<deposited_balance::list>();\n\n        for (auto &i : *vaddr)\n        {\n            auto waddr = bc::wallet::payment_address(i.get_address());\n            sync_fetch_deposited_balance(waddr, blockchain, deposited_balances);\n        }\n\n        for (auto &balance : *deposited_balances)\n        {\n            // non-zero lesser\n            if (option_.lesser)\n            {\n                if (balance.balance > option_.lesser || balance.balance < option_.greater)\n                {\n                    continue;\n                }\n            }\n            else\n            {\n                if (balance.balance < option_.greater)\n                {\n                    continue;\n                }\n            }\n\n            Json::Value json_balance;\n            json_balance[\"address\"] = balance.address;\n            json_balance[\"deposited_balance\"] = balance.balance;\n            json_balance[\"bonus_balance\"] = balance.bonus;\n            json_balance[\"deposited_height\"] = balance.deposited_height;\n            json_balance[\"expiration_height\"] = balance.expiration_height;\n            json_balance[\"tx_hash\"] = balance.tx_hash;\n\n            all_balances.append(json_balance);\n        }\n    }\n    else\n    {\n        for (auto &i : *vaddr)\n        {\n            balances addr_balance{0, 0, 0, 0};\n            auto waddr = bc::wallet::payment_address(i.get_address());\n            sync_fetchbalance(waddr, blockchain, addr_balance);\n\n            // non-zero lesser\n            if (option_.lesser)\n            {\n                if (addr_balance.unspent_balance > option_.lesser || addr_balance.unspent_balance < option_.greater)\n                {\n                    continue;\n                }\n            }\n            else\n            {\n                if (addr_balance.unspent_balance < option_.greater)\n                {\n                    continue;\n                }\n            }\n\n            Json::Value address_balance;\n            address_balance[\"address\"] = i.get_address();\n\n            if (get_api_version() == 1)\n            {\n                address_balance[\"confirmed\"] += addr_balance.confirmed_balance;\n                address_balance[\"received\"] += addr_balance.total_received;\n                address_balance[\"unspent\"] += addr_balance.unspent_balance;\n                address_balance[\"available\"] += (addr_balance.unspent_balance - addr_balance.frozen_balance);\n                address_balance[\"frozen\"] += addr_balance.frozen_balance;\n            }\n            else\n            {\n                address_balance[\"confirmed\"] = addr_balance.confirmed_balance;\n                address_balance[\"received\"] = addr_balance.total_received;\n                address_balance[\"unspent\"] = addr_balance.unspent_balance;\n                address_balance[\"available\"] = (addr_balance.unspent_balance - addr_balance.frozen_balance);\n                address_balance[\"frozen\"] = addr_balance.frozen_balance;\n            }\n\n            if (get_api_version() <= 2)\n            {\n                Json::Value target_balance;\n                target_balance[\"balance\"] = address_balance;\n                all_balances.append(target_balance);\n            }\n            else\n            {\n                all_balances.append(address_balance);\n            }\n        }\n    }\n\n    auto &aroot = jv_output;\n    if (get_api_version() == 1 && all_balances.isNull())\n    { //compatible for v1\n        aroot[\"balances\"] = \"\";\n    }\n    else if (get_api_version() <= 2)\n    {\n        aroot[\"balances\"] = all_balances;\n    }\n    else\n    {\n        if (all_balances.isNull())\n            all_balances.resize(0);\n\n        aroot = all_balances;\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showblock.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/showblock.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showblock *************************/\n\nconsole_result showblock::invoke(Json::Value &jv_output,\n                                 libbitcoin::server::server_node &node)\n{\n    auto json = option_.json;\n    auto tx_json = option_.tx_json;\n\n    // uint64_t max length\n    if (argument_.hash_or_height.size() < 18)\n    {\n\n        // fetch_block via height\n        auto block_height = std::stoull(argument_.hash_or_height);\n\n        std::promise<code> p;\n        auto &blockchain = node.chain_impl();\n        blockchain.fetch_block(block_height, [&p, &jv_output, json, tx_json, this](const code &ec, chain::block::ptr block) {\n            if (ec)\n            {\n                p.set_value(ec);\n                return;\n            }\n\n            if (json)\n            {\n                jv_output = config::json_helper(get_api_version()).prop_tree(*block, json, tx_json);\n            }\n            else\n            {\n                jv_output = config::json_helper(get_api_version()).prop_tree(*block, false, false);\n            }\n            p.set_value(error::success);\n        });\n\n        auto result = p.get_future().get();\n        if (result)\n        {\n            throw block_height_get_exception{result.message()};\n        }\n    }\n\n    else\n    {\n        // fetch_block via hash\n        bc::config::hash256 block_hash(argument_.hash_or_height);\n\n        std::promise<code> p;\n        auto &blockchain = node.chain_impl();\n        blockchain.fetch_block(block_hash, [&p, &jv_output, json, tx_json, this](const code &ec, chain::block::ptr block) {\n            if (ec)\n            {\n                p.set_value(ec);\n                return;\n            }\n\n            if (json)\n            {\n                jv_output = config::json_helper(get_api_version()).prop_tree(*block, json, tx_json);\n            }\n            else\n            {\n                jv_output = config::json_helper(get_api_version()).prop_tree(*block, false, false);\n            }\n            p.set_value(error::success);\n        });\n\n        auto result = p.get_future().get();\n        if (result)\n        {\n            throw block_height_get_exception{result.message()};\n        }\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showblockheader.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <jsoncpp/json/json.h>\n#include <UChain/client.hpp>\n#include <UChain/explorer/callback_state.hpp>\n#include <UChainService/api/command/commands/showblockheader.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/display.hpp>\n#include <UChain/explorer/utility.hpp>\n#include <UChain/explorer/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::client;\nusing namespace bc::explorer::config;\n\n/************************ showblockheader *************************/\n\nconsole_result showblockheader::invoke(Json::Value &jv_output,\n                                       libbitcoin::server::server_node &node)\n{\n\n    uint64_t height = 0;\n    auto &blockchain = node.chain_impl();\n    if (!blockchain.get_last_height(height))\n    {\n        throw block_last_height_get_exception{\"query last height failure.\"};\n    }\n\n    if (option_.height != std::numeric_limits<uint32_t>::max())\n    {\n        height = option_.height;\n    }\n\n    const auto connection = get_connection(*this);\n\n    obelisk_client client(connection);\n\n    if (!client.connect(connection))\n    {\n        throw connection_exception{\"Could not connect to ucd port \" + node.server_settings().public_query_endpoint};\n    }\n\n    encoding json_format{\"json\"};\n    std::ostringstream output;\n    callback_state state(output, output, json_format);\n\n    auto on_done = [this, &jv_output](const chain::header &header) {\n        auto &&jheader = config::json_helper(get_api_version()).prop_tree(header);\n\n        if (get_api_version() <= 2)\n        {\n            if (!jheader.isObject() || !jheader[\"result\"].isObject() || !jheader[\"result\"][\"hash\"].isString())\n            {\n                throw block_hash_get_exception{\"getbestblockhash got parser exception.\"};\n            }\n\n            if (option_.is_getbestblockhash)\n            {\n                auto &&blockhash = jheader[\"result\"][\"hash\"].asString();\n                jv_output = blockhash;\n            }\n            else\n            {\n                if (get_api_version() == 1)\n                {\n                    jv_output = jheader;\n                }\n                else\n                {\n                    jv_output = jheader[\"result\"];\n                }\n            }\n        }\n        else\n        {\n            if (!jheader.isObject() || !jheader[\"hash\"].isString())\n            {\n                throw block_hash_get_exception{\"getbestblockhash parser exception.\"};\n            }\n\n            if (option_.is_getbestblockhash)\n            {\n                auto &&blockhash = jheader[\"hash\"].asString();\n                jv_output = blockhash;\n            }\n            else\n            {\n                jv_output = jheader;\n            }\n        }\n    };\n\n    auto on_error = [&state](const code &error) {\n        state.succeeded(error);\n    };\n\n    // Height is ignored if both are specified.\n    // Use the null_hash as sentinel to determine whether to use height or hash.\n    const hash_digest &hash = option_.hash;\n    if (hash == null_hash)\n    {\n        client.blockchain_fetch_block_header(on_error, on_done, height);\n    }\n    else\n    {\n        client.blockchain_fetch_block_header(on_error, on_done, hash);\n    }\n\n    client.wait();\n\n    return state.get_result();\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showblockheaders.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <jsoncpp/json/json.h>\n#include <UChain/client.hpp>\n#include <UChain/explorer/callback_state.hpp>\n#include <UChainService/api/command/node_method_wrapper.hpp>\n#include <UChainService/api/command/commands/showblockheaders.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/display.hpp>\n#include <UChain/explorer/utility.hpp>\n#include <UChain/explorer/define.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::client;\nusing namespace bc::explorer::config;\n\n/************************ showblockheaders *************************/\n\nconsole_result showblockheaders::invoke(Json::Value &jv_output,\n                                        libbitcoin::server::server_node &node)\n{\n\n    using namespace libbitcoin::config; // for hash256\n    auto &blockchain = node.chain_impl();\n    administrator_required_checker(node, auth_.name, auth_.auth);\n    //blockchain.is_account_passwd_valid(auth_.name, auth_.auth);\n    // height check\n\n    uint64_t end, start, height;\n    if (option_.height.second() > option_.height.first())\n    {\n        start = option_.height.first();\n        end = option_.height.second();\n    }\n    else\n    {\n        start = option_.height.second();\n        end = option_.height.first();\n    }\n    if (blockchain.get_last_height(height))\n    {\n        if (height < end)\n            end = height;\n    }\n    if (end - start > 99)\n    {\n        throw block_height_exception{\"Cannot get block headers much than 100!\"};\n    }\n\n    const auto connection = get_connection(*this);\n\n    obelisk_client client(connection);\n\n    if (!client.connect(connection))\n    {\n        throw connection_exception{\"Could not connect to ucd port \" + node.server_settings().public_query_endpoint};\n    }\n\n    encoding json_format{\"json\"};\n    std::ostringstream output;\n    std::vector<Json::Value> headers;\n    callback_state state(output, output, json_format);\n\n    auto on_done = [this, &jv_output, &end](const std::vector<chain::header> &headers) {\n        for (auto &&header : headers)\n        {\n            auto &&jheader = config::json_helper(get_api_version()).prop_tree(header);\n            if (!jheader.isObject() || !jheader[\"hash\"].isString())\n            {\n                throw block_hash_get_exception{\"getbestblockhash parser exception.\"};\n            }\n            jv_output.append(jheader);\n        }\n    };\n\n    auto on_error = [&state](const code &error) {\n        state.succeeded(error);\n    };\n\n    // Height is ignored if both are specified.\n    // Use the null_hash as sentinel to determine whether to use height or hash.\n\n    client.blockchain_fetch_block_headers(on_error, on_done, start, end, option_.height.second() > option_.height.first());\n    client.wait();\n\n    return state.get_result();\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showblockheight.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChainService/api/command/commands/showblockheight.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n/************************ showblockheight *************************/\n\nconsole_result showblockheight::invoke(Json::Value &jv_output,\n                                       libbitcoin::server::server_node &node)\n{\n    administrator_required_checker(node, auth_.name, auth_.auth);\n\n    jv_output = get_last_height(node);\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showcandidate.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChainService/api/command/commands/showcandidate.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nusing namespace bc::explorer::config;\n\n/************************ showcandidate *************************/\n\nconsole_result showcandidate::invoke(Json::Value &jv_output,\n                                     libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n\n    if (!argument_.symbol.empty())\n    {\n        // check symbol\n        check_candidate_symbol(argument_.symbol);\n    }\n\n    if (argument_.symbol.empty())\n    {\n        throw argument_legality_exception(\"candidate symbol not privided while tracing history!\");\n    }\n\n    // page limit & page index paramenter check\n    if (option_.index < 1)\n    {\n        throw argument_legality_exception{\"page index parameter cannot be zero\"};\n    }\n\n    if (option_.limit < 1)\n    {\n        throw argument_legality_exception{\"page record limit parameter cannot be zero\"};\n    }\n\n    if (option_.limit > 100)\n    {\n        throw argument_legality_exception{\"page record limit cannot be bigger than 100.\"};\n    }\n\n    Json::Value json_value;\n    auto json_helper = config::json_helper(get_api_version());\n\n    bool is_list = true;\n    if (argument_.symbol.empty())\n    {\n        auto sh_vec = blockchain.get_registered_candidates();\n        std::sort(sh_vec->begin(), sh_vec->end());\n        for (auto &elem : *sh_vec)\n        {\n            json_value.append(elem.candidate.get_symbol());\n        }\n\n        if (get_api_version() <= 2)\n        {\n            jv_output[\"candidates\"] = json_value;\n        }\n        else\n        {\n            jv_output = json_value;\n        }\n    }\n    else\n    {\n\n        auto sh_vec = blockchain.get_candidate_history(argument_.symbol, option_.limit, option_.index);\n        for (auto &elem : *sh_vec)\n        {\n            Json::Value token_data = json_helper.prop_list(elem);\n            json_value.append(token_data);\n        }\n\n        if (get_api_version() <= 2)\n        {\n            jv_output[\"candidates\"] = json_value;\n        }\n        else\n        {\n            if (json_value.isNull())\n                json_value.resize(0);\n            jv_output = json_value;\n        }\n\n        jv_output = json_value;\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showcandidates.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/showcandidates.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\n/************************ showcandidates *************************/\n\nconsole_result showcandidates::invoke(Json::Value &jv_output,\n                                      libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    Json::Value json_value;\n    auto json_helper = config::json_helper(get_api_version());\n\n    if (auth_.name.empty())\n    {\n        // no wallet -- list whole tokens in blockchain\n        auto sh_vec = blockchain.get_registered_candidates();\n        if (nullptr != sh_vec)\n        {\n            //vote first and height next.\n            std::sort(sh_vec->begin(), sh_vec->end(), [](const candidate_info &a, const candidate_info &b) {\n                return a.vote > b.vote ? true : a.output_height > b.output_height;\n            });\n            for (auto &elem : *sh_vec)\n            {\n                if (elem.candidate.get_status() == CANDIDATE_STATUS_TRANSFER || elem.candidate.get_status() == CANDIDATE_STATUS_REGISTER)\n                {\n                    //elem.candidate.set_status(CANDIDATE_STATUS_REGISTER);\n                    Json::Value token_data = json_helper.prop_list(elem);\n                    json_value.append(token_data);\n                }\n            }\n        }\n    }\n    else\n    {\n        blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n        // list tokens owned by wallet\n        auto sh_vec = blockchain.get_wallet_candidates(auth_.name);\n        if (nullptr != sh_vec)\n        {\n            std::sort(sh_vec->begin(), sh_vec->end());\n            for (auto &elem : *sh_vec)\n            {\n                // update content if it's transfered from others\n                if (!elem.is_register_status())\n                {\n                    auto token = blockchain.get_registered_candidate(elem.get_symbol());\n                    if (nullptr != token)\n                    {\n                        elem.set_content(token->candidate.get_content());\n                    }\n                }\n\n                Json::Value token_data = json_helper.prop_list(elem, true);\n                json_value.append(token_data);\n            }\n        }\n    }\n\n    /*if (get_api_version() <= 2) {\n        jv_output[\"candidates\"] = json_value;\n    }\n    else {*/\n    if (json_value.isNull())\n        json_value.resize(0);\n\n    jv_output = json_value;\n    //}\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showheaderext.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChainService/api/command/commands/showheaderext.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChain/explorer/json_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\n/************************ showheaderext *************************/\n\nconsole_result showheaderext::invoke(Json::Value &jv_output,\n                                     libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n    if (argument_.number.empty())\n        throw block_height_get_exception{\"Block number or earliest, latest, pending is needed\"};\n\n    chain::header block_header;\n\n    auto &miner = node.miner();\n    auto ret = miner.get_block_header(block_header, argument_.number);\n\n    auto &aroot = jv_output;\n\n    if (ret)\n    {\n\n        auto &&result = config::json_helper(get_api_version()).prop_list(block_header);\n\n        if (get_api_version() == 1)\n        {\n            aroot[\"result\"] = result;\n        }\n        else\n        {\n            aroot = result;\n        }\n    }\n    else\n    {\n        throw block_height_get_exception{\"get block header on height \" + argument_.number + \" failed.\"};\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showinfo.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/version.hpp>\n#include <UChainService/api/command/commands/showinfo.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/node_method_wrapper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\n/************************ showinfo *************************/\n\nconsole_result showinfo::invoke(Json::Value &jv_output,\n                                libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n\n    administrator_required_checker(node, auth_.name, auth_.auth);\n\n    auto sh_vec = blockchain.get_issued_tokens();\n    std::set<std::string> symbols;\n    for (const auto &elem : *sh_vec)\n    {\n        symbols.insert(elem.get_symbol());\n    }\n\n    uint64_t height;\n    //uint64_t rate;\n    uint32_t minercount;\n    //std::string difficulty;\n    bool is_solo_mining;\n    node.miner().get_state(height, minercount, is_solo_mining);\n\n    auto &jv = jv_output;\n    if (get_api_version() <= 2)\n    {\n        jv[\"protocol-version\"] = node.network_settings().protocol;\n        jv[\"wallet-version\"] = UC_EXPLORER_VERSION;\n        jv[\"database-version\"] = UC_DATABASE_VERSION;\n        //jv[\"testnet\"] = blockchain.chain_settings().use_testnet_rules;\n        jv[\"peers\"] = get_connections_count(node);\n\n        jv[\"network-tokens-count\"] = static_cast<uint64_t>(symbols.size());\n        jv[\"wallet-wallet-count\"] = static_cast<uint64_t>(blockchain.get_wallets()->size());\n\n        jv[\"height\"] = height;\n        //jv[\"difficulty\"] = difficulty;\n        jv[\"is-mining\"] = is_solo_mining;\n        jv[\"miner-count\"] = minercount;\n        jv[\"identifier\"] = node.network_settings().identifier;\n        //jv[\"hash-rate\"] = rate;\n    }\n    else\n    {\n        jv[\"protocol_version\"] = node.network_settings().protocol;\n        jv[\"wallet_version\"] = UC_EXPLORER_VERSION;\n        jv[\"database_version\"] = UC_DATABASE_VERSION;\n        //jv[\"testnet\"] = blockchain.chain_settings().use_testnet_rules;\n        jv[\"peers\"] = get_connections_count(node);\n\n        jv[\"token_count\"] = static_cast<uint64_t>(symbols.size());\n        jv[\"wallet_wallet_count\"] = static_cast<uint64_t>(blockchain.get_wallets()->size());\n\n        jv[\"height\"] = height;\n        //jv[\"miner-count\"] = minercount;jv[\"difficulty\"] = difficulty;\n        jv[\"is_mining\"] = is_solo_mining;\n        jv[\"miner-count\"] = minercount;\n        jv[\"identifier\"] = node.network_settings().identifier;\n        //jv[\"hash_rate\"] = rate;\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showminers.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/showminers.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/consensus/miner.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\n/************************ showminers *************************/\n\nconsole_result showminers::invoke(Json::Value &jv_output,\n                                  libbitcoin::server::server_node &node)\n{\n    administrator_required_checker(node, auth_.name, auth_.auth);\n\n    auto &aroot = jv_output;\n    Json::Value miners;\n    auto json_helper = config::json_helper(get_api_version());\n\n    auto sh_vec = node.miner().get_miners();\n    for (auto &elem : sh_vec)\n    {\n        Json::Value token_data = json_helper.prop_list(elem, true, true);\n        miners.append(token_data);\n    }\n\n    if (miners.isNull())\n        miners.resize(0);\n\n    aroot = miners;\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showmininginfo.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChainService/api/command/node_method_wrapper.hpp>\n#include <UChainService/api/command/commands/showmininginfo.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\n/************************ showmininginfo *************************/\n\nconsole_result showmininginfo::invoke(Json::Value &jv_output,\n                                      libbitcoin::server::server_node &node)\n{\n    administrator_required_checker(node, auth_.name, auth_.auth);\n\n    uint64_t height, rate;\n    std::string difficulty;\n    bool is_mining;\n\n    auto &miner = node.miner();\n    //miner.get_state(height, rate, difficulty, is_mining);\n\n    if (get_api_version() <= 2)\n    {\n        auto &aroot = jv_output;\n        Json::Value info;\n        info[\"is-mining\"] = is_mining;\n        info[\"height\"] += height;\n        info[\"rate\"] += rate;\n        info[\"difficulty\"] = difficulty;\n        aroot[\"mining-info\"] = info;\n    }\n    else\n    {\n        jv_output[\"is_mining\"] = is_mining;\n        jv_output[\"height\"] += height;\n        jv_output[\"rate\"] += rate;\n        jv_output[\"difficulty\"] = difficulty;\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showmultisigaddresses.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/showmultisigaddresses.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nusing namespace bc::explorer::config;\n\nconsole_result showmultisigaddresses::invoke(Json::Value &jv_output,\n                                             libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    // parameter wallet name check\n    auto acc = blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    Json::Value nodes;\n    auto multisig_vec = acc->get_multisig_vec();\n    auto helper = config::json_helper(get_api_version());\n    for (auto &acc_multisig : multisig_vec)\n    {\n        Json::Value node = helper.prop_list(acc_multisig);\n        nodes.append(node);\n    }\n\n    if (get_api_version() == 1 && nodes.isNull())\n    { // compatible for v1\n        jv_output[\"multisig\"] = \"\";\n    }\n    else if (get_api_version() <= 2)\n    {\n        jv_output[\"multisig\"] = nodes;\n    }\n    else\n    {\n        if (nodes.isNull())\n            nodes.resize(0);\n\n        jv_output = nodes;\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showpeers.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/node/p2p_node.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/showpeers.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/node_method_wrapper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\n/************************ showpeers *************************/\n\nconsole_result showpeers::invoke(Json::Value &jv_output,\n                                 libbitcoin::server::server_node &node)\n{\n    administrator_required_checker(node, auth_.name, auth_.auth);\n\n    Json::Value array;\n    for (auto authority : node.connections_ptr()->authority_list())\n    {\n        // invalid authority\n        if (authority.to_hostname() == \"[::]\" && authority.port() == 0)\n            continue;\n        array.append(authority.to_string());\n    }\n\n    if (get_api_version() <= 2)\n    {\n        auto &root = jv_output;\n        root[\"peers\"] = array;\n    }\n    else\n    {\n        if (array.isNull())\n            array.resize(0);\n\n        jv_output = array;\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showtoken.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChainService/api/command/commands/showtoken.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\n/************************ showtoken *************************/\n\nconsole_result showtoken::invoke(Json::Value &jv_output,\n                                 libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n\n    if (!argument_.symbol.empty())\n    {\n        // check token symbol\n        blockchain.uppercase_symbol(argument_.symbol);\n        check_token_symbol(argument_.symbol);\n    }\n\n    std::string json_key;\n    Json::Value json_value;\n    auto json_helper = config::json_helper(get_api_version());\n\n    if (option_.is_cert)\n    { // only get token certs\n        json_key = \"tokencerts\";\n\n        // get token cert in blockchain\n        auto sh_vec = blockchain.get_issued_token_certs();\n        if (argument_.symbol.empty())\n        {\n            std::set<std::string> symbols;\n            std::sort(sh_vec->begin(), sh_vec->end());\n            for (auto &elem : *sh_vec)\n            {\n                // get rid of duplicate symbols\n                if (!symbols.count(elem.get_symbol()))\n                {\n                    symbols.insert(elem.get_symbol());\n                    json_value.append(elem.get_symbol());\n                }\n            }\n        }\n        else\n        {\n            auto result_vec = std::make_shared<token_cert::list>();\n            for (auto &cert : *sh_vec)\n            {\n                if (argument_.symbol != cert.get_symbol())\n                {\n                    continue;\n                }\n\n                result_vec->push_back(cert);\n            }\n\n            std::sort(result_vec->begin(), result_vec->end());\n            for (auto &elem : *result_vec)\n            {\n                Json::Value token_data = json_helper.prop_list(elem);\n                json_value.append(token_data);\n            }\n        }\n    }\n    else\n    {\n        json_key = \"tokens\";\n\n        // get token in blockchain\n        auto sh_vec = blockchain.get_issued_tokens(argument_.symbol);\n        if (argument_.symbol.empty())\n        {\n            std::sort(sh_vec->begin(), sh_vec->end());\n            std::set<std::string> symbols;\n            for (auto &elem : *sh_vec)\n            {\n                // get rid of duplicate symbols\n                if (!symbols.count(elem.get_symbol()))\n                {\n                    symbols.insert(elem.get_symbol());\n                    json_value.append(elem.get_symbol());\n                }\n            }\n        }\n        else\n        {\n            for (auto &elem : *sh_vec)\n            {\n                if (elem.get_symbol() != argument_.symbol)\n                {\n                    continue;\n                }\n\n                Json::Value token_data = json_helper.prop_list(elem, true);\n                token_data[\"status\"] = \"issued\";\n                json_value.append(token_data);\n            }\n        }\n    }\n\n    if (get_api_version() == 1 && json_value.isNull())\n    { //compatible for v1\n        jv_output[json_key] = \"\";\n    }\n    else if (get_api_version() <= 2)\n    {\n        jv_output[json_key] = json_value;\n    }\n    else\n    {\n        if (json_value.isNull())\n            json_value.resize(0);\n\n        jv_output = json_value;\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showtokens.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/showtokens.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\n/************************ showtokens *************************/\n\nconsole_result showtokens::invoke(Json::Value &jv_output,\n                                  libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n\n    std::string json_key;\n    Json::Value json_value;\n\n    auto json_helper = config::json_helper(get_api_version());\n\n    if (option_.is_cert)\n    { // only get token certs\n        json_key = \"tokencerts\";\n\n        if (auth_.name.empty())\n        { // no wallet -- list whole token certs in blockchain\n            auto result_vec = blockchain.get_issued_token_certs();\n            std::sort(result_vec->begin(), result_vec->end());\n            for (auto &elem : *result_vec)\n            {\n                Json::Value token_data = json_helper.prop_list(elem);\n                json_value.append(token_data);\n            }\n        }\n        else\n        { // list token certs owned by wallet\n            blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n            auto pvaddr = blockchain.get_wallet_addresses(auth_.name);\n            if (!pvaddr)\n                throw address_list_nullptr_exception{\"nullptr for address list\"};\n\n            auto sh_vec = std::make_shared<token_cert::list>();\n            for (auto &each : *pvaddr)\n            {\n                sync_fetch_token_cert_balance(each.get_address(), \"\", blockchain, sh_vec);\n            }\n\n            std::sort(sh_vec->begin(), sh_vec->end());\n            for (auto &elem : *sh_vec)\n            {\n                Json::Value token_cert = json_helper.prop_list(elem);\n                json_value.append(token_cert);\n            }\n        }\n    }\n    else\n    {\n        json_key = \"tokens\";\n\n        if (auth_.name.empty())\n        { // no wallet -- list whole tokens in blockchain\n            auto sh_vec = blockchain.get_issued_tokens();\n            std::sort(sh_vec->begin(), sh_vec->end());\n            for (auto &elem : *sh_vec)\n            {\n                Json::Value token_data = json_helper.prop_list(elem, true);\n                token_data[\"status\"] = \"issued\";\n                json_value.append(token_data);\n            }\n        }\n        else\n        { // list token owned by wallet\n            blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n            auto pvaddr = blockchain.get_wallet_addresses(auth_.name);\n            if (!pvaddr)\n                throw address_list_nullptr_exception{\"nullptr for address list\"};\n\n            auto sh_vec = std::make_shared<token_balances::list>();\n\n            // 1. get token in blockchain\n            // get address unspent token balance\n            for (auto &each : *pvaddr)\n            {\n                sync_fetch_token_balance(each.get_address(), true, blockchain, sh_vec);\n            }\n\n            std::sort(sh_vec->begin(), sh_vec->end());\n            for (auto &elem : *sh_vec)\n            {\n                auto issued_token = blockchain.get_issued_token(elem.symbol);\n                if (!issued_token)\n                {\n                    continue;\n                }\n                Json::Value token_data = json_helper.prop_list(elem, *issued_token, false);\n                token_data[\"status\"] = \"unspent\";\n                json_value.append(token_data);\n            }\n\n            // 2. get token in local database\n            // shoudl filter all issued token which be stored in local wallet token database\n            sh_vec->clear();\n            auto sh_unissued = blockchain.get_wallet_unissued_tokens(auth_.name);\n            for (auto &elem : *sh_unissued)\n            {\n                Json::Value token_data = json_helper.prop_list(elem.detail, false, false);\n                token_data[\"status\"] = \"unissued\";\n                json_value.append(token_data);\n            }\n        }\n    }\n\n    if (get_api_version() == 1 && json_value.isNull())\n    { //compatible for v1\n        jv_output[json_key] = \"\";\n    }\n    else if (get_api_version() <= 2)\n    {\n        jv_output[json_key] = json_value;\n    }\n    else\n    {\n        if (json_value.isNull())\n            json_value.resize(0);\n\n        jv_output = json_value;\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showtokenview.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/showtokenview.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\n/************************ showtokenview *************************/\n\nconsole_result showtokenview::invoke(Json::Value &jv_output,\n                                     libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n\n    if (!argument_.symbol.empty())\n    {\n        // check token symbol\n        blockchain.uppercase_symbol(argument_.symbol);\n        check_token_symbol(argument_.symbol);\n    }\n\n    // page limit & page index paramenter check\n    if (!argument_.index)\n        throw argument_legality_exception{\"page index parameter cannot be zero\"};\n    if (!argument_.limit)\n        throw argument_legality_exception{\"page record limit parameter cannot be zero\"};\n    if (argument_.limit > 100)\n        throw argument_legality_exception{\"page record limit cannot be bigger than 100.\"};\n\n    Json::Value json_value;\n    auto json_helper = config::json_helper(get_api_version());\n\n    uint64_t start, end, total_page, tx_count;\n    auto calc_range = [&](uint64_t record_size) {\n        if (record_size == 0 || (!argument_.index && !argument_.limit))\n        { // all tx records\n            start = 0;\n            tx_count = record_size;\n            argument_.index = 1;\n            total_page = 1;\n        }\n        else if (argument_.index && argument_.limit)\n        {\n            start = (argument_.index - 1) * argument_.limit;\n            end = (argument_.index) * argument_.limit;\n            if (start >= record_size || record_size == 0)\n                throw argument_legality_exception{\"no record in this page\"};\n\n            total_page = record_size % argument_.limit ? (record_size / argument_.limit + 1) : (record_size / argument_.limit);\n            tx_count = end >= record_size ? (record_size - start) : argument_.limit;\n        }\n        else\n        {\n            throw argument_legality_exception{\"invalid limit or index parameter\"};\n        }\n    };\n\n    if (option_.is_deposit)\n    {\n        auto sh_vec = sync_fetch_token_deposited_view(argument_.symbol, blockchain);\n        if (!sh_vec->empty())\n        {\n            std::sort(sh_vec->begin(), sh_vec->end());\n        }\n\n        calc_range(sh_vec->size());\n\n        std::vector<token_deposited_balance> result(sh_vec->begin() + start, sh_vec->begin() + start + tx_count);\n        for (auto &elem : result)\n        {\n            auto issued_token = blockchain.get_issued_token(elem.symbol);\n            if (!issued_token)\n            {\n                continue;\n            }\n            Json::Value token_data = json_helper.prop_list(elem, *issued_token);\n            token_data[\"status\"] = \"unspent\";\n            json_value.append(token_data);\n        }\n    }\n    else\n    {\n        auto sh_vec = sync_fetch_token_view(argument_.symbol, blockchain);\n        if (!sh_vec->empty())\n        {\n            std::sort(sh_vec->begin(), sh_vec->end());\n        }\n\n        calc_range(sh_vec->size());\n        std::vector<token_balances> result(sh_vec->begin() + start, sh_vec->begin() + start + tx_count);\n        for (auto &elem : result)\n        {\n            Json::Value token_data = json_helper.prop_list(elem);\n            token_data[\"status\"] = \"unspent\";\n            json_value.append(token_data);\n        }\n    }\n\n    jv_output[\"total_page\"] = total_page;\n    jv_output[\"current_page\"] = argument_.index;\n    jv_output[\"view_count\"] = tx_count;\n    jv_output[\"views\"] = json_value;\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showtx.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/showtx.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showtx *************************/\n/// extent fetch-tx command , add tx height in tx content\nconsole_result showtx::invoke(Json::Value &jv_output,\n                              libbitcoin::server::server_node &node)\n{\n    bc::chain::transaction tx;\n    uint64_t tx_height = 0;\n    auto &blockchain = node.chain_impl();\n    auto exist = blockchain.get_transaction(argument_.hash, tx, tx_height);\n    if (!exist)\n    {\n        throw tx_notfound_exception{\"transaction does not exist!\"};\n    }\n\n    auto json_helper = config::json_helper(get_api_version());\n    if (option_.json)\n    {\n        if (get_api_version() == 1 && option_.is_fetch_tx)\n        { // compatible for v1 fetch-tx\n            jv_output = json_helper.prop_tree(tx, true);\n        }\n        else\n        {\n            jv_output = json_helper.prop_list(tx, tx_height, true);\n        }\n    }\n    else\n    {\n        jv_output = json_helper.prop_tree(tx, false);\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showtxpool.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChainService/api/command/commands/showtxpool.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/node_method_wrapper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ showtxpool *************************/\n\nconsole_result showtxpool::invoke(Json::Value &jv_output,\n                                      libbitcoin::server::server_node &node)\n{\n\n    administrator_required_checker(node, auth_.name, auth_.auth);\n    auto json = option_.json;\n\n    using transaction_ptr = message::tx_message::ptr;\n    auto &blockchain = node.chain_impl();\n    std::promise<code> p;\n    blockchain.pool().fetch([&jv_output, &p, &json, this](const code &ec, const std::vector<transaction_ptr> &txs) {\n        if (ec)\n        {\n            p.set_value(ec);\n            return;\n        }\n\n        std::vector<config::transaction> txs1;\n        txs1.reserve(txs.size());\n        for (auto tp : txs)\n        {\n            txs1.push_back(*tp);\n        }\n\n        if (json)\n        {\n            jv_output = config::json_helper(get_api_version()).prop_tree(txs1, true);\n        }\n        else\n        {\n            jv_output = config::json_helper(get_api_version()).prop_tree(txs1, false);\n        }\n        p.set_value(ec);\n    });\n\n    auto result = p.get_future().get();\n    if (result)\n    {\n        throw tx_fetch_exception{result.message()};\n    }\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showtxs.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/node_method_wrapper.hpp>\n#include <UChainService/api/command/commands/showtxs.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\nclass BC_API tx_block_info\n{\n  public:\n    tx_block_info(uint64_t height, uint32_t timestamp, hash_digest hash) : height_(height), timestamp_(timestamp), hash_(hash)\n    {\n    }\n    uint64_t get_height()\n    {\n        return height_;\n    }\n    uint32_t get_timestamp()\n    {\n        return timestamp_;\n    }\n    hash_digest get_hash()\n    {\n        return hash_;\n    }\n    bool operator<(const tx_block_info &rinfo) const\n    {\n        return hash_ < const_cast<tx_block_info &>(rinfo).get_hash();\n    }\n    bool operator==(const tx_block_info &rinfo) const\n    {\n        return hash_ == const_cast<tx_block_info &>(rinfo).get_hash();\n    }\n\n  private:\n    uint64_t height_;\n    uint32_t timestamp_;\n    hash_digest hash_;\n};\n\n/************************ showtxs *************************/\n\nconsole_result showtxs::invoke(Json::Value &jv_output,\n                               libbitcoin::server::server_node &node)\n{\n    using namespace libbitcoin::config; // for hash256\n    auto &blockchain = node.chain_impl();\n    administrator_required_checker(node, auth_.name, auth_.auth);\n    //blockchain.is_account_passwd_valid(auth_.name, auth_.auth);\n    // address option check\n    if (!argument_.address.empty() && !blockchain.is_valid_address(argument_.address))\n        throw address_invalid_exception{\"invalid address parameter!\"};\n    // height check\n    if (option_.height.first() && option_.height.second() && (option_.height.first() >= option_.height.second()))\n    {\n        throw block_height_exception{\"invalid height option!\"};\n    }\n    // symbol check\n    if (!argument_.symbol.empty())\n    {\n        blockchain.uppercase_symbol(argument_.symbol);\n        if (!blockchain.get_issued_token(argument_.symbol))\n            throw token_symbol_notfound_exception{argument_.symbol + std::string(\" not exist!\")};\n    }\n\n    auto &aroot = jv_output;\n    Json::Value balances;\n\n    auto sort_by_height = [](const tx_block_info &lhs, const tx_block_info &rhs) -> bool {\n        return const_cast<tx_block_info &>(lhs).get_height() > const_cast<tx_block_info &>(rhs).get_height();\n    };\n\n    auto sh_txs = std::make_shared<std::vector<tx_block_info>>();\n    auto sh_addr_vec = std::make_shared<std::vector<std::string>>();\n\n    // collect address\n    if (argument_.address.empty())\n    {\n        auto pvaddr = blockchain.get_wallet_addresses(auth_.name);\n        if (!pvaddr)\n            throw address_invalid_exception{\"nullptr for address list\"};\n\n        for (auto &elem : *pvaddr)\n        {\n            sh_addr_vec->push_back(elem.get_address());\n        }\n    }\n    else\n    { // address exist in command\n        sh_addr_vec->push_back(argument_.address);\n    }\n\n    // page limit & page index paramenter check\n    if (!argument_.index)\n        throw argument_legality_exception{\"page index parameter cannot be zero\"};\n    if (!argument_.limit)\n        throw argument_legality_exception{\"page record limit parameter cannot be zero\"};\n    if (argument_.limit > 100)\n        throw argument_legality_exception{\"page record limit cannot be bigger than 100.\"};\n\n    if (sh_addr_vec->size())\n    {\n        // scan all addresses business record\n        for (auto &each : *sh_addr_vec)\n        {\n            auto sh_vec = blockchain.get_address_business_record(each, argument_.symbol,\n                                                                 option_.height.first(), option_.height.second(), 0, 0);\n            for (auto &elem : *sh_vec)\n                sh_txs->push_back(tx_block_info(elem.height, elem.data.get_timestamp(), elem.point.hash));\n        }\n        std::sort(sh_txs->begin(), sh_txs->end());\n        sh_txs->erase(std::unique(sh_txs->begin(), sh_txs->end()), sh_txs->end());\n        std::sort(sh_txs->begin(), sh_txs->end(), sort_by_height);\n    }\n    else\n    {\n        std::promise<code> p;\n        blockchain.fetch_latest_transactions(argument_.index, argument_.limit, [&p, &balances, this](const code &ec, const std::shared_ptr<chain::transaction::list> txs) {\n            if (ec)\n            {\n                p.set_value(ec);\n                return;\n            }\n            std::vector<config::transaction> txes;\n            for (auto &&tx : *txs)\n            {\n                txes.push_back(tx);\n            }\n            balances = config::json_helper(get_api_version()).prop_tree(txes, true);\n            p.set_value(error::success);\n        });\n\n        auto result = p.get_future().get();\n        if (result)\n        {\n            throw block_height_get_exception{result.message()};\n        }\n    }\n\n    uint64_t start, end, total_page, tx_count;\n    if (argument_.index && argument_.limit)\n    {\n        start = (argument_.index - 1) * argument_.limit;\n        end = (argument_.index) * argument_.limit;\n        if ((start >= sh_txs->size() || !sh_txs->size()) && !balances.size())\n            throw argument_legality_exception{\"no record in this page\"};\n\n        total_page = sh_txs->size() % argument_.limit ? (sh_txs->size() / argument_.limit + 1) : (sh_txs->size() / argument_.limit);\n        tx_count = end >= sh_txs->size() ? (sh_txs->size() - start) : argument_.limit;\n    }\n    else if (!argument_.index && !argument_.limit)\n    { // all tx records\n        start = 0;\n        tx_count = sh_txs->size();\n        argument_.index = 1;\n        total_page = 1;\n    }\n    else\n    {\n        throw argument_legality_exception{\"invalid limit or index parameter\"};\n    }\n    if (!balances.size())\n    {\n        auto json_helper = config::json_helper(get_api_version());\n\n        // sort by height\n        std::vector<tx_block_info> result(sh_txs->begin() + start, sh_txs->begin() + start + tx_count);\n\n        // fetch tx according its hash\n        std::vector<std::string> vec_ip_addr; // input addr\n        chain::transaction tx;\n        uint64_t tx_height;\n        //hash_digest trans_hash;\n        for (auto &each : result)\n        {\n            //decode_hash(trans_hash, each.hash);\n            if (!blockchain.get_transaction(each.get_hash(), tx, tx_height))\n                continue;\n\n            Json::Value tx_item;\n            tx_item[\"hash\"] = encode_hash(each.get_hash());\n            if (get_api_version() == 1)\n            {\n                tx_item[\"height\"] += each.get_height();\n                tx_item[\"timestamp\"] += each.get_timestamp();\n            }\n            else\n            {\n                tx_item[\"height\"] = each.get_height();\n                tx_item[\"timestamp\"] = each.get_timestamp();\n            }\n            tx_item[\"direction\"] = \"send\";\n\n            // set inputs content\n            Json::Value input_addrs;\n            for (auto &input : tx.inputs)\n            {\n                Json::Value input_addr;\n\n                auto &&script_address = payment_address::extract(input.script);\n                if (script_address)\n                {\n                    auto &&temp_addr = script_address.encoded();\n                    input_addr[\"address\"] = temp_addr;\n                    // add input address\n                    vec_ip_addr.push_back(temp_addr);\n                }\n                else\n                {\n                    // empty input address : coin base tx;\n                    if (get_api_version() == 1)\n                        input_addr[\"address\"] = \"\";\n                    else\n                        input_addr[\"address\"] = Json::nullValue;\n                }\n\n                input_addr[\"script\"] = input.script.to_string(1);\n                input_addrs.append(input_addr);\n            }\n\n            if (get_api_version() == 1 && input_addrs.isNull())\n            { // compatible for v1\n                tx_item[\"inputs\"] = \"\";\n            }\n            else\n            {\n                tx_item[\"inputs\"] = input_addrs;\n            }\n\n            // set outputs content\n            Json::Value pt_outputs;\n            uint64_t lock_height = 0;\n            for (auto &op : tx.outputs)\n            {\n                Json::Value pt_output;\n\n                auto &&address = payment_address::extract(op.script);\n                if (address)\n                {\n                    auto &&temp_addr = address.encoded();\n                    pt_output[\"address\"] = temp_addr;\n                    auto ret = blockchain.get_wallet_address(auth_.name, temp_addr);\n                    if (get_api_version() == 1)\n                        pt_output[\"own\"] = ret ? \"true\" : \"false\";\n                    else\n                        pt_output[\"own\"] = ret ? true : false;\n                }\n                else\n                {\n                    // empty output address ? unbelievable.\n                    if (get_api_version() == 1)\n                        pt_output[\"address\"] = \"\";\n                    else\n                        pt_output[\"address\"] = Json::nullValue;\n                }\n\n                pt_output[\"script\"] = op.script.to_string(1);\n                lock_height = 0;\n                if (chain::operation::is_pay_key_hash_with_lock_height_pattern(op.script.operations))\n                    lock_height = chain::operation::get_lock_height_from_pay_key_hash_with_lock_height(op.script.operations);\n\n                pt_output[\"locked_height_range\"] = lock_height;\n                pt_output[\"ucn_value\"] = op.value;\n\n                if (chain::operation::is_pay_key_hash_with_attenuation_model_pattern(op.script.operations))\n                {\n                    const auto &model_param = op.get_attenuation_model_param();\n                    pt_output[\"attenuation_model_param\"] = json_helper.prop_attenuation_model_param(model_param);\n                }\n\n                auto attach_data = op.attach_data;\n                Json::Value tree = json_helper.prop_list(attach_data);\n\n                if (attach_data.get_type() == UC_TOKEN_TYPE)\n                {\n                    auto token_info = boost::get<bc::chain::token>(attach_data.get_attach());\n                    if (token_info.get_status() == TOKEN_TRANSFERABLE_TYPE)\n                    {\n                        // token_transfer dose not contain decimal_number message,\n                        // so we get decimal_number from the issued token with the same symbol.\n                        auto symbol = tree[\"symbol\"].asString();\n                        auto issued_token = blockchain.get_issued_token(symbol);\n\n                        if (issued_token)\n                        {\n                            if (get_api_version() == 1)\n                            {\n                                tree[\"decimal_number\"] += issued_token->get_decimal_number();\n                            }\n                            else\n                            {\n                                tree[\"decimal_number\"] = issued_token->get_decimal_number();\n                            }\n                        }\n                    }\n                }\n\n                pt_output[\"asset\"] = tree;\n                ////////////////////////////////////////////////////////////\n\n                pt_outputs.append(pt_output);\n            }\n\n            if (get_api_version() == 1 && pt_outputs.isNull())\n            { // compatible for v1\n                tx_item[\"outputs\"] = \"\";\n            }\n            else\n            {\n                tx_item[\"outputs\"] = pt_outputs;\n            }\n\n            // set tx direction\n            // 1. receive check\n            auto pos = std::find_if(vec_ip_addr.begin(), vec_ip_addr.end(), [&](const std::string &i) {\n                return blockchain.get_wallet_address(auth_.name, i) != nullptr;\n            });\n\n            if (pos == vec_ip_addr.end())\n            {\n                tx_item[\"direction\"] = \"receive\";\n            }\n\n            // 3. all address clear\n            vec_ip_addr.clear();\n            balances.append(tx_item);\n        }\n    }\n\n    aroot[\"total_page\"] = balances.size() ? 10000 / argument_.limit : total_page;\n    aroot[\"current_page\"] = argument_.index;\n    aroot[\"transaction_count\"] = balances.size() ? balances.size() : tx_count;\n\n    if (get_api_version() == 1 && balances.isNull())\n    { // compatible for v1\n        aroot[\"transactions\"] = \"\";\n    }\n    else if (get_api_version() <= 2)\n    {\n        aroot[\"transactions\"] = balances;\n    }\n    else\n    {\n        if (balances.isNull())\n            balances.resize(0);\n\n        aroot[\"transactions\"] = balances;\n    }\n\n    return console_result::okay;\n}\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showuid.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/showuid.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nconsole_result showuid::invoke(Json::Value &jv_output,\n                               libbitcoin::server::server_node &node)\n{\n    Json::Value json_value;\n\n    auto &blockchain = node.chain_impl();\n\n    if (option_.symbol.empty())\n    {\n\n        auto sh_vec = blockchain.get_registered_uids();\n\n        std::sort(sh_vec->begin(), sh_vec->end());\n        // add blockchain uids\n        for (auto &elem : *sh_vec)\n        {\n            json_value.append(elem.get_symbol());\n        }\n\n        if (get_api_version() <= 2)\n        {\n            jv_output[\"uids\"] = json_value;\n        }\n        else\n        {\n            jv_output = json_value;\n        }\n    }\n    else\n    {\n        auto uidSymbol = option_.symbol;\n        if (blockchain.is_valid_address(uidSymbol))\n        {\n            throw token_symbol_name_exception{\"Address is not supported.\"};\n        }\n\n        // check uid symbol\n        check_uid_symbol(uidSymbol);\n\n        // check uid exists\n        if (!blockchain.is_uid_exist(uidSymbol))\n        {\n            throw uid_symbol_notfound_exception{\"uid symbol does not exist on the blockchain\"};\n        }\n\n        auto blockchain_uids = blockchain.get_uid_history_addresses(uidSymbol);\n        if (blockchain_uids)\n        {\n            Json::Value json_address;\n            Json::Value uid_data;\n            for (auto &uid : *blockchain_uids)\n            {\n                uid_data[\"address\"] = uid.get_uid().get_address();\n                uid_data[\"status\"] = uid.get_status_string();\n                if (get_api_version() >= 3)\n                {\n                    uid_data[\"symbol\"] = uidSymbol;\n                }\n                json_value.append(uid_data);\n            }\n\n            if (get_api_version() <= 2)\n            {\n                jv_output[\"uid\"] = uidSymbol;\n                jv_output[\"addresses\"] = json_value;\n            }\n            else\n            {\n                if (json_value.isNull())\n                    json_value.resize(0);\n\n                jv_output = json_value;\n            }\n        }\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showuids.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/showuids.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\n/************************ showuids *************************/\n\nconsole_result showuids::invoke(Json::Value &jv_output,\n                                libbitcoin::server::server_node &node)\n{\n    // page limit & page index paramenter check\n    if (argument_.index <= 0)\n    {\n        throw argument_legality_exception{\"page index parameter cannot be zero\"};\n    }\n    if (argument_.limit <= 0)\n    {\n        throw argument_legality_exception{\"page record limit parameter cannot be zero\"};\n    }\n    if (argument_.limit > 100)\n    {\n        throw argument_legality_exception{\"page record limit cannot be bigger than 100.\"};\n    }\n\n    auto &blockchain = node.chain_impl();\n    std::shared_ptr<uid_detail::list> sh_vec;\n    if (auth_.name.empty())\n    {\n        // no wallet -- list all uids in blockchain\n        sh_vec = blockchain.get_registered_uids();\n    }\n    else\n    {\n        // list uids owned by the wallet\n        blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n        sh_vec = blockchain.get_wallet_uids(auth_.name);\n    }\n\n    uint64_t limit = argument_.limit;\n    uint64_t index = argument_.index;\n\n    std::vector<uid_detail> result;\n    uint64_t total_count = sh_vec->size();\n    uint64_t total_page = 0;\n    if (total_count > 0)\n    {\n        std::sort(sh_vec->begin(), sh_vec->end());\n\n        uint64_t start = 0, end = 0, tx_count = 0;\n        if (index && limit)\n        {\n            total_page = (total_count % limit) ? (total_count / limit + 1) : (total_count / limit);\n            index = index > total_page ? total_page : index;\n            start = (index - 1) * limit;\n            end = index * limit;\n            tx_count = end >= total_count ? (total_count - start) : limit;\n        }\n        else if (!index && !limit)\n        { // all tx records\n            start = 0;\n            tx_count = total_count;\n            index = 1;\n            total_page = 1;\n        }\n        else\n        {\n            throw argument_legality_exception{\"invalid limit or index parameter\"};\n        }\n\n        if (start < total_count && tx_count > 0)\n        {\n            result.resize(tx_count);\n            std::copy(sh_vec->begin() + start, sh_vec->begin() + start + tx_count, result.begin());\n        }\n    }\n\n    Json::Value uids;\n    // add blockchain uids\n    for (auto &elem : result)\n    {\n        Json::Value uid_data;\n        uid_data[\"symbol\"] = elem.get_symbol();\n        uid_data[\"address\"] = elem.get_address();\n        uid_data[\"status\"] = \"registered\";\n        uids.append(uid_data);\n    }\n\n    // output\n    if (uids.isNull())\n    {\n        uids.resize(0);\n    }\n\n    jv_output[\"total_count\"] = total_count;\n    jv_output[\"total_page\"] = total_page;\n    jv_output[\"current_page\"] = index;\n    jv_output[\"uids\"] = uids;\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showvote.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/showvote.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\n/************************ showvote *************************/\n\nconsole_result showvote::invoke(Json::Value &jv_output,\n                                libbitcoin::server::server_node &node)\n{\n    if (argument_.endheight < argument_.startheight)\n    {\n        throw block_height_exception{\"END_HEIGHT is less than START_HEIGHT.\"};\n    }\n\n    auto &blockchain = node.chain_impl();\n    std::string from_address = get_address_from_strict_uid(argument_.uid, blockchain);\n\n    if (!blockchain.is_valid_address(from_address))\n        throw uid_symbol_name_exception{\"Uid symbol \" + argument_.uid + \" is not valid.\"};\n\n    Json::Value json_value;\n    auto json_helper = config::json_helper(get_api_version());\n\n    auto sh_vec = std::make_shared<token_balances::list>();\n    sync_fetch_token_balance(from_address, true, blockchain, sh_vec, argument_.startheight ,argument_.endheight);\n    std::sort(sh_vec->begin(), sh_vec->end());\n    for (auto &elem : *sh_vec)\n    {\n        if ( elem.symbol != UC_VOTE_TOKEN_SYMBOL)\n            continue;\n\n        auto issued_token = blockchain.get_issued_token(UC_VOTE_TOKEN_SYMBOL);\n        if (!issued_token)\n        {\n            continue;\n        }\n        \n        Json::Value token_data = json_helper.prop_list(elem, *issued_token);\n        token_data[\"status\"] = \"unspent\";\n        json_value.append(token_data);\n    }\n\n    if (json_value.isNull())\n        json_value.resize(0);\n\n    jv_output = json_value;\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showwallettoken.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/showwallettoken.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\n/************************ showwallettoken *************************/\n\nconsole_result showwallettoken::invoke(Json::Value &jv_output,\n                                       libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    if (!argument_.symbol.empty())\n    {\n        // check token symbol\n        check_token_symbol(argument_.symbol);\n    }\n\n    auto pvaddr = blockchain.get_wallet_addresses(auth_.name);\n    if (!pvaddr)\n        throw address_list_nullptr_exception{\"nullptr for address list\"};\n\n    std::string json_key;\n    Json::Value json_value;\n    auto json_helper = config::json_helper(get_api_version());\n\n    if (option_.is_cert)\n    { // only get token certs\n        json_key = \"tokencerts\";\n        auto sh_vec = std::make_shared<token_cert::list>();\n        for (auto &each : *pvaddr)\n        {\n            sync_fetch_token_cert_balance(each.get_address(), argument_.symbol, blockchain, sh_vec);\n        }\n\n        std::sort(sh_vec->begin(), sh_vec->end());\n        for (auto &elem : *sh_vec)\n        {\n            if (!argument_.symbol.empty() && argument_.symbol != elem.get_symbol())\n                continue;\n\n            Json::Value token_cert = json_helper.prop_list(elem);\n            json_value.append(token_cert);\n        }\n    }\n    else if (option_.deposited)\n    {\n        json_key = \"tokens\";\n        auto sh_vec = std::make_shared<token_deposited_balance::list>();\n\n        // get address unspent token balance\n        std::string addr;\n        for (auto &each : *pvaddr)\n        {\n            sync_fetch_token_deposited_balance(each.get_address(), blockchain, sh_vec);\n        }\n\n        std::sort(sh_vec->begin(), sh_vec->end());\n\n        for (auto &elem : *sh_vec)\n        {\n            auto &symbol = elem.symbol;\n            if (!argument_.symbol.empty() && argument_.symbol != symbol)\n                continue;\n\n            auto issued_token = blockchain.get_issued_token(symbol);\n            if (!issued_token)\n            {\n                continue;\n            }\n\n            Json::Value token_data = json_helper.prop_list(elem, *issued_token, true);\n            token_data[\"status\"] = \"unspent\";\n            json_value.append(token_data);\n        }\n    }\n    else\n    {\n        json_key = \"tokens\";\n        auto sh_vec = std::make_shared<token_balances::list>();\n\n        // 1. get token in blockchain\n        // get address unspent token balance\n        std::string addr;\n        for (auto &each : *pvaddr)\n        {\n            sync_fetch_token_balance(each.get_address(), false, blockchain, sh_vec);\n        }\n\n        std::sort(sh_vec->begin(), sh_vec->end());\n        for (auto &elem : *sh_vec)\n        {\n            auto &symbol = elem.symbol;\n            if (!argument_.symbol.empty() && argument_.symbol != symbol)\n                continue;\n            auto issued_token = blockchain.get_issued_token(symbol);\n            if (!issued_token)\n            {\n                continue;\n            }\n            Json::Value token_data = json_helper.prop_list(elem, *issued_token);\n            token_data[\"status\"] = \"unspent\";\n            json_value.append(token_data);\n        }\n\n        // 2. get token in local database\n        // shoudl filter all issued token which be stored in local wallet token database\n        auto sh_unissued = blockchain.get_wallet_unissued_tokens(auth_.name);\n        for (auto &elem : *sh_unissued)\n        {\n            auto &symbol = elem.detail.get_symbol();\n            // symbol filter\n            if (!argument_.symbol.empty() && argument_.symbol != symbol)\n                continue;\n\n            Json::Value token_data = json_helper.prop_list(elem.detail, false);\n            token_data[\"status\"] = \"unissued\";\n            json_value.append(token_data);\n        }\n    }\n\n    if (get_api_version() == 1 && json_value.isNull())\n    { //compatible for v1\n        jv_output[json_key] = \"\";\n    }\n    else if (get_api_version() <= 2)\n    {\n        jv_output[json_key] = json_value;\n    }\n    else\n    {\n        if (json_value.isNull())\n            json_value.resize(0);\n\n        jv_output = json_value;\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/showwork.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChainService/api/command/node_method_wrapper.hpp>\n#include <UChainService/api/command/commands/showwork.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\n/************************ showwork *************************/\n\nconsole_result showwork::invoke(Json::Value &jv_output,\n                                libbitcoin::server::server_node &node)\n{\n\n    administrator_required_checker(node, auth_.name, auth_.auth);\n\n    std::string seed_hash;\n    std::string header_hash;\n    std::string boundary;\n\n    auto &blockchain = node.chain_impl();\n    auto &miner = node.miner();\n\n    //auto ret = miner.get_work(seed_hash, header_hash, boundary);\n    auto ret = 0;\n\n    auto &aroot = jv_output;\n\n    if (ret)\n    {\n\n        Json::Value result;\n        result.append(header_hash);\n        result.append(seed_hash);\n        result.append(boundary);\n\n        if (get_api_version() == 1)\n        {\n            aroot[\"result\"] = result;\n        }\n        else\n        {\n            aroot = result;\n        }\n    }\n    else\n    {\n        throw setting_required_exception{\"Use command <setminingwallet> to set mining address.\"};\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/shutdown.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChainService/api/command/commands/shutdown.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/node_method_wrapper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ shutdown *************************/\nconsole_result shutdown::invoke(Json::Value &jv_output,\n                                libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n\n    administrator_required_checker(node, auth_.name, auth_.auth);\n    jv_output = \"sending SIGTERM to ucd.\";\n\n#ifndef _WIN32\n    killpg(getpgrp(), SIGTERM);\n#else\n    std::thread(\n        []() {\n            Sleep(2000);\n            ExitProcess(0);\n        })\n        .detach();\n#endif\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/signmultisigtx.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/signmultisigtx.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nconsole_result signmultisigtx::invoke(\n    Json::Value &jv_output,\n    libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    auto wallet = blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    tx_type tx_ = argument_.transaction;\n\n    // get all address of this wallet\n    auto pvaddr = blockchain.get_wallet_addresses(auth_.name);\n    if (!pvaddr)\n    {\n        throw address_list_empty_exception{\"empty address list for this wallet.\"};\n    }\n\n    std::string addr_prikey(\"\");\n    if (!option_.self_publickey.empty())\n    {\n        auto owned = false;\n        for (auto &each : *pvaddr)\n        {\n            auto prv_key = each.get_prv_key(auth_.auth);\n            auto pub_key = ec_to_xxx_impl(\"ec-to-public\", prv_key);\n            if (option_.self_publickey == pub_key)\n            {\n                owned = true;\n                addr_prikey = prv_key;\n                break;\n            }\n        }\n\n        if (!owned)\n        {\n            throw pubkey_dismatch_exception(\n                \"public key \" + option_.self_publickey + \" is not owned by \" + auth_.name);\n        }\n    }\n\n    bc::chain::script input_script;\n    bc::chain::script redeem_script;\n\n    bool fullfilled = true;\n    std::string multisig_script;\n    uint32_t index = 0;\n    for (auto &each_input : tx_.inputs)\n    {\n        input_script = each_input.script;\n\n        if (script_pattern::sign_multisig != input_script.pattern())\n            continue;\n\n        // 1. extract address from multisig payment script\n        // zero sig1 sig2 ... encoded-multisig\n        const auto &redeem_data = input_script.operations.back().data;\n        if (redeem_data.empty())\n        {\n            throw redeem_script_empty_exception{\"empty redeem script.\"};\n        }\n\n        if (!redeem_script.from_data(redeem_data, false, bc::chain::script::parse_mode::strict))\n        {\n            throw redeem_script_data_exception{\"error occured when parse redeem script data.\"};\n        }\n\n        // Is the redeem script a standard pay (output) script?\n        if (redeem_script.pattern() != script_pattern::pay_multisig)\n        {\n            throw redeem_script_pattern_exception{\"redeem script is not pay multisig pattern.\"};\n        }\n\n        const payment_address address(redeem_script, payment_address::mainnet_p2sh);\n        auto hash_address = address.encoded(); // pay address\n\n        // 2. get address prikey\n        auto multisig_vec = wallet->get_multisig(hash_address);\n        if (!multisig_vec || multisig_vec->empty())\n        {\n            throw multisig_notfound_exception(hash_address + \" multisig record not found.\");\n        }\n\n        // signed, nothing to do (2 == zero + encoded-script)\n        wallet_multisig acc_multisig = *(multisig_vec->begin());\n        if (input_script.operations.size() >= acc_multisig.get_m() + 2)\n        {\n            index++;\n            continue;\n        }\n\n        for (auto &acc_multisig : *multisig_vec)\n        {\n            /*if (!option_.self_publickey.empty() && option_.self_publickey != acc_multisig.get_pub_key()) {\n                continue;\n            }*/\n\n            if (option_.self_publickey.empty())\n            {\n                addr_prikey = \"\";\n                for (auto &each : *pvaddr)\n                {\n                    auto prv_key = each.get_prv_key(auth_.auth);\n                    auto &&pub_key = ec_to_xxx_impl(\"ec-to-public\", prv_key);\n                    if (pub_key == acc_multisig.get_pub_key())\n                    {\n                        addr_prikey = prv_key;\n                        break;\n                    }\n                }\n            }\n\n            if (addr_prikey.empty())\n            {\n                throw prikey_notfound_exception(\n                    \"The private key of \" + acc_multisig.get_pub_key() + \" not found.\");\n            }\n\n            // 3. populate unlock script\n            multisig_script = acc_multisig.get_multisig_script();\n            // log::trace(\"multisig_script=\") << multisig_script;\n\n            // prepare sign\n            explorer::config::hashtype sign_type;\n            uint8_t hash_type = (signature_hash_algorithm)sign_type;\n\n            bc::explorer::config::ec_private config_private_key(addr_prikey);\n            bc::explorer::config::script config_contract(multisig_script);\n\n            // gen sign\n            bc::endorsement endorse;\n            if (!bc::chain::script::create_endorsement(\n                    endorse, config_private_key, config_contract, tx_, index, hash_type))\n            {\n                throw tx_sign_exception{\"get_input_sign sign failure\"};\n            }\n\n            // insert endorse before multisig script\n            auto position = input_script.operations.end();\n            input_script.operations.insert(position - 1, {bc::chain::opcode::special, endorse});\n        }\n\n        // rearange signature order\n        data_chunk data;\n        chain::script script_encoded;\n        script_encoded.from_string(multisig_script);\n\n        bc::chain::script new_script;\n        // insert zero\n        new_script.operations.push_back(input_script.operations.front());\n\n        /*\n            \"multisig-script\" : \"2 [ pubkey_1 ] [ pubkey_2 ] [ pubkey_3 ] 3 checkmultisig\",\n            \"script\" : \"zero [ signature_1 ] [ signature_2 ] [ encoded-script ]\",\n        */\n        // skip first \"m\" and last \"n checkmultisig\"\n        auto multisig_start = script_encoded.operations.begin() + 1;\n        auto multisig_end = script_encoded.operations.end() - 2;\n\n        // skip first zero and last encoded-script\n        auto script_op_start = input_script.operations.begin() + 1;\n        auto script_op_end = input_script.operations.end() - 1;\n\n        for (auto multisig_it = multisig_start; multisig_it != multisig_end; ++multisig_it)\n        {\n            for (auto script_op_it = script_op_start; script_op_it != script_op_end; ++script_op_it)\n            {\n                auto endorsement = script_op_it->data;\n                const auto sighash_type = endorsement.back();\n                auto distinguished = endorsement;\n                distinguished.pop_back();\n\n                ec_signature signature;\n                // from validate_tx_engine.cpp handle_previous_tx\n                auto strict = ((script_context::all_enabled & script_context::bip66_enabled) != 0);\n                if (!parse_signature(signature, distinguished, strict))\n                {\n                    log::trace(\"multisig\") << \"failed to parse_signature! \" << sighash_type;\n                    continue;\n                }\n\n                if (chain::script::check_signature(signature, sighash_type, multisig_it->data,\n                                                   script_encoded, tx_, index))\n                {\n                    new_script.operations.push_back(*script_op_it);\n                    break;\n                }\n            }\n\n            if (new_script.operations.size() >= acc_multisig.get_m() + 1)\n            {\n                break;\n            }\n        }\n\n        // insert encoded-script\n        new_script.operations.push_back(input_script.operations.back());\n        if (new_script.operations.size() < acc_multisig.get_m() + 2)\n        {\n            fullfilled = false;\n        }\n\n        // set input script of this tx\n        each_input.script = new_script;\n        index++;\n    }\n\n    // output json\n    if (get_api_version() <= 2)\n    {\n        jv_output = config::json_helper(get_api_version()).prop_list_of_rawtx(tx_, false, true);\n    }\n    else\n    {\n        jv_output = config::json_helper(get_api_version()).prop_list_of_rawtx(tx_, true);\n    }\n\n    if (option_.broadcast_flag /* TODO && fullfilled */)\n    {\n        log::trace(\"multisig\") << \"validate and broadcast multisig transaction.\" << tx_.to_string(1);\n\n        if (blockchain.validate_tx_engine(tx_))\n        {\n            throw tx_validate_exception{\"validate transaction failure\"};\n        }\n\n        if (blockchain.broadcast_transaction(tx_))\n        {\n            throw tx_broadcast_exception{\"broadcast transaction failure\"};\n        }\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/signrawtx.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/signrawtx.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nconsole_result signrawtx::invoke(Json::Value &jv_output,\n                                 libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    tx_type tx_ = argument_.transaction;\n\n    // sign tx\n    {\n        uint32_t index = 0;\n        chain::transaction tx_temp;\n        uint64_t tx_height;\n\n        for (auto &fromeach : tx_.inputs)\n        {\n            if (!(blockchain.get_transaction(fromeach.previous_output.hash, tx_temp, tx_height)))\n                throw argument_legality_exception{\"invalid transaction hash \" + encode_hash(fromeach.previous_output.hash)};\n\n            auto output = tx_temp.outputs.at(fromeach.previous_output.index);\n\n            // get address private key\n            auto address = payment_address::extract(output.script);\n            if (!address || (address.version() == 0x5)) // script address : maybe multisig\n                throw argument_legality_exception{\"invalid script \" + config::script(output.script).to_string()};\n\n            auto acc_addr = blockchain.get_wallet_address(auth_.name, address.encoded());\n\n            if (!acc_addr)\n                throw argument_legality_exception{\"not own address \" + address.encoded()};\n\n            // paramaters\n            explorer::config::hashtype sign_type;\n            uint8_t hash_type = (signature_hash_algorithm)sign_type;\n\n            bc::explorer::config::ec_private config_private_key(acc_addr->get_prv_key(auth_.auth)); // address private key\n            const ec_secret &private_key = config_private_key;\n            bc::wallet::ec_private ec_private_key(private_key, 0u, true);\n\n            bc::explorer::config::script config_contract(output.script); // previous output script\n            const bc::chain::script &contract = config_contract;\n\n            // gen sign\n            bc::endorsement endorse;\n            if (!bc::chain::script::create_endorsement(endorse, private_key,\n                                                       contract, tx_, index, hash_type))\n            {\n                throw tx_sign_exception{\"signrawtx sign failure\"};\n            }\n\n            // do script\n            auto &&public_key = ec_private_key.to_public();\n            data_chunk public_key_data;\n            public_key.to_data(public_key_data);\n            bc::chain::script ss;\n            ss.operations.push_back({bc::chain::opcode::special, endorse});\n            ss.operations.push_back({bc::chain::opcode::special, public_key_data});\n\n            // if pre-output script is deposit tx.\n            if (contract.pattern() == bc::chain::script_pattern::pay_key_hash_with_lock_height)\n            {\n                uint64_t lock_height = chain::operation::get_lock_height_from_pay_key_hash_with_lock_height(\n                    contract.operations);\n                ss.operations.push_back({bc::chain::opcode::special, script_number(lock_height).data()});\n            }\n\n            // set input script of this tx\n            tx_.inputs[index].script = ss;\n            index++;\n        } // end for\n    }\n\n    // get raw tx\n    if (blockchain.validate_tx_engine(tx_))\n    {\n        throw tx_validate_exception{\"validate transaction failure\"};\n    }\n\n    jv_output = config::json_helper(get_api_version()).prop_list_of_rawtx(tx_, true);\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/startmining.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/startmining.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ startmining *************************/\n\nconsole_result startmining::invoke(Json::Value &jv_output,\n                                   libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    auto &miner = node.miner();\n\n    uint64_t height;\n    //uint64_t rate;\n    //std::string difficulty;\n    uint32_t miners;\n    bool is_solo_mining;\n    node.miner().get_state(height, miners, /*rate, difficulty,*/ is_solo_mining);\n    if (is_solo_mining)\n    {\n        throw setting_required_exception{\"Currently mining, please use command <stopmining> to stop the running mining.\"};\n    }\n\n    auto str_addr = argument_.address;\n\n    blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    if (!blockchain.is_valid_address(str_addr))\n    {\n        throw address_invalid_exception{\"invalid address parameter! \" + str_addr};\n    }\n\n    /*const vector<string>& miner_address = miner.get_miner_addresses();\n    if(std::find(miner_address.begin(), miner_address.end(), str_addr) == miner_address.end()) \n        throw address_invalid_exception{str_addr + \" is not a miner address \"};*/\n\n    if (!blockchain.get_wallet_address(auth_.name, str_addr))\n    {\n        throw address_dismatch_wallet_exception{\"target address does not match wallet. \" + str_addr};\n    }\n\n    bc::wallet::payment_address addr(str_addr);\n\n    if (addr.version() == bc::wallet::payment_address::mainnet_p2sh)\n    { // for multisig address\n        throw argument_legality_exception{\"script address parameter not allowed!\"};\n    }\n\n    // start\n    const auto &spaddr = blockchain.get_wallet_address(auth_.name, str_addr);\n    miner.set_miner_pri_key(spaddr->get_prv_key(auth_.auth));\n    if (miner.start(addr, option_.number))\n    {\n        if (option_.number == 0)\n        {\n            jv_output = \"solo mining started at \" + str_addr;\n        }\n        else\n        {\n            jv_output = \"solo mining started at \" + str_addr + \", try to mine \" + std::to_string(option_.number) + \" block(s).\";\n        }\n    }\n    else\n    {\n        throw unknown_error_exception{\"solo mining startup got error\"};\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/stopmining.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <jsoncpp/json/json.h>\n#include <UChainService/api/command/node_method_wrapper.hpp>\n#include <UChainService/api/command/commands/stopmining.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ stopmining *************************/\n\nconsole_result stopmining::invoke(Json::Value &jv_output,\n                                  libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    auto &miner = node.miner();\n    blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n    if (!administrator_required_checker(node, auth_.name, auth_.auth) &&\n        !blockchain.get_wallet_address(auth_.name, miner.get_miner_address()))\n        throw wallet_authority_exception{\"not the miner wallet.\"};\n    auto ret = miner.stop();\n\n    if (ret)\n    {\n        jv_output = \"signal STOP sent.\";\n    }\n    else\n    {\n        throw unknown_error_exception{\"mining stop got error.\"};\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/submitwork.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/submitwork.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\nusing namespace bc::explorer::config;\n\n/************************ submitwork *************************/\ninline bool startswith(const string &str, const char *prefix)\n{\n    return str.find(prefix) == 0;\n}\n\nconsole_result submitwork::invoke(Json::Value &jv_output,\n                                  libbitcoin::server::server_node &node)\n{\n    auto &miner = node.miner();\n\n    const uint64_t nounce_mask = (get_api_version() == 3) ? 0 : 0x6675636b6d657461;\n    //Note: submitwork does not starts with 0x, while eth_submitWork does!\n    if (get_api_version() == 3)\n    {\n        if (!startswith(argument_.nonce, \"0x\"))\n        {\n            throw argument_legality_exception{\"nonce should start with \\\"0x\\\" for eth_submitWork\"};\n        }\n        argument_.nonce = argument_.nonce.substr(2, argument_.nonce.size() - 2);\n    }\n\n    //auto ret = miner.put_result(argument_.nonce, argument_.mix_hash, argument_.header_hash, nounce_mask);\n    auto ret = 0;\n    auto &root = jv_output;\n\n    if (ret)\n    {\n        if (get_api_version() == 1)\n        {\n            root[\"result\"] = \"true\"; // boost json parser output as string, for compatible.\n        }\n        else\n        {\n            root = true;\n        }\n    }\n    else\n    {\n        if (get_api_version() == 1)\n        {\n            root[\"result\"] = \"false\"; // boost json parser output as string, for compatible.\n        }\n        else\n        {\n            root = false;\n        }\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/swaptoken.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/swaptoken.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n#include <UChainService/consensus/libdevcore/SHA3.h>\n#include <boost/algorithm/string.hpp>\n#include <regex>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n//Check if address is checksum of ETH address\nbool is_ETH_Address(const string &address)\n{\n    // regex checking\n    {\n        sregex_iterator end;\n\n        // check if it has the basic requirements of an address\n        static const regex reg_common(\"^0x[0-9a-fA-F]{40}$\");\n        sregex_iterator it(address.begin(), address.end(), reg_common);\n        if (it == end)\n        {\n            return false;\n        }\n\n        // If it's all small caps, return true\n        static const regex reg_alllower(\"^0x[0-9a-f]{40}$\");\n        sregex_iterator it1(address.begin(), address.end(), reg_alllower);\n        if (it1 != end)\n        {\n            return true;\n        }\n\n        // If it's all caps, return true\n        static const regex reg_allupper(\"^0x[0-9A-F]{40}$\");\n        sregex_iterator it2(address.begin(), address.end(), reg_allupper);\n        if (it2 != end)\n        {\n            return true;\n        }\n    }\n\n    // Otherwise check each case\n    auto addr = address.substr(2); // get rid of prefix \"0x\"\n    auto address_hash = bc::sha3(boost::to_lower_copy(addr)).hex();\n\n    for (size_t i = 0; i < addr.size(); ++i)\n    {\n        auto c = addr[i];\n        if (std::isdigit(c))\n        {\n            continue;\n        }\n        // the nth letter should be uppercase if the nth digit of casemap is 1 (89abcdef)\n        bool is_less_than_8 = (address_hash[i] >= '0' && address_hash[i] < '8');\n        if ((is_less_than_8 && !std::islower(c)) ||\n            (!is_less_than_8 && !std::isupper(c)))\n        {\n            return false;\n        }\n    }\n\n    return true;\n}\n\nconsole_result swaptoken::invoke(Json::Value &jv_output,\n                                 libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n    blockchain.uppercase_symbol(argument_.symbol);\n\n    // check message\n    if (argument_.foreign_addr.empty() || argument_.foreign_addr.size() >= 255)\n    {\n        throw argument_size_invalid_exception{\"message length out of bounds.\"};\n    }\n\n    // check ETH address\n    if (!is_ETH_Address(argument_.foreign_addr))\n    {\n        throw argument_legality_exception{argument_.foreign_addr + \" is not a valid ETH address.\"};\n    }\n\n    // check token symbol\n    check_token_symbol(argument_.symbol);\n\n    asset attach_token, attach_fee;\n    const std::string &&to_address = get_address(argument_.to, attach_token, false, blockchain);\n    const std::string &&swapfee_address = bc::get_developer_community_address(\n        blockchain.chain_settings().use_testnet_rules);\n\n    std::string from_address(\"\");\n    if (!option_.from.empty())\n    {\n        from_address = get_address(option_.from, attach_token, true, blockchain);\n        get_address(option_.from, attach_fee, true, blockchain);\n    }\n\n    std::string change_address = get_address(option_.change, blockchain);\n\n    if (!argument_.amount)\n    {\n        throw argument_legality_exception{\"invalid amount parameter!\"};\n    }\n    if (option_.swapfee < DEFAULT_SWAP_FEE)\n    {\n        throw argument_legality_exception{\"invalid swapfee parameter! must >= 1 UCN\"};\n    }\n\n    std::vector<receiver_record> receiver{\n        {to_address, argument_.symbol, 0, argument_.amount, utxo_attach_type::token_transfer, attach_token},\n        {swapfee_address, \"\", option_.swapfee, 0, utxo_attach_type::ucn, attach_fee},\n    };\n\n    std::string message(\"{\\\"type\\\":\\\"ETH\\\",\\\"address\\\":\\\"\" + argument_.foreign_addr + \"\\\"}\");\n\n    auto send_helper = sending_token(\n        *this, blockchain,\n        std::move(auth_.name), std::move(auth_.auth),\n        std::move(from_address), std::move(argument_.symbol),\n        \"\",\n        std::move(receiver), option_.fee,\n        std::move(message), std::move(change_address));\n\n    send_helper.exec();\n\n    // json output\n    auto tx = send_helper.get_transaction();\n    jv_output = config::json_helper(get_api_version()).prop_tree(tx, true);\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/transfercandidate.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChainService/api/command/commands/transfercandidate.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nconsole_result transfercandidate::invoke(Json::Value &jv_output,\n                                         libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    auto acc = blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    // check symbol\n    check_candidate_symbol(argument_.symbol);\n\n    // check to uid\n    auto to_uid = argument_.to;\n    auto to_address = get_address_from_uid(to_uid, blockchain);\n    if (!blockchain.is_valid_address(to_address))\n    {\n        throw toaddress_invalid_exception(\"Invalid uid parameter! \" + to_uid);\n    }\n\n    auto sh_vec = blockchain.get_registered_candidates();\n    if (nullptr != sh_vec)\n    {\n        auto pred = [to_uid, this](libbitcoin::chain::candidate_info &info) {\n            return info.to_uid == to_uid && info.candidate.get_symbol() == argument_.symbol;\n        };\n        if (std::find_if(sh_vec->begin(), sh_vec->end(), pred) != sh_vec->end())\n            throw toaddress_invalid_exception(\"The UID has owned the address. \");\n    }\n    // get identifiable token\n    auto candidates = blockchain.get_wallet_candidates(auth_.name, argument_.symbol);\n    if (candidates->size() == 0)\n    {\n        throw token_lack_exception(\"Not enough token '\" + argument_.symbol + \"'\");\n    }\n\n    auto &candidate = *(candidates->begin());\n    std::string from_address(candidate.get_address());\n    bool is_multisig_address = blockchain.is_script_address(from_address);\n\n    wallet_multisig acc_multisig;\n    if (is_multisig_address)\n    {\n        auto multisig_vec = acc->get_multisig(from_address);\n        if (!multisig_vec || multisig_vec->empty())\n        {\n            throw multisig_notfound_exception(\"From address multisig record not found.\");\n        }\n\n        acc_multisig = *(multisig_vec->begin());\n    }\n    auto candidate_info = blockchain.get_registered_candidate(argument_.symbol);\n    if (nullptr == candidate_info)\n    {\n        throw token_symbol_name_exception(\"Invalid SYMBOL parameter! \" + argument_.symbol);\n    }\n    std::string from_uid = candidate_info->to_uid;\n    // receiver\n    std::vector<receiver_record> receiver{\n        {to_address, argument_.symbol, 0, 0, 0,\n         utxo_attach_type::candidate_transfer, asset(from_uid, to_uid)}};\n\n    auto helper = transferring_candidate(\n        *this, blockchain,\n        std::move(auth_.name), std::move(auth_.auth),\n        is_multisig_address ? std::move(from_address) : \"\",\n        std::move(argument_.symbol),\n        std::move(receiver), argument_.fee,\n        std::move(acc_multisig));\n\n    helper.exec();\n\n    // json output\n    auto tx = helper.get_transaction();\n    if (is_multisig_address)\n    {\n        jv_output = config::json_helper(get_api_version()).prop_list_of_rawtx(tx, false, true);\n    }\n    else\n    {\n        jv_output = config::json_helper(get_api_version()).prop_tree(tx, true);\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/transfercert.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChainService/api/command/commands/transfercert.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nconsole_result transfercert::invoke(Json::Value &jv_output,\n                                    libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    auto acc = blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    blockchain.uppercase_symbol(argument_.symbol);\n    boost::to_lower(argument_.cert);\n\n    // check token symbol\n    check_token_symbol(argument_.symbol);\n\n    // check token cert types\n    auto &cert_type_name = argument_.cert;\n    auto match = [&cert_type_name](const std::pair<token_cert_type, std::string> &item) {\n        return item.second == cert_type_name;\n    };\n    const auto &type_name_map = token_cert::get_type_name_map();\n    auto iter = std::find_if(type_name_map.begin(), type_name_map.end(), match);\n    if (iter == type_name_map.end())\n    {\n        throw token_cert_exception(\"unsupported token cert type \" + cert_type_name);\n    }\n\n    auto cert_type = iter->first;\n    if (cert_type == token_cert_ns::issue)\n    {\n        auto sh_token = blockchain.get_issued_token(argument_.symbol);\n        if (!sh_token)\n            throw token_symbol_notfound_exception(\n                \"token '\" + argument_.symbol + \"' does not exist.\");\n    }\n\n    // check target address\n    auto to_uid = argument_.to;\n    auto to_address = get_address_from_uid(to_uid, blockchain);\n    if (!blockchain.is_valid_address(to_address))\n        throw toaddress_invalid_exception{\"invalid uid parameter! \" + to_uid};\n\n    // check cert is owned by the wallet\n    bool exist = blockchain.is_token_cert_exist(argument_.symbol, cert_type);\n    if (!exist)\n    {\n        throw token_cert_notfound_exception(\n            cert_type_name + \" cert '\" + argument_.symbol + \"' does not exist.\");\n    }\n\n    auto cert = blockchain.get_wallet_token_cert(auth_.name, argument_.symbol, cert_type);\n    if (!cert)\n    {\n        throw token_cert_notowned_exception(\n            cert_type_name + \" cert '\" + argument_.symbol + \"' is not owned by \" + auth_.name);\n    }\n\n    auto from_address = cert->get_address();\n    wallet_multisig acc_multisig;\n    bool is_multisig_address = blockchain.is_script_address(from_address);\n    if (is_multisig_address)\n    {\n        auto multisig_vec = acc->get_multisig(from_address);\n        if (!multisig_vec || multisig_vec->empty())\n        {\n            throw multisig_notfound_exception{\"from address multisig record not found.\"};\n        }\n\n        acc_multisig = *(multisig_vec->begin());\n    }\n\n    // receiver\n    std::vector<receiver_record> receiver{\n        {to_address, argument_.symbol, 0, 0,\n         cert_type, utxo_attach_type::token_cert_transfer, asset(\"\", to_uid)}};\n\n    auto helper = transferring_token_cert(*this, blockchain,\n                                          std::move(auth_.name), std::move(auth_.auth),\n                                          is_multisig_address ? std::move(from_address) : \"\",\n                                          std::move(argument_.symbol),\n                                          std::move(receiver), argument_.fee,\n                                          std::move(acc_multisig));\n\n    helper.exec();\n\n    // json output\n    auto &&tx = helper.get_transaction();\n    if (is_multisig_address)\n    {\n        jv_output = config::json_helper(get_api_version()).prop_list_of_rawtx(tx, false, true);\n    }\n    else\n    {\n        jv_output = config::json_helper(get_api_version()).prop_tree(tx, true);\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/transferuid.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/transferuid.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nconsole_result transferuid::invoke(Json::Value &jv_output,\n                                   libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    auto acc = blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n\n    // check uid symbol\n    auto uid = argument_.symbol;\n\n    check_uid_symbol(uid);\n\n    // check uid exsits\n    auto uid_detail = blockchain.get_registered_uid(uid);\n    if (!uid_detail)\n    {\n        throw uid_symbol_notfound_exception{\"Uid '\" + uid + \"' does not exist on the blockchain\"};\n    }\n\n    auto from_address = uid_detail->get_address();\n\n    // check uid is owned by the wallet\n    if (!blockchain.get_wallet_address(auth_.name, from_address))\n    {\n        throw uid_symbol_notowned_exception{\n            \"Uid '\" + uid + \"' is not owned by \" + auth_.name};\n    }\n\n    // check to address is valid\n    if (!blockchain.is_valid_address(argument_.to))\n        throw toaddress_invalid_exception{\"Invalid target address parameter!\"};\n\n    // check to address is owned by the wallet\n    if (!blockchain.get_wallet_address(auth_.name, argument_.to))\n    {\n        throw address_dismatch_wallet_exception{\"Target address is not owned by wallet. \" + argument_.to};\n    }\n\n    // fail if address is already binded with uid in blockchain\n    if (blockchain.is_address_registered_uid(argument_.to))\n    {\n        throw uid_symbol_existed_exception{\"Target address is already binded with some uid on the blockchain\"};\n    }\n\n    // receiver\n    std::vector<receiver_record> receiver{\n        {argument_.to, argument_.symbol, 0, 0, utxo_attach_type::uid_transfer, asset()}};\n\n    auto toaddr = bc::wallet::payment_address(argument_.to);\n    auto addr = bc::wallet::payment_address(from_address);\n\n    if (toaddr.version() == bc::wallet::payment_address::mainnet_p2sh && addr.version() == bc::wallet::payment_address::mainnet_p2sh)\n        throw uid_multisig_address_exception{\"uid cannot modify multi-signature address to multi-signature address\"};\n\n    if (addr.version() == bc::wallet::payment_address::mainnet_p2sh || toaddr.version() == bc::wallet::payment_address::mainnet_p2sh) // for multisig address\n    {\n\n        auto findmultisig = [&acc](wallet_multisig &acc_multisig, std::string address) {\n            auto multisig_vec = acc->get_multisig(address);\n            if (!multisig_vec || multisig_vec->empty())\n                return false;\n\n            acc_multisig = *(multisig_vec->begin());\n            return true;\n        };\n\n        wallet_multisig acc_multisig;\n        if (addr.version() == bc::wallet::payment_address::mainnet_p2sh && !findmultisig(acc_multisig, from_address))\n            throw multisig_notfound_exception{\"from address multisig record not found.\"};\n\n        wallet_multisig acc_multisig_to;\n        if (toaddr.version() == bc::wallet::payment_address::mainnet_p2sh && !findmultisig(acc_multisig_to, argument_.to))\n            throw multisig_notfound_exception{\"to address multisig record not found.\"};\n\n        auto send_helper = sending_multisig_uid(*this, blockchain, std::move(auth_.name), std::move(auth_.auth),\n                                                std::move(from_address), std::move(argument_.to),\n                                                std::move(argument_.symbol), std::move(receiver), argument_.fee,\n                                                std::move(acc_multisig), std::move(acc_multisig_to));\n\n        send_helper.exec();\n        // json output\n        auto &&tx = send_helper.get_transaction();\n        jv_output = config::json_helper(get_api_version()).prop_list_of_rawtx(tx, false, true);\n    }\n    else\n    {\n        auto send_helper = sending_uid(*this, blockchain,\n                                       std::move(auth_.name), std::move(auth_.auth),\n                                       std::move(from_address), std::move(argument_.to),\n                                       std::move(argument_.symbol), std::move(receiver), argument_.fee);\n\n        send_helper.exec();\n\n        // json output\n        auto tx = send_helper.get_transaction();\n        jv_output = config::json_helper(get_api_version()).prop_tree(tx, true);\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/validateaddress.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <jsoncpp/json/json.h>\n#include <UChainService/api/command/commands/validateaddress.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n/************************ validateaddress *************************/\n\nconsole_result validateaddress::invoke(Json::Value &jv_output,\n                                       libbitcoin::server::server_node &node)\n{\n    std::string version_info;\n    std::string message{\"valid address\"};\n    bool is_valid{true};\n\n    auto &blockchain = node.chain_impl();\n    const bool use_testnet_rules{blockchain.chain_settings().use_testnet_rules};\n    bc::wallet::payment_address payment_address(argument_.address);\n\n    if (blockchain.is_blackhole_address(argument_.address))\n    {\n        version_info = \"p2blackhole\";\n    }\n    else if (payment_address.version() == 0x44)\n    {\n        version_info = \"p2kh(main-net)\";\n    }\n    else if (payment_address.version() == 0x7f)\n    {\n        version_info = \"p2kh(test-net)\";\n    }\n    else if (payment_address.version() == payment_address::mainnet_p2sh)\n    {\n        version_info = \"p2sh(multi-signature)\";\n    }\n    else\n    {\n        version_info = \"none\";\n        message = \"invalid address!\";\n        is_valid = false;\n    }\n\n    auto &jv = jv_output;\n    if (get_api_version() <= 2)\n    {\n        jv[\"address-type\"] = version_info;\n        jv[\"test-net\"] = use_testnet_rules;\n        jv[\"is-valid\"] = is_valid;\n        jv[\"message\"] = message;\n    }\n    else\n    {\n        jv[\"address_type\"] = version_info;\n        jv[\"testnet\"] = use_testnet_rules;\n        jv[\"is_valid\"] = is_valid;\n        jv[\"message\"] = message;\n    }\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/commands/vote.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChain/explorer/json_helper.hpp>\n#include <UChain/explorer/dispatch.hpp>\n#include <UChainService/api/command/commands/vote.hpp>\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/command_assistant.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/base_helper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\nconsole_result vote::invoke(Json::Value &jv_output,\n                            libbitcoin::server::server_node &node)\n{\n    auto &blockchain = node.chain_impl();\n    blockchain.is_wallet_passwd_valid(auth_.name, auth_.auth);\n    std::string from_address = get_address_from_strict_uid(argument_.from, blockchain);\n    if (!blockchain.is_valid_address(from_address))\n        throw uid_symbol_name_exception{\"Uid symbol \" + argument_.from + \" is not valid.\"};\n\n    auto acc_addr = blockchain.get_wallet_address(auth_.name, from_address);\n    if (!acc_addr)\n        throw argument_legality_exception{\"You don't own address \" + from_address};\n\n    std::vector<receiver_record> receiver{};\n    uint64_t amount = 0;\n    for (auto &each : argument_.to)\n    {\n        colon_delimited2_item<std::string, uint64_t> item(each);\n\n        std::string address = get_address_from_strict_uid(item.first(), blockchain);\n        if (item.second() <= 0)\n        {\n            throw argument_legality_exception(\"invalid amount parameter for \" + item.first());\n        }\n        amount += item.second();\n        receiver.push_back({address, UC_VOTE_TOKEN_SYMBOL, 0, item.second(), utxo_attach_type::token_transfer, asset{argument_.from, item.first()}});\n    }\n\n    receiver.push_back({from_address, \"\", amount * coin_price(1) / 20, 0, utxo_attach_type::deposit, asset{\"\", argument_.from}});\n\n    auto vote_helper = voting_token(*this, blockchain, std::move(auth_.name), std::move(auth_.auth),\n                                    std::move(from_address), std::move(receiver), amount, option_.fee);\n\n    vote_helper.exec();\n\n    // json output\n    auto tx = vote_helper.get_transaction();\n    jv_output = config::json_helper(get_api_version()).prop_tree(tx, true);\n\n    return console_result::okay;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/exception.cpp",
    "content": "/*\n * exception.cpp\n *\n *  Created on: Jun 5, 2017\n *      Author: jiang\n */\n\n#include <jsoncpp/json/json.h>\n#include <UChain/coin/error.hpp>\n#include <UChainService/api/command/exception.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\n\nexplorer_exception::explorer_exception(uint32_t code, const std::string &message) : code_{code}, message_{message}\n{\n}\n\nstd::ostream &operator<<(std::ostream &out, const explorer_exception &ex)\n{\n    boost::format fmt{\"{\\\"code\\\":%d, \\\"error\\\":\\\"%s\\\", \\\"result\\\":null}\"};\n    out << (fmt % (int32_t)ex.code() % ex.message());\n    return out;\n}\n\nvoid relay_exception(std::stringstream &ss)\n{\n    try\n    {\n        Json::Reader reader;\n        Json::Value root;\n        if (reader.parse(ss, root) && root[\"code\"].isUInt() && root[\"message\"].isString())\n        {\n            auto code = root[\"code\"].asUInt();\n            auto msg = root[\"message\"].asString();\n            if (code)\n                throw explorer_exception{code, msg};\n        }\n    }\n    catch (const explorer_exception &e)\n    {\n        throw e;\n    }\n    catch (const std::exception &e)\n    {\n    }\n}\n\n} //namespace explorer\n} //namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/node_method_wrapper.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-explorer.\n *\n * UChain-explorer is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChainService/api/command/exception.hpp>\n#include <UChainService/api/command/node_method_wrapper.hpp>\n\nnamespace libbitcoin\n{\nnamespace explorer\n{\nnamespace commands\n{\n\n// ----------------------------- checker methods ------------------------------\n\nbool administrator_required_checker(bc::server::server_node &node,\n                                    const std::string &name, const std::string &auth)\n{\n    auto &blockchain = node.chain_impl();\n    // administrator_required option is true\n    if (node.server_settings().administrator_required)\n    {\n        if (!blockchain.is_admin_wallet(name))\n            throw wallet_authority_exception{\"Incorrect administrator name.\"};\n        blockchain.is_wallet_passwd_valid(name, auth);\n        return true;\n    }\n    else\n    {\n        return false;\n    }\n}\n\n// ----------------------------- qurey methods ------------------------------\nuint64_t get_last_height(bc::server::server_node &node)\n{\n    uint64_t last_height;\n    std::promise<code> p;\n\n    auto &blockchain = node.chain_impl();\n    blockchain.fetch_last_height([&p, &last_height](const code &ec, uint64_t height) {\n        if (ec)\n        {\n            p.set_value(ec);\n            return;\n        }\n\n        last_height = height;\n\n        p.set_value(error::success);\n    });\n\n    auto result = p.get_future().get();\n    if (result)\n    {\n        throw block_height_get_exception{result.message()};\n    }\n\n    return last_height;\n}\n\nuint32_t get_connections_count(bc::server::server_node &node)\n{\n    uint32_t ret;\n\n    node.connections_ptr()->count([&ret](size_t count) {\n        ret = count;\n    });\n\n    return ret;\n}\n\n} // namespace commands\n} // namespace explorer\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/api/command/wallet_info.cpp",
    "content": "/**\r\n * Copyright (c) 2018-2020 UChain developers \r\n *\r\n * This file is part of uc-node.\r\n *\r\n * UChain is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU Affero General Public License with\r\n * additional permissions to the one published by the Free Software\r\n * Foundation, either version 3 of the License, or (at your option)\r\n * any later version. For more information see LICENSE.\r\n *\r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU Affero General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Affero General Public License\r\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\r\n */\r\n#include <UChainService/api/command/wallet_info.hpp>\r\n\r\n#include <sstream>\r\n#include <boost/iostreams/stream.hpp>\r\n#include <UChain/coin/utility/container_sink.hpp>\r\n#include <UChain/coin/utility/container_source.hpp>\r\n#include <UChain/coin/utility/istream_reader.hpp>\r\n#include <UChain/coin/utility/ostream_writer.hpp>\r\n\r\n#include <UChain/coin/math/crypto.hpp>\r\n#include <UChain/coin.hpp>\r\n#include <UChain/coin/config/base16.hpp>\r\n#include <UChain/coin/math/checksum.hpp>\r\n\r\nusing namespace libbitcoin::wallet;\r\nusing namespace libbitcoin::config;\r\n\r\nnamespace libbitcoin\r\n{\r\nnamespace chain\r\n{\r\n\r\nwallet_info::wallet_info(blockchain::block_chain_impl &blockchain, std::string &passphrase) : blockchain_(blockchain),\r\n                                                                                              passphrase_(passphrase)\r\n{\r\n}\r\nwallet_info::wallet_info(blockchain::block_chain_impl &blockchain, std::string &passphrase,\r\n                         libbitcoin::chain::wallet &meta, std::vector<wallet_address> &addr_vec, std::vector<token_detail> &token_vec) : blockchain_(blockchain), passphrase_(passphrase), meta_(meta), addr_vec_(addr_vec), token_vec_(token_vec)\r\n{\r\n}\r\n\r\nbool wallet_info::from_data(const data_chunk &data)\r\n{\r\n    data_source istream(data);\r\n    return from_data(istream);\r\n}\r\n\r\nbool wallet_info::from_data(std::istream &stream)\r\n{\r\n    istream_reader source(stream);\r\n    return from_data(source);\r\n}\r\n\r\nbool wallet_info::from_data(reader &source)\r\n{\r\n    meta_.from_data(source);\r\n\r\n    wallet_address addr;\r\n    uint32_t addr_size = source.read_4_bytes_little_endian();\r\n    while (addr_size--)\r\n    {\r\n        addr.reset();\r\n        addr.from_data(source);\r\n        addr_vec_.push_back(addr);\r\n    }\r\n\r\n    token_detail detail;\r\n    uint32_t token_size = source.read_4_bytes_little_endian();\r\n    while (token_size--)\r\n    {\r\n        detail.reset();\r\n        detail.from_data(source);\r\n        token_vec_.push_back(detail);\r\n    }\r\n\r\n    return true;\r\n}\r\n\r\ndata_chunk wallet_info::to_data() const\r\n{\r\n    data_chunk data;\r\n    data_sink ostream(data);\r\n    to_data(ostream);\r\n    ostream.flush();\r\n    //BITCOIN_ASSERT(data.size() == serialized_size()); // serialized_size is not used\r\n    return data;\r\n}\r\n\r\nvoid wallet_info::to_data(std::ostream &stream) const\r\n{\r\n    ostream_writer sink(stream);\r\n    to_data(sink);\r\n}\r\n\r\nvoid wallet_info::to_data(writer &sink) const\r\n{\r\n    meta_.to_data(sink);\r\n    // wallet_address vector\r\n    sink.write_4_bytes_little_endian(addr_vec_.size());\r\n    if (addr_vec_.size())\r\n    {\r\n        for (auto &each : addr_vec_)\r\n        {\r\n            each.to_data(sink);\r\n        }\r\n    }\r\n    // wallet token vector\r\n    sink.write_4_bytes_little_endian(token_vec_.size());\r\n    if (token_vec_.size())\r\n    {\r\n        for (auto &each : token_vec_)\r\n        {\r\n            each.to_data(sink);\r\n        }\r\n    }\r\n}\r\nwallet wallet_info::get_wallet() const\r\n{\r\n    return meta_;\r\n}\r\nstd::vector<wallet_address> &wallet_info::get_wallet_address()\r\n{\r\n    return addr_vec_;\r\n}\r\nstd::vector<token_detail> &wallet_info::get_wallet_token()\r\n{\r\n    return token_vec_;\r\n}\r\nvoid wallet_info::store(std::string &name, std::string &passwd)\r\n{\r\n    // restore wallet\r\n    auto acc = std::make_shared<libbitcoin::chain::wallet>(meta_);\r\n    auto mnemonic = acc->get_mnemonic();\r\n    acc->set_name(name);\r\n    acc->set_mnemonic(mnemonic, passwd);\r\n    acc->set_passwd(passwd);\r\n    blockchain_.store_wallet(acc);\r\n\r\n    // restore wallet addresses\r\n    std::string prv_key;\r\n    for (auto &each : addr_vec_)\r\n    {\r\n        prv_key = each.get_prv_key();\r\n        each.set_prv_key(prv_key, passwd);\r\n        each.set_name(name);\r\n        auto addr = std::make_shared<wallet_address>(each);\r\n        blockchain_.store_wallet_address(addr);\r\n    }\r\n\r\n    // restore wallet token\r\n    for (auto &each : token_vec_)\r\n    {\r\n        each.set_issuer(name);\r\n        auto acc = std::make_shared<token_detail>(each);\r\n        blockchain_.store_wallet_token(acc, name);\r\n    }\r\n}\r\nvoid wallet_info::encrypt()\r\n{\r\n    auto src_data = to_data();\r\n    append_checksum(src_data);\r\n    data_chunk pass_chunk(passphrase_.begin(), passphrase_.end());\r\n    aes256_common_encrypt(src_data, pass_chunk, data_);\r\n}\r\nvoid wallet_info::decrypt(std::string &hexcode)\r\n{\r\n    data_chunk pass_chunk(passphrase_.begin(), passphrase_.end());\r\n    data_chunk encrypt_data = base16(hexcode);\r\n    aes256_common_decrypt(encrypt_data, pass_chunk, data_);\r\n    if (!verify_checksum(data_))\r\n        throw std::logic_error{\"error while decrypting the wallet.\"};\r\n}\r\nstd::istream &operator>>(std::istream &input, wallet_info &self_ref)\r\n{\r\n    std::string hexcode;\r\n    input >> hexcode;\r\n    self_ref.decrypt(hexcode);\r\n\r\n    data_chunk body(self_ref.data_.begin(), self_ref.data_.end() - libbitcoin::checksum_size);\r\n    self_ref.from_data(body);\r\n\r\n    return input;\r\n}\r\n\r\nstd::ostream &operator<<(std::ostream &output, const wallet_info &self_ref)\r\n{\r\n    wallet_info &tmp_self_ref = const_cast<wallet_info &>(self_ref);\r\n    tmp_self_ref.encrypt();\r\n    //output << base16(self_ref.to_data());\r\n    output << base16(self_ref.data_);\r\n    return output;\r\n}\r\n\r\n} // namespace chain\r\n} // namespace libbitcoin\r\n"
  },
  {
    "path": "src/UChainService/api/restful/MgServer.cpp",
    "content": "/*\n* Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS).\n* Copyright (C) 2013-2018 Swirly Cloud Limited.\n*\n* This program is free software; you can redistribute it and/or modify it under the terms of the\n* GNU General Public License as published by the Free Software Foundation; either version 2 of the\n* License, or (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n* General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License along with this program; if\n* not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n* 02110-1301, USA.\n*/\n\n#include <thread>\n#include <functional>\n#include <UChainService/api/restful/MgServer.hpp>\n#include <UChain/coin/utility/log.hpp>\n#include <UChain/coin/version.hpp>\n\nnamespace mgbubble\n{\nusing namespace std::placeholders;\n\nbool MgServer::start()\n{\n    if (!nc_)\n        return false;\n    if (running_)\n        return true;\n\n    running_ = true;\n    worker_ = std::make_shared<std::thread>([this]() { this->run(); });\n    return !!worker_;\n}\n\nvoid MgServer::stop()\n{\n    if (running_)\n    {\n        running_ = false;\n        if (!!worker_)\n            worker_->join();\n    }\n}\n\nbool MgServer::broadcast(const std::string &msg)\n{\n    if (!nc_ || !running_)\n        return false;\n\n    mg_broadcast(&mgr_, ev_broadcast, (void *)(msg.data()), msg.size() + 1);\n    return true;\n}\n\nbool MgServer::broadcast(const char *msg, size_t len)\n{\n    if (!nc_ || !running_)\n        return false;\n\n    mg_broadcast(&mgr_, ev_broadcast, (void *)(msg), len + 1);\n    return true;\n}\n\nbool MgServer::send(struct mg_connection &nc, const std::string &msg, bool close_required)\n{\n    if (!nc_ || !running_)\n        return false;\n\n    mg_send(&nc, msg.c_str(), msg.size());\n    if (close_required)\n        nc.flags |= MG_F_SEND_AND_CLOSE;\n    return true;\n}\n\nbool MgServer::send(struct mg_connection &nc, const char *msg, size_t len, bool close_required)\n{\n    if (!nc_ || !running_)\n        return false;\n\n    mg_send(&nc, msg, len);\n    if (close_required)\n        nc.flags |= MG_F_SEND_AND_CLOSE;\n    return true;\n}\n\nbool MgServer::send_frame(struct mg_connection &nc, const std::string &msg, bool binary)\n{\n    if (!nc_ || !running_)\n        return false;\n\n    mg_send_websocket_frame(&nc, (binary ? WEBSOCKET_OP_BINARY : WEBSOCKET_OP_TEXT), (void *)(msg.data()), msg.size());\n    return true;\n}\n\nbool MgServer::send_frame(struct mg_connection &nc, const char *msg, size_t len, bool binary)\n{\n    if (!nc_ || !running_)\n        return false;\n\n    mg_send_websocket_frame(&nc, (binary ? WEBSOCKET_OP_BINARY : WEBSOCKET_OP_TEXT), (void *)(msg), len);\n    return true;\n}\n\nvoid MgServer::run()\n{\n    while (running_)\n    {\n        mg_mgr_poll(&mgr_, 1000);\n    }\n}\n\nvoid MgServer::on_http_req_handler(struct mg_connection &nc, http_message &msg)\n{\n    mg_http_send_error(&nc, 403, nullptr);\n}\n\n// demo\nvoid MgServer::on_ws_handshake_req_handler(struct mg_connection &nc, http_message &msg)\n{\n    if ((mg_ncasecmp(msg.uri.p, \"/ws\", 3) != 0) && (mg_ncasecmp(msg.uri.p, \"/ws/\", 4) != 0))\n    {\n        nc.flags |= MG_F_SEND_AND_CLOSE;\n    }\n}\n\nvoid MgServer::on_ws_handshake_done_handler(struct mg_connection &nc)\n{\n}\n\n// echo\nvoid MgServer::on_ws_frame_handler(struct mg_connection &nc, websocket_message &msg)\n{\n    struct mg_str d = {(char *)msg.data, msg.size};\n    bc::log::info(NAME) << std::string(d.p, d.len);\n    mg_send_websocket_frame(&nc, WEBSOCKET_OP_TEXT, msg.data, msg.size);\n}\n\nvoid MgServer::on_ws_ctrlf_handler(struct mg_connection &nc, websocket_message &msg)\n{\n}\n\nvoid MgServer::on_timer_handler(struct mg_connection &nc)\n{\n}\n\nvoid MgServer::on_close_handler(struct mg_connection &nc)\n{\n}\n\nvoid MgServer::on_send_handler(struct mg_connection &nc, int bytes_transfered)\n{\n}\n\nvoid MgServer::on_notify_handler(struct mg_connection &nc, struct mg_event &ev)\n{\n}\n\nvoid MgServer::on_broadcast(struct mg_connection &nc, const char *ev_data)\n{\n}\n\nvoid MgServer::ev_handler_default(struct mg_connection *nc, int ev, void *ev_data)\n{\n}\n\nvoid MgServer::ev_broadcast(struct mg_connection *nc, int ev, void *ev_data)\n{\n    auto *self = dynamic_cast<MgServer *>(static_cast<MgServer *>(nc->mgr->user_data));\n    if (!self || self->stopped())\n        return;\n\n    self->on_broadcast(*nc, (const char *)ev_data);\n}\n\nvoid MgServer::ev_handler(struct mg_connection *nc, int ev, void *ev_data)\n{\n    auto *self = dynamic_cast<MgServer *>(static_cast<MgServer *>(nc->mgr->user_data));\n    if (!self || self->stopped())\n        return;\n    switch (ev)\n    {\n    case MG_EV_SEND:\n    {\n        self->on_send_handler(*nc, *((int *)ev_data));\n        break;\n    }\n    case MG_EV_HTTP_REQUEST:\n    {\n        struct http_message *msg = (struct http_message *)ev_data;\n        self->on_http_req_handler(*nc, *msg);\n        break;\n    }\n    case MG_EV_WEBSOCKET_HANDSHAKE_REQUEST:\n    {\n        struct http_message *msg = (struct http_message *)ev_data;\n        self->on_ws_handshake_req_handler(*nc, *msg);\n        break;\n    }\n    case MG_EV_WEBSOCKET_HANDSHAKE_DONE:\n    {\n        self->on_ws_handshake_done_handler(*nc);\n        break;\n    }\n    case MG_EV_WEBSOCKET_FRAME:\n    {\n        struct websocket_message *msg = (struct websocket_message *)ev_data;\n        self->on_ws_frame_handler(*nc, *msg);\n        break;\n    }\n    case MG_EV_WEBSOCKET_CONTROL_FRAME:\n    {\n        struct websocket_message *msg = (struct websocket_message *)ev_data;\n        self->on_ws_ctrlf_handler(*nc, *msg);\n        break;\n    }\n    case MG_EV_TIMER:\n    {\n        self->on_timer_handler(*nc);\n        break;\n    }\n    case MG_EV_CLOSE:\n    {\n        self->on_close_handler(*nc);\n        break;\n    }\n    default:\n        self->ev_handler_default(nc, ev, ev_data);\n    }\n}\n\nvoid MgServer::ev_notify_handler(struct mg_connection *nc, int ev, void *ev_data)\n{\n    auto *self = dynamic_cast<MgServer *>(static_cast<MgServer *>(nc->mgr->user_data));\n    if (!self || self->stopped())\n        return;\n    switch (ev)\n    {\n    case MG_EV_RECV:\n    {\n        if (nc->flags & MG_F_USER_2)\n        {\n            assert(nc->recv_mbuf.len >= sizeof(struct mg_event));\n            assert(static_cast<size_t>(*((int *)(ev_data))) >= sizeof(struct mg_event));\n            size_t len = 0;\n            size_t maxlen = nc->recv_mbuf.len / sizeof(struct mg_event) * sizeof(struct mg_event);\n            for (; len < maxlen; len += sizeof(struct mg_event))\n            {\n                struct mg_event *pev = (struct mg_event *)(nc->recv_mbuf.buf + len);\n                self->on_notify_handler(*nc, *pev);\n            }\n            mbuf_remove(&nc->recv_mbuf, len);\n        }\n        break;\n    }\n    }\n}\n\n} // namespace mgbubble\n"
  },
  {
    "path": "src/UChainService/api/restful/Mongoose.cpp",
    "content": "/*\r\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS).\r\n * Copyright (C) 2013-2018 Swirly Cloud Limited.\r\n *\r\n * This program is free software; you can redistribute it and/or modify it under the terms of the\r\n * GNU General Public License as published by the Free Software Foundation; either version 2 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\r\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r\n * General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU General Public License along with this program; if\r\n * not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\r\n * 02110-1301, USA.\r\n */\r\n#include <cctype>\r\n#include <jsoncpp/json/json.h>\r\n#include <UChainService/api/restful/Mongoose.hpp>\r\n#include <UChainService/api/restful/utility/Tokeniser.hpp>\r\n#include <UChainService/api/command/exception.hpp>\r\n\r\nnamespace mgbubble\r\n{\r\n\r\nvoid HttpMessage::data_to_arg(uint8_t rpc_version)\r\n{\r\n\r\n    auto vargv_to_argv = [this]() {\r\n        // convert to char** argv\r\n        int i = 0;\r\n        for (auto &iter : this->vargv_)\r\n        {\r\n            if (i >= max_paramters)\r\n            {\r\n                break;\r\n            }\r\n            this->argv_[i++] = iter.c_str();\r\n        }\r\n        argc_ = i;\r\n    };\r\n\r\n    Json::Reader reader;\r\n    Json::Value root;\r\n    const char *begin = body().data();\r\n    const char *end = body().data() + body().size();\r\n    if (!reader.parse(begin, end, root) || !root.isObject())\r\n    {\r\n        throw libbitcoin::explorer::jsonrpc_parse_error();\r\n    }\r\n\r\n    if (root[\"method\"].isString())\r\n    {\r\n        vargv_.emplace_back(root[\"method\"].asString());\r\n    }\r\n\r\n    if (root.isMember(\"params\") && !root[\"params\"].isArray())\r\n    {\r\n        throw libbitcoin::explorer::jsonrpc_invalid_params();\r\n    }\r\n\r\n    if (rpc_version == 1)\r\n    {\r\n        /* ***************** /rpc **********************\r\n         * application/json\r\n         * {\"method\":\"xxx\", \"params\":[\"p1\",\"p2\"]}\r\n         * ******************************************/\r\n        for (auto &param : root[\"params\"])\r\n        {\r\n            if (!param.isObject())\r\n                vargv_.emplace_back(param.asString());\r\n        }\r\n    }\r\n    else\r\n    {\r\n        /* ***************** /rpc/v2 or /rpc/v3 **********************\r\n         * application/json\r\n         * {\r\n         *  \"method\":\"xxx\",\r\n         *  \"params\":[\r\n         *      {\r\n         *          k1:v1,  ==> Command Option\r\n         *          k2:v2\r\n         *      },\r\n         *      \"p1\",  ==> Command Argument\r\n         *      \"p2\"\r\n         *      ]\r\n         *  }\r\n         * ******************************************/\r\n\r\n        const vector<std::string> api20_ver_list = {\"2.0\", \"3.0\"};\r\n        auto checkAPIVer = [](const vector<std::string> &api_ver_list, const std::string &rpc_version) {\r\n            return find(api_ver_list.begin(), api_ver_list.end(), rpc_version) != api_ver_list.end();\r\n        };\r\n\r\n        if (!checkAPIVer(api20_ver_list, root[\"jsonrpc\"].asString()))\r\n        {\r\n            throw libbitcoin::explorer::jsonrpc_invalid_request();\r\n        }\r\n\r\n        if (root[\"id\"].isString())\r\n        {\r\n            jsonrpc_id_ = std::stol(root[\"id\"].asString());\r\n        }\r\n        else\r\n        {\r\n            jsonrpc_id_ = root[\"id\"].asInt64();\r\n        }\r\n\r\n        // push options\r\n        for (auto &param : root[\"params\"])\r\n        {\r\n            if (param.isObject())\r\n            {\r\n                for (auto &key : param.getMemberNames())\r\n                {\r\n                    if (!param[key].empty())\r\n                    {\r\n\r\n                        if (!param[key].isArray())\r\n                        {\r\n                            // --option\r\n                            vargv_.emplace_back(\"--\" + key);\r\n                            // value\r\n                            vargv_.emplace_back(param[key].asString());\r\n                        }\r\n                        else\r\n                        {\r\n                            for (auto &member : param[key])\r\n                            {\r\n                                // --option\r\n                                vargv_.emplace_back(\"--\" + key);\r\n                                // value\r\n                                vargv_.emplace_back(member.asString());\r\n                            }\r\n                        }\r\n                    }\r\n                    else\r\n                    {\r\n                        // --option\r\n                        vargv_.emplace_back(\"--\" + key);\r\n                    }\r\n                }\r\n                break;\r\n            }\r\n        }\r\n\r\n        // push arguments at last\r\n        for (auto &param : root[\"params\"])\r\n        {\r\n            if (!param.isObject())\r\n            {\r\n                vargv_.emplace_back(param.asString());\r\n            }\r\n        }\r\n    }\r\n\r\n    vargv_to_argv();\r\n}\r\n\r\nvoid WebsocketMessage::data_to_arg(uint8_t api_version)\r\n{\r\n    Tokeniser<' '> args;\r\n    args.reset(+*impl_);\r\n\r\n    // store args from ws message\r\n    do\r\n    {\r\n        //skip spaces\r\n        if (args.top().front() == ' ')\r\n        {\r\n            args.pop();\r\n            continue;\r\n        }\r\n        else if (std::iscntrl(args.top().front()))\r\n        {\r\n            break;\r\n        }\r\n        else\r\n        {\r\n            this->vargv_.push_back({args.top().data(), args.top().size()});\r\n            args.pop();\r\n        }\r\n    } while (!args.empty());\r\n\r\n    // convert to char** argv\r\n    int i = 0;\r\n    for (auto &iter : vargv_)\r\n    {\r\n        if (i >= max_paramters)\r\n        {\r\n            break;\r\n        }\r\n        argv_[i++] = iter.c_str();\r\n    }\r\n    argc_ = i;\r\n}\r\n\r\nvoid ToCommandArg::add_arg(std::string &&outside)\r\n{\r\n    vargv_.push_back(outside);\r\n    argc_++;\r\n}\r\n\r\n} // namespace mgbubble\r\n"
  },
  {
    "path": "src/UChainService/api/restful/RestServ.cpp",
    "content": "/*\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS).\n * Copyright (C) 2013-2018 Swirly Cloud Limited.\n *\n * This program is free software; you can redistribute it and/or modify it under the terms of the\n * GNU General Public License as published by the Free Software Foundation; either version 2 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along with this program; if\n * not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n * 02110-1301, USA.\n */\n#include <exception>\n#include <functional> //hash\n\n#include <UChainService/api/restful/RestServ.hpp>\n#include <UChainService/api/restful/exception/Instances.hpp>\n#include <UChainService/api/restful/utility/Stream_buf.hpp>\n\n#include <UChainService/api/command/command_extension_func.hpp>\n#include <UChainService/api/command/exception.hpp>\n#include <UChainApp/ucd/server_node.hpp>\n\nnamespace mgbubble\n{\n\nthread_local OStream RestServ::out_;\nthread_local Tokeniser<'/'> RestServ::uri_;\nthread_local int RestServ::state_ = 0;\n\nvoid RestServ::reset(HttpMessage &data) noexcept\n{\n    state_ = 0;\n\n    const auto method = data.method();\n    if (method == \"GET\")\n    {\n        state_ |= MethodGet;\n    }\n    else if (method == \"POST\")\n    {\n        state_ |= MethodPost;\n    }\n    else if (method == \"PUT\")\n    {\n        state_ |= MethodPut;\n    }\n    else if (method == \"DELETE\")\n    {\n        state_ |= MethodDelete;\n    }\n\n    auto uri = data.uri();\n    // Remove leading slash.\n    if (uri.front() == '/')\n    {\n        uri.remove_prefix(1);\n    }\n    uri_.reset(uri);\n}\n\nvoid RestServ::rpc_request(mg_connection &nc, HttpMessage data, uint8_t rpc_version)\n{\n    reset(data);\n    StreamBuf buf{nc.send_mbuf};\n    out_.rdbuf(&buf);\n    out_.reset(200, \"OK\");\n\n    const vector<uint8_t> api20_ver_list = {2, 3};\n    auto checkAPIVer = [](const vector<uint8_t> &api_ver_list, const uint8_t &rpc_version) {\n        return find(api_ver_list.begin(), api_ver_list.end(), rpc_version) != api_ver_list.end();\n    };\n    try\n    {\n        data.data_to_arg(rpc_version);\n\n        Json::Value jv_output;\n\n        auto retcode = explorer::dispatch_command(data.argc(), const_cast<const char **>(data.argv()),\n                                                  jv_output, node_, rpc_version);\n\n        if (retcode == console_result::failure)\n        { // only orignal command\n            if (rpc_version == 1 && !jv_output.isObject() && !jv_output.isArray())\n            {\n                throw explorer::command_params_exception{jv_output.asString()};\n            }\n            throw explorer::command_params_exception{jv_output.toStyledString()};\n        }\n\n        if (retcode == console_result::okay)\n        {\n            if (rpc_version == 1)\n            {\n                if (jv_output.isObject() || jv_output.isArray())\n                    out_ << jv_output.toStyledString();\n                else\n                    out_ << jv_output.asString();\n            }\n            else if (checkAPIVer(api20_ver_list, rpc_version))\n            {\n                Json::Value jv_root;\n                jv_root[\"jsonrpc\"] = \"3.0\";\n                jv_root[\"id\"] = data.jsonrpc_id();\n                jv_root[\"result\"] = jv_output;\n\n                out_ << jv_root.toStyledString();\n            }\n        }\n    }\n    catch (const libbitcoin::explorer::explorer_exception &e)\n    {\n        if (rpc_version == 1)\n        {\n            out_ << e;\n        }\n        else if (checkAPIVer(api20_ver_list, rpc_version))\n        {\n            Json::Value root;\n            root[\"jsonrpc\"] = \"3.0\";\n            root[\"id\"] = data.jsonrpc_id();\n            root[\"error\"][\"code\"] = (int32_t)e.code();\n            root[\"error\"][\"message\"] = e.what();\n\n            out_ << root.toStyledString();\n        }\n    }\n    catch (const std::exception &e)\n    {\n        if (rpc_version == 1)\n        {\n            libbitcoin::explorer::explorer_exception ex(1000, e.what());\n            out_ << ex;\n        }\n        else if (checkAPIVer(api20_ver_list, rpc_version))\n        {\n            Json::Value root;\n            root[\"jsonrpc\"] = \"3.0\";\n            root[\"id\"] = data.jsonrpc_id();\n            root[\"error\"][\"code\"] = 1000;\n            root[\"error\"][\"message\"] = e.what();\n\n            out_ << root.toStyledString();\n        }\n    }\n    out_.setContentLength();\n}\n\nvoid RestServ::ws_request(mg_connection &nc, WebsocketMessage ws)\n{\n    Json::Value jv_output;\n\n    try\n    {\n        ws.data_to_arg();\n\n        console_result retcode = explorer::dispatch_command(ws.argc(), const_cast<const char **>(ws.argv()), jv_output, node_);\n        if (retcode != console_result::okay)\n        {\n            throw explorer::command_params_exception(jv_output.asString());\n        }\n    }\n    catch (const std::exception &e)\n    {\n        jv_output = Json::objectValue;\n        jv_output[\"error\"][\"code\"] = 1000;\n        jv_output[\"error\"][\"message\"] = e.what();\n    }\n\n    if (jv_output.isObject() || jv_output.isArray())\n        send_frame(nc, jv_output.toStyledString());\n    else\n        send_frame(nc, jv_output.asString());\n}\n\nbool RestServ::start()\n{\n    if (!attach_notify())\n        return false;\n    return base::start();\n}\n\nvoid RestServ::spawn_to_mongoose(const std::function<void(uint64_t)> &&handler)\n{\n    auto msg = std::make_shared<MgEvent>(std::move(handler));\n    struct mg_event ev\n    {\n        msg->hook()\n    };\n    if (!notify(ev))\n        msg->unhook();\n}\n\nvoid RestServ::run()\n{\n    log::info(LOG_HTTP) << \"Http Service listen on \" << node_.server_settings().mongoose_listen;\n\n    node_.subscribe_stop([this](const libbitcoin::code &ec) { stop(); });\n\n    base::run();\n\n    log::info(LOG_HTTP) << \"Http Service Stopped.\";\n}\n\nvoid RestServ::on_http_req_handler(struct mg_connection &nc, http_message &msg)\n{\n    if ((mg_ncasecmp(msg.uri.p, \"/rpc/v3\", 7) == 0) || (mg_ncasecmp(msg.uri.p, \"/rpc/v3/\", 8) == 0))\n    {\n        rpc_request(nc, HttpMessage(&msg), 3); // v3 rpc\n    }\n    else if ((mg_ncasecmp(msg.uri.p, \"/rpc/v2\", 7) == 0) || (mg_ncasecmp(msg.uri.p, \"/rpc/v2/\", 8) == 0))\n    {\n        rpc_request(nc, HttpMessage(&msg), 2); // v2 rpc\n    }\n    else if ((mg_ncasecmp(msg.uri.p, \"/rpc\", 4) == 0) || (mg_ncasecmp(msg.uri.p, \"/rpc/\", 5) == 0))\n    {\n        rpc_request(nc, HttpMessage(&msg), 1); //v1 rpc\n    }\n    else\n    {\n        std::shared_ptr<struct mg_connection> con(&nc, [](struct mg_connection *ptr) { (void)(ptr); });\n        serve_http_static(nc, msg);\n    }\n}\n\nvoid RestServ::on_notify_handler(struct mg_connection &nc, struct mg_event &ev)\n{\n    static uint64_t api_call_counter = 0;\n\n    if (ev.data == nullptr)\n        return;\n\n    auto &msg = *(MgEvent *)ev.data;\n    msg(++api_call_counter);\n}\n\nvoid RestServ::on_ws_handshake_done_handler(struct mg_connection &nc)\n{\n    std::shared_ptr<struct mg_connection> con(&nc, [](struct mg_connection *ptr) { (void)(ptr); });\n    send_frame(nc, \"connected\", 9);\n}\n\nvoid RestServ::on_ws_frame_handler(struct mg_connection &nc, websocket_message &msg)\n{\n    std::istringstream iss;\n    iss.str(std::string((const char *)msg.data, msg.size));\n    ws_request(nc, WebsocketMessage(&msg));\n}\n\n} // namespace mgbubble\n"
  },
  {
    "path": "src/UChainService/api/restful/WsPushServ.cpp",
    "content": "/*\n* Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS).\n* Copyright (C) 2013-2018 Swirly Cloud Limited.\n*\n* This program is free software; you can redistribute it and/or modify it under the terms of the\n* GNU General Public License as published by the Free Software Foundation; either version 2 of the\n* License, or (at your option) any later version.\n*\n* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n* General Public License for more details.\n*\n* You should have received a copy of the GNU General Public License along with this program; if\n* not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n* 02110-1301, USA.\n*/\n\n#include <thread>\n#include <sstream>\n#include <UChain/explorer/json_helper.hpp>\n#include <UChainService/api/restful/WsPushServ.hpp>\n#include <UChainApp/ucd/server_node.hpp>\n\nnamespace mgbubble\n{\nconstexpr auto EV_VERSION = \"version\";\nconstexpr auto EV_SUBSCRIBE = \"subscribe\";\nconstexpr auto EV_UNSUBSCRIBE = \"unsubscribe\";\nconstexpr auto EV_SUBSCRIBED = \"subscribed\";\nconstexpr auto EV_UNSUBSCRIBED = \"unsubscribed\";\nconstexpr auto EV_PUBLISH = \"publish\";\nconstexpr auto EV_REQUEST = \"request\";\nconstexpr auto EV_RESPONSE = \"response\";\nconstexpr auto EV_MG_ERROR = \"error\";\nconstexpr auto EV_INFO = \"info\";\nconstexpr auto EV_PING = \"ping\";\n\nconstexpr auto CH_BLOCK = \"block\";\nconstexpr auto CH_HEIGHT = \"height\";\nconstexpr auto CH_TRANSACTION = \"tx\";\nconstexpr auto CH_ALL = \"all\";\n\nconstexpr int JSON_FORMAT_VERSION = 3;\n} // namespace mgbubble\n\nnamespace mgbubble\n{\nusing namespace bc;\nusing namespace libbitcoin;\n\nexplorer::config::json_helper get_json_helper()\n{\n    return explorer::config::json_helper(JSON_FORMAT_VERSION);\n}\n\nvoid WsPushServ::run()\n{\n    log::info(NAME) << \"Websocket Service listen on \" << node_.server_settings().websocket_listen;\n\n    node_.subscribe_stop([this](const libbitcoin::code &ec) { stop(); });\n\n    node_.subscribe_tx_pool(\n        std::bind(&WsPushServ::handle_tx_pool,\n                  this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));\n\n    node_.subscribe_blockchain(\n        std::bind(&WsPushServ::handle_blockchain_reorganization,\n                  this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));\n\n    base::run();\n\n    log::info(NAME) << \"Websocket Service Stopped.\";\n}\n\nbool WsPushServ::start()\n{\n    if (node_.server_settings().websocket_service_enabled == false)\n        return true;\n    if (!attach_notify())\n        return false;\n    return base::start();\n}\n\nvoid WsPushServ::spawn_to_mongoose(const std::function<void(uint64_t)> &&handler)\n{\n    auto msg = std::make_shared<WsEvent>(std::move(handler));\n    struct mg_event ev\n    {\n        msg->hook()\n    };\n    if (!notify(ev))\n        msg->unhook();\n}\n\nbool WsPushServ::handle_tx_pool(const code &ec, const index_list &, message::tx_message::ptr tx)\n{\n    if (stopped())\n        return false;\n    if (ec == (code)error::mock || ec == (code)error::service_stopped)\n        return true;\n    if (ec)\n    {\n        log::debug(NAME) << \"Failure handling new transaction: \" << ec.message();\n        return true;\n    }\n\n    notify_transaction(0, null_hash, *tx);\n    return true;\n}\n\nbool WsPushServ::handle_blockchain_reorganization(const code &ec, uint64_t fork_point, const block_list &new_blocks, const block_list &)\n{\n    if (stopped())\n        return false;\n    if (ec == (code)error::mock || ec == (code)error::service_stopped)\n        return true;\n    if (ec)\n    {\n        log::debug(NAME) << \"Failure handling new block: \" << ec.message();\n        return true;\n    }\n\n    const auto fork_point32 = static_cast<uint32_t>(fork_point);\n\n    notify_blocks(fork_point32, new_blocks);\n    return true;\n}\n\nvoid WsPushServ::notify_blocks(uint32_t fork_point, const block_list &blocks)\n{\n    if (stopped())\n        return;\n\n    //auto height = fork_point;\n\n    for (const auto block : blocks)\n        notify_block(block.get()->header.number, block);\n}\n\nvoid WsPushServ::notify_block(uint32_t height, const block::ptr block)\n{\n    if (stopped())\n        return;\n\n    notify_block_impl(height, block);\n\n    const auto block_hash = block->header.hash();\n    for (const auto &tx : block->transactions)\n    {\n        const auto tx_hash = tx.hash();\n\n        notify_transaction(height, block_hash, tx);\n    }\n}\n\nvoid WsPushServ::notify_block_impl(uint32_t height, const bc::chain::block::ptr block)\n{\n    connection_string_map subscribers;\n    {\n        std::lock_guard<std::mutex> guard(block_subscribers_lock_);\n        if (block_subscribers_.size() == 0)\n        {\n            return;\n        }\n\n        for (auto &con : block_subscribers_)\n        {\n            if (!con.first.expired())\n            {\n                subscribers.insert(con);\n            }\n        }\n\n        if (subscribers.size() != block_subscribers_.size())\n        {\n            block_subscribers_ = subscribers;\n        }\n    }\n\n    std::vector<std::weak_ptr<mg_connection>> notify_block_cons;\n    std::vector<std::weak_ptr<mg_connection>> notify_height_cons;\n    for (auto &sub : subscribers)\n    {\n        auto &params = sub.second;\n        if (params.end() != std::find(params.begin(), params.end(), CH_HEIGHT))\n        {\n            notify_height_cons.push_back(sub.first);\n        }\n\n        if (params.end() != std::find(params.begin(), params.end(), CH_BLOCK))\n        {\n            notify_block_cons.push_back(sub.first);\n        }\n    }\n\n    if (notify_block_cons.size() > 0)\n    {\n        Json::Value root;\n        root[\"event\"] = EV_PUBLISH;\n        root[\"channel\"] = CH_BLOCK;\n        root[\"result\"] = get_json_helper().prop_tree(*block, true, true);\n\n        // log::info(NAME) << \" ******** notify_block: height [\" << height << \"]  ******** \";\n\n        do_notify(notify_block_cons, root);\n    }\n\n    if (notify_height_cons.size() > 0)\n    {\n        Json::Value root;\n        root[\"event\"] = EV_PUBLISH;\n        root[\"channel\"] = CH_HEIGHT;\n        root[\"result\"] = height;\n\n        // log::info(NAME) << \" ******** notify_height: height [\" << height << \"]  ******** \";\n\n        do_notify(notify_height_cons, root);\n    }\n}\n\nvoid WsPushServ::do_notify(\n    const std::vector<std::weak_ptr<mg_connection>> &notify_cons,\n    Json::Value &root,\n    std::shared_ptr<connection_string_map> topic_map)\n{\n    auto orignal_rep = root.toStyledString();\n\n    for (auto &con : notify_cons)\n    {\n        auto shared_con = con.lock();\n        if (!shared_con)\n        {\n            continue;\n        }\n\n        std::string rep;\n        if (topic_map != nullptr)\n        {\n            auto iter = topic_map->find(con);\n            if (iter != topic_map->end())\n            {\n                auto &topics = iter->second;\n                if (topics.end() != std::find(topics.begin(), topics.end(), CH_ALL))\n                {\n                    root[\"topic\"] = CH_ALL;\n                }\n                else if (topics.size() == 1)\n                {\n                    root[\"topic\"] = topics[0];\n                }\n                else\n                {\n                    Json::Value value;\n                    for (auto &topic : topics)\n                    {\n                        value.append(topic);\n                    }\n                    if (value.isNull())\n                        value.resize(0);\n\n                    root[\"topic\"] = value;\n                }\n\n                rep = root.toStyledString();\n            }\n        }\n\n        if (rep.empty())\n        {\n            rep = orignal_rep;\n        }\n\n        spawn_to_mongoose([this, shared_con, rep](uint64_t id) {\n            size_t active_connections = 0;\n            auto *mgr = &this->mg_mgr();\n            auto *notify_nc = shared_con.get();\n            for (auto *nc = mg_next(mgr, NULL); nc != NULL; nc = mg_next(mgr, nc))\n            {\n                if (!is_websocket(*nc) || is_listen_socket(*nc) || is_notify_socket(*nc))\n                    continue;\n                ++active_connections;\n                if (notify_nc == nc)\n                {\n                    send_frame(*nc, rep);\n                }\n            }\n\n            if (active_connections != map_connections_.size())\n            {\n                refresh_connections();\n            }\n        });\n    }\n}\n\nvoid WsPushServ::notify_transaction(uint32_t height, const hash_digest &block_hash, const transaction &tx)\n{\n    if (stopped() || tx.outputs.empty())\n    {\n        return;\n    }\n\n    connection_string_map subscribers;\n    {\n        std::lock_guard<std::mutex> guard(subscribers_lock_);\n        if (subscribers_.size() == 0)\n        {\n            return;\n        }\n\n        for (auto &con : subscribers_)\n        {\n            if (!con.first.expired())\n            {\n                subscribers.insert(con);\n            }\n        }\n\n        if (subscribers.size() != subscribers_.size())\n        {\n            subscribers_ = subscribers;\n        }\n    }\n\n    /* ---------- may has subscribers ---------- */\n\n    string_vector tx_addrs;\n    for (const auto &input : tx.inputs)\n    {\n        const auto address = payment_address::extract(input.script);\n        if (address)\n        {\n            auto addr_hash = address.encoded();\n            if (tx_addrs.end() == std::find(tx_addrs.begin(), tx_addrs.end(), addr_hash))\n            {\n                tx_addrs.push_back(addr_hash);\n            }\n        }\n    }\n\n    for (const auto &output : tx.outputs)\n    {\n        const auto address = payment_address::extract(output.script);\n        if (address)\n        {\n            auto addr_hash = address.encoded();\n            if (tx_addrs.end() == std::find(tx_addrs.begin(), tx_addrs.end(), addr_hash))\n            {\n                tx_addrs.push_back(addr_hash);\n            }\n        }\n    }\n\n    std::shared_ptr<connection_string_map> topic_map = std::make_shared<connection_string_map>();\n\n    std::vector<std::weak_ptr<mg_connection>> notify_cons;\n    for (auto &sub : subscribers)\n    {\n        string_vector topics;\n        auto &sub_addrs = sub.second;\n        if (sub_addrs.empty())\n        {\n            topics.push_back(CH_ALL);\n        }\n        else\n        {\n            for (auto &addr_hash : sub_addrs)\n            {\n                if (tx_addrs.end() != std::find(tx_addrs.begin(), tx_addrs.end(), addr_hash))\n                {\n                    topics.push_back(addr_hash);\n                }\n            }\n        }\n\n        if (!topics.empty())\n        {\n            topic_map->insert({sub.first, topics});\n            notify_cons.push_back(sub.first);\n        }\n    }\n\n    if (notify_cons.size() == 0)\n    {\n        return;\n    }\n\n    // log::info(NAME) << \" ******** notify_transaction: height [\" << height << \"]  ******** \";\n\n    Json::Value root;\n    root[\"event\"] = EV_PUBLISH;\n    root[\"channel\"] = CH_TRANSACTION;\n    root[\"result\"] = get_json_helper().prop_list(tx, height, true);\n\n    do_notify(notify_cons, root, topic_map);\n}\n\nvoid WsPushServ::send_bad_response(struct mg_connection &nc, const char *message, int code, Json::Value data)\n{\n    Json::Value root;\n    Json::Value result;\n    result[\"code\"] = code;\n    result[\"message\"] = message ? message : \"bad request\";\n    if (!data.isNull())\n        result[\"data\"] = data;\n    root[\"event\"] = EV_MG_ERROR;\n    root[\"result\"] = result;\n\n    auto &&tmp = root.toStyledString();\n    send_frame(nc, tmp.c_str(), tmp.size());\n}\n\nvoid WsPushServ::send_response(struct mg_connection &nc, const std::string &event, const std::string &channel, Json::Value data)\n{\n    Json::Value root;\n    root[\"event\"] = event;\n    if (!channel.empty())\n    {\n        root[\"channel\"] = channel;\n    }\n\n    if (!data.isNull())\n    {\n        root[\"result\"] = data;\n    }\n\n    auto &&tmp = root.toStyledString();\n    send_frame(nc, tmp.c_str(), tmp.size());\n}\n\nvoid WsPushServ::refresh_connections()\n{\n    auto *mgr = &mg_mgr();\n    std::unordered_map<void *, std::shared_ptr<mg_connection>> swap;\n    for (auto *nc = mg_next(mgr, NULL); nc != NULL; nc = mg_next(mgr, nc))\n    {\n        if (!is_websocket(*nc) || is_listen_socket(*nc) || is_notify_socket(*nc))\n            continue;\n        std::shared_ptr<struct mg_connection> con(nc, [](struct mg_connection *ptr) { (void)(ptr); });\n        swap.emplace(&nc, con);\n    }\n    map_connections_.swap(swap);\n}\n\nvoid WsPushServ::on_ws_handshake_done_handler(struct mg_connection &nc)\n{\n    std::shared_ptr<struct mg_connection> con(&nc, [](struct mg_connection *ptr) { (void)(ptr); });\n    map_connections_.emplace(&nc, con);\n\n    std::string version(\"{\\\"event\\\": \\\"version\\\", \"\n                        \"\\\"result\\\": \\\"\" UC_VERSION \"\\\"}\");\n    send_frame(nc, version);\n\n    std::stringstream ss;\n    Json::Value root;\n    Json::Value connections;\n    connections[\"connections\"] = static_cast<uint64_t>(map_connections_.size());\n    root[\"event\"] = EV_INFO;\n    root[\"result\"] = connections;\n\n    auto &&tmp = root.toStyledString();\n    send_frame(nc, tmp);\n}\n\nvoid WsPushServ::on_ws_frame_handler(struct mg_connection &nc, websocket_message &msg)\n{\n    Json::Reader reader;\n    Json::Value root;\n    if (node_.is_blockchain_sync())\n    {\n        send_bad_response(nc, \"under blockchain synchronizing\", 1000002);\n        return;\n    }\n\n    try\n    {\n        const char *begin = (const char *)msg.data;\n        const char *end = begin + msg.size;\n        if (!reader.parse(begin, end, root) || !root.isObject() || !root[\"event\"].isString())\n        {\n            stringstream ss;\n            ss << \"parse request error, \"\n               << reader.getFormattedErrorMessages();\n            throw std::runtime_error(ss.str());\n            return;\n        }\n\n        std::string channel;\n        auto event = root[\"event\"].asString();\n        if (event == EV_SUBSCRIBE || event == EV_UNSUBSCRIBE)\n        {\n            if (!root[\"channel\"].isString())\n            {\n                stringstream ss;\n                ss << \"parse request error, \"\n                   << reader.getFormattedErrorMessages();\n                throw std::runtime_error(ss.str());\n                return;\n            }\n\n            channel = root[\"channel\"].asString();\n        }\n\n        if ((event == EV_SUBSCRIBE) && (channel == CH_TRANSACTION))\n        {\n            if (!root[\"address\"].isString() && !root[\"address\"].isArray())\n            {\n                stringstream ss;\n                ss << \"parse request error, invalid address!\"\n                   << reader.getFormattedErrorMessages();\n                throw std::runtime_error(ss.str());\n                return;\n            }\n\n            std::vector<std::string> addresses;\n            if (root[\"address\"].isString())\n            {\n                auto short_addr = root[\"address\"].asString();\n                auto pay_addr = payment_address(short_addr);\n                if (!short_addr.empty() && !pay_addr)\n                {\n                    send_bad_response(nc, \"invalid address.\");\n                    return;\n                }\n\n                addresses.push_back(short_addr);\n            }\n            else if (root[\"address\"].isArray())\n            {\n                auto array = root[\"address\"];\n                int length = (int)(array.size());\n                for (int i = 0; i < length; ++i)\n                {\n                    auto item = array[i];\n                    if (!item.isString())\n                    {\n                        send_bad_response(nc, \"invalid address.\");\n                        return;\n                    }\n\n                    auto short_addr = item.asString();\n                    auto pay_addr = payment_address(short_addr);\n                    if (!short_addr.empty() && !pay_addr)\n                    {\n                        send_bad_response(nc, \"invalid address.\");\n                        return;\n                    }\n\n                    if (addresses.end() == std::find(addresses.begin(), addresses.end(), short_addr))\n                    {\n                        addresses.push_back(short_addr);\n                    }\n                }\n            }\n            else\n            {\n                send_bad_response(nc, \"invalid address.\");\n                return;\n            }\n\n            auto it = map_connections_.find(&nc);\n            if (it != map_connections_.end())\n            {\n                std::lock_guard<std::mutex> guard(subscribers_lock_);\n                std::weak_ptr<struct mg_connection> week_con(it->second);\n                auto sub_it = subscribers_.find(week_con);\n                if (sub_it != subscribers_.end())\n                {\n                    auto &sub_list = sub_it->second;\n\n                    if (addresses.empty())\n                    {\n                        sub_list.clear();\n                        send_response(nc, EV_SUBSCRIBED, channel);\n                        return;\n                    }\n\n                    for (const auto &address : addresses)\n                    {\n                        if (sub_list.end() == std::find(sub_list.begin(), sub_list.end(), address))\n                        {\n                            sub_list.push_back(address);\n                        }\n                    }\n\n                    send_response(nc, EV_SUBSCRIBED, channel);\n                }\n                else\n                {\n                    string_vector sub_list;\n                    for (const auto &address : addresses)\n                    {\n                        if (sub_list.end() == std::find(sub_list.begin(), sub_list.end(), address))\n                        {\n                            sub_list.push_back(address);\n                        }\n                    }\n\n                    subscribers_.insert({week_con, sub_list});\n                    send_response(nc, EV_SUBSCRIBED, channel);\n                }\n            }\n            else\n            {\n                send_bad_response(nc, \"connection lost.\");\n            }\n        }\n        else if ((event == EV_UNSUBSCRIBE) && (channel == CH_TRANSACTION))\n        {\n            auto it = map_connections_.find(&nc);\n            if (it != map_connections_.end())\n            {\n                std::lock_guard<std::mutex> guard(subscribers_lock_);\n                std::weak_ptr<struct mg_connection> week_con(it->second);\n                subscribers_.erase(week_con);\n                send_response(nc, EV_UNSUBSCRIBED, channel);\n            }\n            else\n            {\n                send_bad_response(nc, \"no subscription.\");\n            }\n        }\n\n        else if (channel == CH_BLOCK || channel == CH_HEIGHT)\n        {\n            if (event == EV_SUBSCRIBE)\n            {\n                auto it = map_connections_.find(&nc);\n                if (it != map_connections_.end())\n                {\n                    std::lock_guard<std::mutex> guard(block_subscribers_lock_);\n                    std::weak_ptr<struct mg_connection> week_con(it->second);\n\n                    auto iter = block_subscribers_.find(week_con);\n                    if (iter != block_subscribers_.end())\n                    {\n                        auto &sub_list = iter->second;\n                        if (sub_list.end() == std::find(sub_list.begin(), sub_list.end(), channel))\n                        {\n                            sub_list.push_back(channel);\n                        }\n\n                        send_response(nc, EV_SUBSCRIBED, channel);\n                    }\n                    else\n                    {\n                        string_vector sub_list;\n                        sub_list.push_back(channel);\n\n                        block_subscribers_.insert({week_con, sub_list});\n                        send_response(nc, EV_SUBSCRIBED, channel);\n                    }\n                }\n                else\n                {\n                    send_bad_response(nc, \"connection lost.\");\n                }\n            }\n            else if (event == EV_UNSUBSCRIBE)\n            {\n                auto it = map_connections_.find(&nc);\n                if (it != map_connections_.end())\n                {\n                    std::lock_guard<std::mutex> guard(block_subscribers_lock_);\n                    std::weak_ptr<struct mg_connection> week_con(it->second);\n\n                    auto iter = block_subscribers_.find(week_con);\n                    if (iter != block_subscribers_.end())\n                    {\n                        auto &params = iter->second;\n                        auto chit = std::find(params.begin(), params.end(), channel);\n                        if (chit != params.end())\n                        {\n                            params.erase(chit);\n                        }\n\n                        if (params.empty())\n                        {\n                            subscribers_.erase(week_con);\n                        }\n                    }\n\n                    send_response(nc, EV_UNSUBSCRIBED, channel);\n                }\n                else\n                {\n                    send_bad_response(nc, \"no subscription.\");\n                }\n            }\n            else\n            {\n                send_bad_response(nc, \"request not support.\");\n            }\n        }\n\n        else if (event == EV_VERSION)\n        {\n            Json::Value version;\n            version[\"wallet\"] = UC_VERSION;\n            version[\"protocol\"] = node_.network_settings().protocol;\n            send_response(nc, event, \"\", version);\n        }\n\n        else if (event == EV_PING)\n        {\n            Json::Value pong = \"pong\";\n            send_response(nc, event, \"\", pong);\n        }\n        else\n        {\n            send_bad_response(nc, \"request not support.\");\n        }\n    }\n    catch (std::exception &e)\n    {\n        auto error = std::string(e.what());\n        log::info(NAME) << \"on on_ws_frame_handler: \" << error;\n        send_bad_response(nc, error.c_str());\n    }\n}\n\nvoid WsPushServ::on_close_handler(struct mg_connection &nc)\n{\n    if (is_websocket(nc))\n    {\n        map_connections_.erase(&nc);\n    }\n}\n\nvoid WsPushServ::on_broadcast(struct mg_connection &nc, const char *ev_data)\n{\n    if (is_listen_socket(nc) || is_notify_socket(nc))\n        return;\n\n    send_frame(nc, ev_data, strlen(ev_data));\n}\n\nvoid WsPushServ::on_send_handler(struct mg_connection &nc, int bytes_transfered)\n{\n}\n\nvoid WsPushServ::on_notify_handler(struct mg_connection &nc, struct mg_event &ev)\n{\n    static uint64_t api_call_counter = 0;\n\n    if (ev.data == nullptr)\n        return;\n\n    auto &msg = *(WsEvent *)ev.data;\n    msg(++api_call_counter);\n}\n\n} // namespace mgbubble\n"
  },
  {
    "path": "src/UChainService/api/restful/exception/Error.cpp",
    "content": "/*\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS) - UChain.\n *\n * This program is free software; you can redistribute it and/or modify it under the terms of the\n * GNU General Public License as published by the Free Software Foundation; either version 2 of the\n * License, or (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License along with this program; if\n * not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\n * 02110-1301, USA.\n */\n#include <UChainService/api/restful/exception/Error.hpp>\n\nnamespace mgbubble\n{\n\n} // namespace mgbubble\n"
  },
  {
    "path": "src/UChainService/api/restful/exception/Exception.cpp",
    "content": "/*\r\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS).\r\n * Copyright (C) 2013-2018 Swirly Cloud Limited.\r\n *\r\n * This program is free software; you can redistribute it and/or modify it under the terms of the\r\n * GNU General Public License as published by the Free Software Foundation; either version 2 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\r\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r\n * General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU General Public License along with this program; if\r\n * not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\r\n * 02110-1301, USA.\r\n */\r\n#include <UChainService/api/restful/exception/Exception.hpp>\r\n\r\nusing namespace std;\r\n\r\nnamespace mgbubble\r\n{\r\n\r\nnamespace\r\n{\r\nthread_local ErrMsg errMsg_;\r\n} // namespace\r\n\r\nException::Exception(string_view what) noexcept\r\n{\r\n  const auto len = min(ErrMsgMax, what.size());\r\n  if (len > 0)\r\n  {\r\n    memcpy(what_, what.data(), len);\r\n  }\r\n  what_[len] = '\\0';\r\n}\r\n\r\nException::~Exception() noexcept = default;\r\n\r\nconst char *Exception::what() const noexcept\r\n{\r\n  return what_;\r\n}\r\n\r\nErrMsg &errMsg() noexcept\r\n{\r\n  errMsg_.reset();\r\n  return errMsg_;\r\n}\r\n\r\n} // namespace mgbubble\r\n"
  },
  {
    "path": "src/UChainService/api/restful/exception/Instances.cpp",
    "content": "/*\r\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS).\r\n * Copyright (C) 2013-2018 Swirly Cloud Limited.\r\n *\r\n * This program is free software; you can redistribute it and/or modify it under the terms of the\r\n * GNU General Public License as published by the Free Software Foundation; either version 2 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\r\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r\n * General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU General Public License along with this program; if\r\n * not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\r\n * 02110-1301, USA.\r\n */\r\n#include <UChainService/api/restful/exception/Instances.hpp>\r\n\r\n#include <iostream>\r\n\r\nusing namespace std;\r\n\r\nnamespace mgbubble\r\n{\r\n\r\nServException::~ServException() noexcept = default;\r\n\r\nvoid ServException::toJson(int status, const char *reason, const char *detail, ostream &os)\r\n{\r\n  os << \"{\\\"status\\\":\" << status     //\r\n     << \",\\\"reason\\\":\\\"\" << reason   //\r\n     << \"\\\",\\\"detail\\\":\\\"\" << detail //\r\n     << \"\\\"}\";\r\n}\r\n\r\nBadRequestException::~BadRequestException() noexcept = default;\r\n\r\nint BadRequestException::httpStatus() const noexcept\r\n{\r\n  return 400;\r\n}\r\n\r\nconst char *BadRequestException::httpReason() const noexcept\r\n{\r\n  return \"Bad Request\";\r\n}\r\n\r\nAlreadyExistsException::~AlreadyExistsException() noexcept = default;\r\n\r\nRefAlreadyExistsException::~RefAlreadyExistsException() noexcept = default;\r\n\r\nInvalidException::~InvalidException() noexcept = default;\r\n\r\nForbiddenException::~ForbiddenException() noexcept = default;\r\n\r\nint ForbiddenException::httpStatus() const noexcept\r\n{\r\n  return 403;\r\n}\r\n\r\nconst char *ForbiddenException::httpReason() const noexcept\r\n{\r\n  return \"Forbidden\";\r\n}\r\n\r\nInternalException::~InternalException() noexcept = default;\r\n\r\nint InternalException::httpStatus() const noexcept\r\n{\r\n  return 500;\r\n}\r\n\r\nconst char *InternalException::httpReason() const noexcept\r\n{\r\n  return \"Internal Server Error\";\r\n}\r\n\r\nMethodNotAllowedException::~MethodNotAllowedException() noexcept = default;\r\n\r\nint MethodNotAllowedException::httpStatus() const noexcept\r\n{\r\n  return 405;\r\n}\r\n\r\nconst char *MethodNotAllowedException::httpReason() const noexcept\r\n{\r\n  return \"Method Not Allowed\";\r\n}\r\n\r\nNotFoundException::~NotFoundException() noexcept = default;\r\n\r\nint NotFoundException::httpStatus() const noexcept\r\n{\r\n  return 404;\r\n}\r\n\r\nconst char *NotFoundException::httpReason() const noexcept\r\n{\r\n  return \"Not Found\";\r\n}\r\n\r\nServiceUnavailableException::~ServiceUnavailableException() noexcept = default;\r\n\r\nint ServiceUnavailableException::httpStatus() const noexcept\r\n{\r\n  return 503;\r\n}\r\n\r\nconst char *ServiceUnavailableException::httpReason() const noexcept\r\n{\r\n  return \"Service Unavailable\";\r\n}\r\n\r\nUnauthorizedException::~UnauthorizedException() noexcept = default;\r\n\r\nint UnauthorizedException::httpStatus() const noexcept\r\n{\r\n  return 401;\r\n}\r\n\r\nconst char *UnauthorizedException::httpReason() const noexcept\r\n{\r\n  return \"Unauthorized\";\r\n}\r\n\r\n} // namespace mgbubble\r\n"
  },
  {
    "path": "src/UChainService/api/restful/utility/Stream.cpp",
    "content": "/*\r\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS).\r\n * Copyright (C) 2013-2018 Swirly Cloud Limited.\r\n *\r\n * This program is free software; you can redistribute it and/or modify it under the terms of the\r\n * GNU General Public License as published by the Free Software Foundation; either version 2 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\r\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r\n * General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU General Public License along with this program; if\r\n * not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\r\n * 02110-1301, USA.\r\n */\r\n\r\n#include <UChainService/api/restful/utility/Stream.hpp>\r\n\r\nusing namespace std;\r\n\r\nnamespace mgbubble\r\n{\r\n\r\nUC_API void reset(ostream &os) noexcept\r\n{\r\n  os.clear();\r\n  os.fill(os.widen(' '));\r\n  os.flags(ios_base::skipws | ios_base::dec);\r\n  os.precision(6);\r\n  os.width(0);\r\n};\r\n\r\nOStreamJoiner::~OStreamJoiner() noexcept = default;\r\n\r\n} // namespace mgbubble\r\n"
  },
  {
    "path": "src/UChainService/api/restful/utility/Stream_buf.cpp",
    "content": "/*\r\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS).\r\n * Copyright (C) 2013-2018 Swirly Cloud Limited.\r\n *\r\n * This program is free software; you can redistribute it and/or modify it under the terms of the\r\n * GNU General Public License as published by the Free Software Foundation; either version 2 of the\r\n * License, or (at your option) any later version.\r\n *\r\n * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without\r\n * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r\n * General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU General Public License along with this program; if\r\n * not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA\r\n * 02110-1301, USA.\r\n */\r\n\r\n#include <UChainService/api/restful/utility/Stream.hpp>\r\n#include <UChainService/api/restful/utility/Stream_buf.hpp>\r\n#include <UChainService/api/restful/utility/String.hpp>\r\n\r\nusing namespace std;\r\n\r\nnamespace mgbubble\r\n{\r\n\r\nStreamBuf::StreamBuf(mbuf &buf) : buf_(buf)\r\n{\r\n  if (!buf_.buf)\r\n  {\r\n    // Pre-allocate buffer.\r\n    mbuf_init(&buf_, 4096);\r\n    if (!buf_.buf)\r\n    {\r\n      throw bad_alloc();\r\n    }\r\n  }\r\n}\r\n\r\nStreamBuf::~StreamBuf() noexcept = default;\r\n\r\nvoid StreamBuf::reset() noexcept\r\n{\r\n  buf_.len = 0;\r\n}\r\n\r\nvoid StreamBuf::setContentLength(size_t pos, size_t len) noexcept\r\n{\r\n  char *ptr{buf_.buf + pos};\r\n  do\r\n  {\r\n    --ptr;\r\n    *ptr = '0' + len % 10;\r\n    len /= 10;\r\n  } while (len > 0);\r\n}\r\n\r\nStreamBuf::int_type StreamBuf::overflow(int_type c) noexcept\r\n{\r\n  if (c != traits_type::eof())\r\n  {\r\n    const char z = c;\r\n    if (mbuf_append(&buf_, &z, 1) != 1)\r\n    {\r\n      c = traits_type::eof();\r\n    }\r\n  }\r\n  return c;\r\n}\r\n\r\nstreamsize StreamBuf::xsputn(const char_type *s, streamsize count) noexcept\r\n{\r\n  return mbuf_append(&buf_, s, count);\r\n}\r\n\r\nOStream::OStream() : ostream{nullptr}\r\n{\r\n}\r\n\r\nOStream::~OStream() noexcept = default;\r\n\r\nvoid OStream::reset(int status, const char *reason, const char *content_type, const char *charset) noexcept\r\n{\r\n  rdbuf()->reset();\r\n  mgbubble::reset(*this);\r\n\r\n  // Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF. Use 10 space place-holder for\r\n  // content length. RFC2616 states that field value MAY be preceded by any amount of LWS, though a\r\n  // single SP is preferred.\r\n  *this << \"HTTP/1.1 \" << status << ' ' << reason << \"\\r\\nContent-Type: \" << content_type << \";charset=\" << charset << \"\\r\\nContent-Length:           \\r\\n\\r\\n\";\r\n  headSize_ = size();\r\n  lengthAt_ = headSize_ - 4;\r\n}\r\n\r\nvoid OStream::setContentLength() noexcept\r\n{\r\n  rdbuf()->setContentLength(lengthAt_, size() - headSize_);\r\n}\r\n\r\n} // namespace mgbubble\r\n"
  },
  {
    "path": "src/UChainService/consensus/CMakeLists.txt",
    "content": "INCLUDE_DIRECTORIES(\"${PROJECT_SOURCE_DIR}/src/UChainService/consensus/clone\")\nINCLUDE_DIRECTORIES(\"${PROJECT_SOURCE_DIR}/src/UChainService/consensus/common\")\n\nFILE(GLOB_RECURSE consensus_SOURCES \"*.cpp\")\n\nif(NOT MINGW AND NOT MSYS)\n    INCLUDE(CheckIncludeFile)\n    CHECK_INCLUDE_FILE(byteswap.h HAVE_BYTESWAP_H)\n    CHECK_INCLUDE_FILE(endian.h HAVE_ENDIAN_H)\n\n    if(HAVE_ENDIAN_H AND HAVE_BYTESWAP_H)\n        # endian.h byteswap.h are provided; =1 means no need to complie by myself\n        ADD_DEFINITIONS(-DHAVE_ENDIAN_H -DHAVE_BYTESWAP_H\n        -DHAVE_DECL_BSWAP_16=1 -DHAVE_DECL_BSWAP_32=1 -DHAVE_DECL_BSWAP_64=1\n        -DHAVE_DECL_LE16TOH=1  -DHAVE_DECL_LE32TOH=1 -DHAVE_DECL_LE64TOH=1  \n        -DHAVE_DECL_HTOLE16=1 -DHAVE_DECL_HTOLE32=1 -DHAVE_DECL_HTOLE64=1 \n        -DHAVE_DECL_BE16TOH=1  -DHAVE_DECL_BE32TOH=1 -DHAVE_DECL_BE64TOH=1  \n        -DHAVE_DECL_HTOBE16=1 -DHAVE_DECL_HTOBE32=1 -DHAVE_DECL_HTOBE64=1)\n    ELSE()\n        # no endian.h , no byteswap.h\n        ADD_DEFINITIONS(\n        -DHAVE_DECL_BSWAP_16=0 -DHAVE_DECL_BSWAP_32=0 -DHAVE_DECL_BSWAP_64=0\n        -DHAVE_DECL_LE16TOH=0  -DHAVE_DECL_LE32TOH=0 -DHAVE_DECL_LE64TOH=0  \n        -DHAVE_DECL_HTOLE16=0 -DHAVE_DECL_HTOLE32=0 -DHAVE_DECL_HTOLE64=0 \n        -DHAVE_DECL_BE16TOH=0  -DHAVE_DECL_BE32TOH=0 -DHAVE_DECL_BE64TOH=0  \n        -DHAVE_DECL_HTOBE16=0 -DHAVE_DECL_HTOBE32=0 -DHAVE_DECL_HTOBE64=0)\n    ENDIF()\nENDIF()    \n\nSET(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} -fno-strict-aliasing \")\nSET(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -fno-strict-aliasing -fpermissive\")\n\nADD_DEFINITIONS(-DBCK_STATIC=1)\nADD_LIBRARY(consensus_static STATIC ${consensus_SOURCES})\nSET_TARGET_PROPERTIES(consensus_static PROPERTIES OUTPUT_NAME uc_consensus)\nTARGET_LINK_LIBRARIES(consensus_static ${Boost_LIBRARIES} )\n#IF(MINGW OR MSYS)\n#\tTARGET_LINK_LIBRARIES(consensus_static wsock32 ws2_32)\n#ENDIF()\nINSTALL(TARGETS consensus_static DESTINATION lib)\n\nIF(ENABLE_SHARED_LIBS)\n    ADD_DEFINITIONS(-DBCK_DLL=1)\n  ADD_LIBRARY(consensus_shared SHARED ${consensus_SOURCES})\n  SET_TARGET_PROPERTIES(consensus_shared PROPERTIES OUTPUT_NAME uc_consensus)\n  TARGET_LINK_LIBRARIES(consensus_shared ${Boost_LIBRARIES})\n  INSTALL(TARGETS consensus_shared DESTINATION lib)\nENDIF()\n"
  },
  {
    "path": "src/UChainService/consensus/clone/amount.h",
    "content": "// Copyright (c) 2009-2010 Satoshi Nakamoto\n// Copyright (c) 2009-2015 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#ifndef BITCOIN_AMOUNT_H\n#define BITCOIN_AMOUNT_H\n\n#include \"serialize.h\"\n\n#include <stdlib.h>\n#include <string>\n\ntypedef int64_t CAmount;\n\nstatic const CAmount COIN = 100000000;\nstatic const CAmount CENT = 1000000;\n\nextern const std::string CURRENCY_UNIT;\n\n/** No amount larger than this (in satoshi) is valid.\n *\n * Note that this constant is *not* the total money supply, which in Bitcoin\n * currently happens to be less than 21,000,000 BTC for various reasons, but\n * rather a sanity check. As this sanity check is used by consensus-critical\n * validation code, the exact value of the MAX_MONEY constant is consensus\n * critical; in unusual circumstances like a(nother) overflow bug that allowed\n * for the creation of coins out of thin air modification could lead to a fork.\n * */\nstatic const CAmount MAX_MONEY = 21000000 * COIN;\ninline bool MoneyRange(const CAmount &nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); }\n\n/** Type-safe wrapper class for fee rates\n * (how much to pay based on transaction size)\n */\nclass CFeeRate\n{\n  private:\n    CAmount nSatoshisPerK; // unit is satoshis-per-1,000-bytes\n  public:\n    CFeeRate() : nSatoshisPerK(0) {}\n    explicit CFeeRate(const CAmount &_nSatoshisPerK) : nSatoshisPerK(_nSatoshisPerK) {}\n    CFeeRate(const CAmount &nFeePaid, size_t nSize);\n    CFeeRate(const CFeeRate &other) { nSatoshisPerK = other.nSatoshisPerK; }\n\n    CAmount GetFee(size_t size) const;                  // unit returned is satoshis\n    CAmount GetFeePerK() const { return GetFee(1000); } // satoshis-per-1000-bytes\n\n    friend bool operator<(const CFeeRate &a, const CFeeRate &b) { return a.nSatoshisPerK < b.nSatoshisPerK; }\n    friend bool operator>(const CFeeRate &a, const CFeeRate &b) { return a.nSatoshisPerK > b.nSatoshisPerK; }\n    friend bool operator==(const CFeeRate &a, const CFeeRate &b) { return a.nSatoshisPerK == b.nSatoshisPerK; }\n    friend bool operator<=(const CFeeRate &a, const CFeeRate &b) { return a.nSatoshisPerK <= b.nSatoshisPerK; }\n    friend bool operator>=(const CFeeRate &a, const CFeeRate &b) { return a.nSatoshisPerK >= b.nSatoshisPerK; }\n    CFeeRate &operator+=(const CFeeRate &a)\n    {\n        nSatoshisPerK += a.nSatoshisPerK;\n        return *this;\n    }\n    std::string ToString() const;\n\n    ADD_SERIALIZE_METHODS;\n\n    template <typename Stream, typename Operation>\n    inline void SerializationOp(Stream &s, Operation ser_action, int nType, int nVersion)\n    {\n        READWRITE(nSatoshisPerK);\n    }\n};\n\n#endif //  BITCOIN_AMOUNT_H\n"
  },
  {
    "path": "src/UChainService/consensus/clone/compat/byteswap.h",
    "content": "// Copyright (c) 2014 The Bitcoin developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#ifndef BITCOIN_COMPAT_BYTESWAP_H\n#define BITCOIN_COMPAT_BYTESWAP_H\n\n#if defined(HAVE_CONFIG_H)\n#include \"config/bitcoin-config.h\"\n#endif\n\n#include <stdint.h>\n\n#if defined(HAVE_BYTESWAP_H)\n#include <byteswap.h>\n#endif\n\n#if HAVE_DECL_BSWAP_16 == 0\ninline uint16_t bswap_16(uint16_t x)\n{\n    return (x >> 8) | ((x & 0x00ff) << 8);\n}\n#endif // HAVE_DECL_BSWAP16\n\n#if HAVE_DECL_BSWAP_32 == 0\ninline uint32_t bswap_32(uint32_t x)\n{\n    return (((x & 0xff000000U) >> 24) | ((x & 0x00ff0000U) >> 8) |\n            ((x & 0x0000ff00U) << 8) | ((x & 0x000000ffU) << 24));\n}\n#endif // HAVE_DECL_BSWAP32\n\n#if HAVE_DECL_BSWAP_64 == 0\ninline uint64_t bswap_64(uint64_t x)\n{\n    return (((x & 0xff00000000000000ull) >> 56) | ((x & 0x00ff000000000000ull) >> 40) | ((x & 0x0000ff0000000000ull) >> 24) | ((x & 0x000000ff00000000ull) >> 8) | ((x & 0x00000000ff000000ull) << 8) | ((x & 0x0000000000ff0000ull) << 24) | ((x & 0x000000000000ff00ull) << 40) | ((x & 0x00000000000000ffull) << 56));\n}\n#endif // HAVE_DECL_BSWAP64\n\n#endif // BITCOIN_COMPAT_BYTESWAP_H\n"
  },
  {
    "path": "src/UChainService/consensus/clone/compat/endian.h",
    "content": "// Copyright (c) 2014-2018 The Bitcoin developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#ifndef BITCOIN_COMPAT_ENDIAN_H\n#define BITCOIN_COMPAT_ENDIAN_H\n\n#if defined(HAVE_CONFIG_H)\n#include \"config/bitcoin-config.h\"\n#endif\n\n#include <stdint.h>\n\n#include \"compat/byteswap.h\"\n\n#if defined(HAVE_ENDIAN_H)\n#include <endian.h>\n#elif defined(HAVE_SYS_ENDIAN_H)\n#include <sys/endian.h>\n#elif defined(HAVE_OSX_ENDIAN_H)\n#include <machine/endian.h>\n#endif\n\n#if defined(WORDS_BIGENDIAN)\n\n#if HAVE_DECL_HTOBE16 == 0\ninline uint16_t htobe16(uint16_t host_16bits)\n{\n    return host_16bits;\n}\n#endif // HAVE_DECL_HTOBE16\n\n#if HAVE_DECL_HTOLE16 == 0\ninline uint16_t htole16(uint16_t host_16bits)\n{\n    return bswap_16(host_16bits);\n}\n#endif // HAVE_DECL_HTOLE16\n\n#if HAVE_DECL_BE16TOH == 0\ninline uint16_t be16toh(uint16_t big_endian_16bits)\n{\n    return big_endian_16bits;\n}\n#endif // HAVE_DECL_BE16TOH\n\n#if HAVE_DECL_LE16TOH == 0\ninline uint16_t le16toh(uint16_t little_endian_16bits)\n{\n    return bswap_16(little_endian_16bits);\n}\n#endif // HAVE_DECL_LE16TOH\n\n#if HAVE_DECL_HTOBE32 == 0\ninline uint32_t htobe32(uint32_t host_32bits)\n{\n    return host_32bits;\n}\n#endif // HAVE_DECL_HTOBE32\n\n#if HAVE_DECL_HTOLE32 == 0\ninline uint32_t htole32(uint32_t host_32bits)\n{\n    return bswap_32(host_32bits);\n}\n#endif // HAVE_DECL_HTOLE32\n\n#if HAVE_DECL_BE32TOH == 0\ninline uint32_t be32toh(uint32_t big_endian_32bits)\n{\n    return big_endian_32bits;\n}\n#endif // HAVE_DECL_BE32TOH\n\n#if HAVE_DECL_LE32TOH == 0\ninline uint32_t le32toh(uint32_t little_endian_32bits)\n{\n    return bswap_32(little_endian_32bits);\n}\n#endif // HAVE_DECL_LE32TOH\n\n#if HAVE_DECL_HTOBE64 == 0\ninline uint64_t htobe64(uint64_t host_64bits)\n{\n    return host_64bits;\n}\n#endif // HAVE_DECL_HTOBE64\n\n#if HAVE_DECL_HTOLE64 == 0\ninline uint64_t htole64(uint64_t host_64bits)\n{\n    return bswap_64(host_64bits);\n}\n#endif // HAVE_DECL_HTOLE64\n\n#if HAVE_DECL_BE64TOH == 0\ninline uint64_t be64toh(uint64_t big_endian_64bits)\n{\n    return big_endian_64bits;\n}\n#endif // HAVE_DECL_BE64TOH\n\n#if HAVE_DECL_LE64TOH == 0\ninline uint64_t le64toh(uint64_t little_endian_64bits)\n{\n    return bswap_64(little_endian_64bits);\n}\n#endif // HAVE_DECL_LE64TOH\n\n#else // WORDS_BIGENDIAN\n\n#if HAVE_DECL_HTOBE16 == 0\ninline uint16_t htobe16(uint16_t host_16bits)\n{\n    return bswap_16(host_16bits);\n}\n#endif // HAVE_DECL_HTOBE16\n\n#if HAVE_DECL_HTOLE16 == 0\ninline uint16_t htole16(uint16_t host_16bits)\n{\n    return host_16bits;\n}\n#endif // HAVE_DECL_HTOLE16\n\n#if HAVE_DECL_BE16TOH == 0\ninline uint16_t be16toh(uint16_t big_endian_16bits)\n{\n    return bswap_16(big_endian_16bits);\n}\n#endif // HAVE_DECL_BE16TOH\n\n#if HAVE_DECL_LE16TOH == 0\ninline uint16_t le16toh(uint16_t little_endian_16bits)\n{\n    return little_endian_16bits;\n}\n#endif // HAVE_DECL_LE16TOH\n\n#if HAVE_DECL_HTOBE32 == 0\ninline uint32_t htobe32(uint32_t host_32bits)\n{\n    return bswap_32(host_32bits);\n}\n#endif // HAVE_DECL_HTOBE32\n\n#if HAVE_DECL_HTOLE32 == 0\ninline uint32_t htole32(uint32_t host_32bits)\n{\n    return host_32bits;\n}\n#endif // HAVE_DECL_HTOLE32\n\n#if HAVE_DECL_BE32TOH == 0\ninline uint32_t be32toh(uint32_t big_endian_32bits)\n{\n    return bswap_32(big_endian_32bits);\n}\n#endif // HAVE_DECL_BE32TOH\n\n#if HAVE_DECL_LE32TOH == 0\ninline uint32_t le32toh(uint32_t little_endian_32bits)\n{\n    return little_endian_32bits;\n}\n#endif // HAVE_DECL_LE32TOH\n\n#if HAVE_DECL_HTOBE64 == 0\ninline uint64_t htobe64(uint64_t host_64bits)\n{\n    return bswap_64(host_64bits);\n}\n#endif // HAVE_DECL_HTOBE64\n\n#if HAVE_DECL_HTOLE64 == 0\ninline uint64_t htole64(uint64_t host_64bits)\n{\n    return host_64bits;\n}\n#endif // HAVE_DECL_HTOLE64\n\n#if HAVE_DECL_BE64TOH == 0\ninline uint64_t be64toh(uint64_t big_endian_64bits)\n{\n    return bswap_64(big_endian_64bits);\n}\n#endif // HAVE_DECL_BE64TOH\n\n#if HAVE_DECL_LE64TOH == 0\ninline uint64_t le64toh(uint64_t little_endian_64bits)\n{\n    return little_endian_64bits;\n}\n#endif // HAVE_DECL_LE64TOH\n\n#endif // WORDS_BIGENDIAN\n\n#endif // BITCOIN_COMPAT_ENDIAN_H\n"
  },
  {
    "path": "src/UChainService/consensus/clone/crypto/common.h",
    "content": "// Copyright (c) 2014 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#ifndef BITCOIN_CRYPTO_COMMON_H\n#define BITCOIN_CRYPTO_COMMON_H\n\n#if defined(HAVE_CONFIG_H)\n#include \"bitcoin-config.h\"\n#endif\n\n#include <stdint.h>\n\n#include \"compat/endian.h\"\n\nuint16_t static inline ReadLE16(const unsigned char *ptr)\n{\n    return le16toh(*((uint16_t *)ptr));\n}\n\nuint32_t static inline ReadLE32(const unsigned char *ptr)\n{\n    return le32toh(*((uint32_t *)ptr));\n}\n\nuint64_t static inline ReadLE64(const unsigned char *ptr)\n{\n    return le64toh(*((uint64_t *)ptr));\n}\n\nvoid static inline WriteLE16(unsigned char *ptr, uint16_t x)\n{\n    *((uint16_t *)ptr) = htole16(x);\n}\n\nvoid static inline WriteLE32(unsigned char *ptr, uint32_t x)\n{\n    *((uint32_t *)ptr) = htole32(x);\n}\n\nvoid static inline WriteLE64(unsigned char *ptr, uint64_t x)\n{\n    *((uint64_t *)ptr) = htole64(x);\n}\n\nuint32_t static inline ReadBE32(const unsigned char *ptr)\n{\n    return be32toh(*((uint32_t *)ptr));\n}\n\nuint64_t static inline ReadBE64(const unsigned char *ptr)\n{\n    return be64toh(*((uint64_t *)ptr));\n}\n\nvoid static inline WriteBE32(unsigned char *ptr, uint32_t x)\n{\n    *((uint32_t *)ptr) = htobe32(x);\n}\n\nvoid static inline WriteBE64(unsigned char *ptr, uint64_t x)\n{\n    *((uint64_t *)ptr) = htobe64(x);\n}\n\n#endif // BITCOIN_CRYPTO_COMMON_H\n"
  },
  {
    "path": "src/UChainService/consensus/clone/crypto/hmac_sha512.cpp",
    "content": "// Copyright (c) 2014 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#include \"crypto/hmac_sha512.h\"\n\n#include <string.h>\n\nCHMAC_SHA512::CHMAC_SHA512(const unsigned char *key, size_t keylen)\n{\n    unsigned char rkey[128];\n    if (keylen <= 128)\n    {\n        memcpy(rkey, key, keylen);\n        memset(rkey + keylen, 0, 128 - keylen);\n    }\n    else\n    {\n        CSHA512().Write(key, keylen).Finalize(rkey);\n        memset(rkey + 64, 0, 64);\n    }\n\n    for (int n = 0; n < 128; n++)\n        rkey[n] ^= 0x5c;\n    outer.Write(rkey, 128);\n\n    for (int n = 0; n < 128; n++)\n        rkey[n] ^= 0x5c ^ 0x36;\n    inner.Write(rkey, 128);\n}\n\nvoid CHMAC_SHA512::Finalize(unsigned char hash[OUTPUT_SIZE])\n{\n    unsigned char temp[64];\n    inner.Finalize(temp);\n    outer.Write(temp, 64).Finalize(hash);\n}\n"
  },
  {
    "path": "src/UChainService/consensus/clone/crypto/hmac_sha512.h",
    "content": "// Copyright (c) 2014 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#ifndef BITCOIN_CRYPTO_HMAC_SHA512_H\n#define BITCOIN_CRYPTO_HMAC_SHA512_H\n\n#include \"crypto/sha512.h\"\n\n#include <stdint.h>\n#include <stdlib.h>\n\n/** A hasher class for HMAC-SHA-512. */\nclass CHMAC_SHA512\n{\n  private:\n    CSHA512 outer;\n    CSHA512 inner;\n\n  public:\n    static const size_t OUTPUT_SIZE = 64;\n\n    CHMAC_SHA512(const unsigned char *key, size_t keylen);\n    CHMAC_SHA512 &Write(const unsigned char *data, size_t len)\n    {\n        inner.Write(data, len);\n        return *this;\n    }\n    void Finalize(unsigned char hash[OUTPUT_SIZE]);\n};\n\n#endif // BITCOIN_CRYPTO_HMAC_SHA512_H\n"
  },
  {
    "path": "src/UChainService/consensus/clone/crypto/ripemd160.cpp",
    "content": "// Copyright (c) 2014 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#include \"crypto/ripemd160.h\"\n\n#include \"crypto/common.h\"\n\n#include <string.h>\n\n// Internal implementation code.\nnamespace\n{\n/// Internal RIPEMD-160 implementation.\nnamespace ripemd160\n{\nuint32_t inline f1(uint32_t x, uint32_t y, uint32_t z) { return x ^ y ^ z; }\nuint32_t inline f2(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (~x & z); }\nuint32_t inline f3(uint32_t x, uint32_t y, uint32_t z) { return (x | ~y) ^ z; }\nuint32_t inline f4(uint32_t x, uint32_t y, uint32_t z) { return (x & z) | (y & ~z); }\nuint32_t inline f5(uint32_t x, uint32_t y, uint32_t z) { return x ^ (y | ~z); }\n\n/** Initialize RIPEMD-160 state. */\nvoid inline Initialize(uint32_t *s)\n{\n    s[0] = 0x67452301ul;\n    s[1] = 0xEFCDAB89ul;\n    s[2] = 0x98BADCFEul;\n    s[3] = 0x10325476ul;\n    s[4] = 0xC3D2E1F0ul;\n}\n\nuint32_t inline rol(uint32_t x, int i) { return (x << i) | (x >> (32 - i)); }\n\nvoid inline Round(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t f, uint32_t x, uint32_t k, int r)\n{\n    a = rol(a + f + x + k, r) + e;\n    c = rol(c, 10);\n}\n\nvoid inline R11(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f1(b, c, d), x, 0, r); }\nvoid inline R21(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f2(b, c, d), x, 0x5A827999ul, r); }\nvoid inline R31(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f3(b, c, d), x, 0x6ED9EBA1ul, r); }\nvoid inline R41(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f4(b, c, d), x, 0x8F1BBCDCul, r); }\nvoid inline R51(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f5(b, c, d), x, 0xA953FD4Eul, r); }\n\nvoid inline R12(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f5(b, c, d), x, 0x50A28BE6ul, r); }\nvoid inline R22(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f4(b, c, d), x, 0x5C4DD124ul, r); }\nvoid inline R32(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f3(b, c, d), x, 0x6D703EF3ul, r); }\nvoid inline R42(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f2(b, c, d), x, 0x7A6D76E9ul, r); }\nvoid inline R52(uint32_t &a, uint32_t b, uint32_t &c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f1(b, c, d), x, 0, r); }\n\n/** Perform a RIPEMD-160 transformation, processing a 64-byte chunk. */\nvoid Transform(uint32_t *s, const unsigned char *chunk)\n{\n    uint32_t a1 = s[0], b1 = s[1], c1 = s[2], d1 = s[3], e1 = s[4];\n    uint32_t a2 = a1, b2 = b1, c2 = c1, d2 = d1, e2 = e1;\n    uint32_t w0 = ReadLE32(chunk + 0), w1 = ReadLE32(chunk + 4), w2 = ReadLE32(chunk + 8), w3 = ReadLE32(chunk + 12);\n    uint32_t w4 = ReadLE32(chunk + 16), w5 = ReadLE32(chunk + 20), w6 = ReadLE32(chunk + 24), w7 = ReadLE32(chunk + 28);\n    uint32_t w8 = ReadLE32(chunk + 32), w9 = ReadLE32(chunk + 36), w10 = ReadLE32(chunk + 40), w11 = ReadLE32(chunk + 44);\n    uint32_t w12 = ReadLE32(chunk + 48), w13 = ReadLE32(chunk + 52), w14 = ReadLE32(chunk + 56), w15 = ReadLE32(chunk + 60);\n\n    R11(a1, b1, c1, d1, e1, w0, 11);\n    R12(a2, b2, c2, d2, e2, w5, 8);\n    R11(e1, a1, b1, c1, d1, w1, 14);\n    R12(e2, a2, b2, c2, d2, w14, 9);\n    R11(d1, e1, a1, b1, c1, w2, 15);\n    R12(d2, e2, a2, b2, c2, w7, 9);\n    R11(c1, d1, e1, a1, b1, w3, 12);\n    R12(c2, d2, e2, a2, b2, w0, 11);\n    R11(b1, c1, d1, e1, a1, w4, 5);\n    R12(b2, c2, d2, e2, a2, w9, 13);\n    R11(a1, b1, c1, d1, e1, w5, 8);\n    R12(a2, b2, c2, d2, e2, w2, 15);\n    R11(e1, a1, b1, c1, d1, w6, 7);\n    R12(e2, a2, b2, c2, d2, w11, 15);\n    R11(d1, e1, a1, b1, c1, w7, 9);\n    R12(d2, e2, a2, b2, c2, w4, 5);\n    R11(c1, d1, e1, a1, b1, w8, 11);\n    R12(c2, d2, e2, a2, b2, w13, 7);\n    R11(b1, c1, d1, e1, a1, w9, 13);\n    R12(b2, c2, d2, e2, a2, w6, 7);\n    R11(a1, b1, c1, d1, e1, w10, 14);\n    R12(a2, b2, c2, d2, e2, w15, 8);\n    R11(e1, a1, b1, c1, d1, w11, 15);\n    R12(e2, a2, b2, c2, d2, w8, 11);\n    R11(d1, e1, a1, b1, c1, w12, 6);\n    R12(d2, e2, a2, b2, c2, w1, 14);\n    R11(c1, d1, e1, a1, b1, w13, 7);\n    R12(c2, d2, e2, a2, b2, w10, 14);\n    R11(b1, c1, d1, e1, a1, w14, 9);\n    R12(b2, c2, d2, e2, a2, w3, 12);\n    R11(a1, b1, c1, d1, e1, w15, 8);\n    R12(a2, b2, c2, d2, e2, w12, 6);\n\n    R21(e1, a1, b1, c1, d1, w7, 7);\n    R22(e2, a2, b2, c2, d2, w6, 9);\n    R21(d1, e1, a1, b1, c1, w4, 6);\n    R22(d2, e2, a2, b2, c2, w11, 13);\n    R21(c1, d1, e1, a1, b1, w13, 8);\n    R22(c2, d2, e2, a2, b2, w3, 15);\n    R21(b1, c1, d1, e1, a1, w1, 13);\n    R22(b2, c2, d2, e2, a2, w7, 7);\n    R21(a1, b1, c1, d1, e1, w10, 11);\n    R22(a2, b2, c2, d2, e2, w0, 12);\n    R21(e1, a1, b1, c1, d1, w6, 9);\n    R22(e2, a2, b2, c2, d2, w13, 8);\n    R21(d1, e1, a1, b1, c1, w15, 7);\n    R22(d2, e2, a2, b2, c2, w5, 9);\n    R21(c1, d1, e1, a1, b1, w3, 15);\n    R22(c2, d2, e2, a2, b2, w10, 11);\n    R21(b1, c1, d1, e1, a1, w12, 7);\n    R22(b2, c2, d2, e2, a2, w14, 7);\n    R21(a1, b1, c1, d1, e1, w0, 12);\n    R22(a2, b2, c2, d2, e2, w15, 7);\n    R21(e1, a1, b1, c1, d1, w9, 15);\n    R22(e2, a2, b2, c2, d2, w8, 12);\n    R21(d1, e1, a1, b1, c1, w5, 9);\n    R22(d2, e2, a2, b2, c2, w12, 7);\n    R21(c1, d1, e1, a1, b1, w2, 11);\n    R22(c2, d2, e2, a2, b2, w4, 6);\n    R21(b1, c1, d1, e1, a1, w14, 7);\n    R22(b2, c2, d2, e2, a2, w9, 15);\n    R21(a1, b1, c1, d1, e1, w11, 13);\n    R22(a2, b2, c2, d2, e2, w1, 13);\n    R21(e1, a1, b1, c1, d1, w8, 12);\n    R22(e2, a2, b2, c2, d2, w2, 11);\n\n    R31(d1, e1, a1, b1, c1, w3, 11);\n    R32(d2, e2, a2, b2, c2, w15, 9);\n    R31(c1, d1, e1, a1, b1, w10, 13);\n    R32(c2, d2, e2, a2, b2, w5, 7);\n    R31(b1, c1, d1, e1, a1, w14, 6);\n    R32(b2, c2, d2, e2, a2, w1, 15);\n    R31(a1, b1, c1, d1, e1, w4, 7);\n    R32(a2, b2, c2, d2, e2, w3, 11);\n    R31(e1, a1, b1, c1, d1, w9, 14);\n    R32(e2, a2, b2, c2, d2, w7, 8);\n    R31(d1, e1, a1, b1, c1, w15, 9);\n    R32(d2, e2, a2, b2, c2, w14, 6);\n    R31(c1, d1, e1, a1, b1, w8, 13);\n    R32(c2, d2, e2, a2, b2, w6, 6);\n    R31(b1, c1, d1, e1, a1, w1, 15);\n    R32(b2, c2, d2, e2, a2, w9, 14);\n    R31(a1, b1, c1, d1, e1, w2, 14);\n    R32(a2, b2, c2, d2, e2, w11, 12);\n    R31(e1, a1, b1, c1, d1, w7, 8);\n    R32(e2, a2, b2, c2, d2, w8, 13);\n    R31(d1, e1, a1, b1, c1, w0, 13);\n    R32(d2, e2, a2, b2, c2, w12, 5);\n    R31(c1, d1, e1, a1, b1, w6, 6);\n    R32(c2, d2, e2, a2, b2, w2, 14);\n    R31(b1, c1, d1, e1, a1, w13, 5);\n    R32(b2, c2, d2, e2, a2, w10, 13);\n    R31(a1, b1, c1, d1, e1, w11, 12);\n    R32(a2, b2, c2, d2, e2, w0, 13);\n    R31(e1, a1, b1, c1, d1, w5, 7);\n    R32(e2, a2, b2, c2, d2, w4, 7);\n    R31(d1, e1, a1, b1, c1, w12, 5);\n    R32(d2, e2, a2, b2, c2, w13, 5);\n\n    R41(c1, d1, e1, a1, b1, w1, 11);\n    R42(c2, d2, e2, a2, b2, w8, 15);\n    R41(b1, c1, d1, e1, a1, w9, 12);\n    R42(b2, c2, d2, e2, a2, w6, 5);\n    R41(a1, b1, c1, d1, e1, w11, 14);\n    R42(a2, b2, c2, d2, e2, w4, 8);\n    R41(e1, a1, b1, c1, d1, w10, 15);\n    R42(e2, a2, b2, c2, d2, w1, 11);\n    R41(d1, e1, a1, b1, c1, w0, 14);\n    R42(d2, e2, a2, b2, c2, w3, 14);\n    R41(c1, d1, e1, a1, b1, w8, 15);\n    R42(c2, d2, e2, a2, b2, w11, 14);\n    R41(b1, c1, d1, e1, a1, w12, 9);\n    R42(b2, c2, d2, e2, a2, w15, 6);\n    R41(a1, b1, c1, d1, e1, w4, 8);\n    R42(a2, b2, c2, d2, e2, w0, 14);\n    R41(e1, a1, b1, c1, d1, w13, 9);\n    R42(e2, a2, b2, c2, d2, w5, 6);\n    R41(d1, e1, a1, b1, c1, w3, 14);\n    R42(d2, e2, a2, b2, c2, w12, 9);\n    R41(c1, d1, e1, a1, b1, w7, 5);\n    R42(c2, d2, e2, a2, b2, w2, 12);\n    R41(b1, c1, d1, e1, a1, w15, 6);\n    R42(b2, c2, d2, e2, a2, w13, 9);\n    R41(a1, b1, c1, d1, e1, w14, 8);\n    R42(a2, b2, c2, d2, e2, w9, 12);\n    R41(e1, a1, b1, c1, d1, w5, 6);\n    R42(e2, a2, b2, c2, d2, w7, 5);\n    R41(d1, e1, a1, b1, c1, w6, 5);\n    R42(d2, e2, a2, b2, c2, w10, 15);\n    R41(c1, d1, e1, a1, b1, w2, 12);\n    R42(c2, d2, e2, a2, b2, w14, 8);\n\n    R51(b1, c1, d1, e1, a1, w4, 9);\n    R52(b2, c2, d2, e2, a2, w12, 8);\n    R51(a1, b1, c1, d1, e1, w0, 15);\n    R52(a2, b2, c2, d2, e2, w15, 5);\n    R51(e1, a1, b1, c1, d1, w5, 5);\n    R52(e2, a2, b2, c2, d2, w10, 12);\n    R51(d1, e1, a1, b1, c1, w9, 11);\n    R52(d2, e2, a2, b2, c2, w4, 9);\n    R51(c1, d1, e1, a1, b1, w7, 6);\n    R52(c2, d2, e2, a2, b2, w1, 12);\n    R51(b1, c1, d1, e1, a1, w12, 8);\n    R52(b2, c2, d2, e2, a2, w5, 5);\n    R51(a1, b1, c1, d1, e1, w2, 13);\n    R52(a2, b2, c2, d2, e2, w8, 14);\n    R51(e1, a1, b1, c1, d1, w10, 12);\n    R52(e2, a2, b2, c2, d2, w7, 6);\n    R51(d1, e1, a1, b1, c1, w14, 5);\n    R52(d2, e2, a2, b2, c2, w6, 8);\n    R51(c1, d1, e1, a1, b1, w1, 12);\n    R52(c2, d2, e2, a2, b2, w2, 13);\n    R51(b1, c1, d1, e1, a1, w3, 13);\n    R52(b2, c2, d2, e2, a2, w13, 6);\n    R51(a1, b1, c1, d1, e1, w8, 14);\n    R52(a2, b2, c2, d2, e2, w14, 5);\n    R51(e1, a1, b1, c1, d1, w11, 11);\n    R52(e2, a2, b2, c2, d2, w0, 15);\n    R51(d1, e1, a1, b1, c1, w6, 8);\n    R52(d2, e2, a2, b2, c2, w3, 13);\n    R51(c1, d1, e1, a1, b1, w15, 5);\n    R52(c2, d2, e2, a2, b2, w9, 11);\n    R51(b1, c1, d1, e1, a1, w13, 6);\n    R52(b2, c2, d2, e2, a2, w11, 11);\n\n    uint32_t t = s[0];\n    s[0] = s[1] + c1 + d2;\n    s[1] = s[2] + d1 + e2;\n    s[2] = s[3] + e1 + a2;\n    s[3] = s[4] + a1 + b2;\n    s[4] = t + b1 + c2;\n}\n\n} // namespace ripemd160\n\n} // namespace\n\n////// RIPEMD160\n\nCRIPEMD160::CRIPEMD160() : bytes(0)\n{\n    ripemd160::Initialize(s);\n}\n\nCRIPEMD160 &CRIPEMD160::Write(const unsigned char *data, size_t len)\n{\n    const unsigned char *end = data + len;\n    size_t bufsize = bytes % 64;\n    if (bufsize && bufsize + len >= 64)\n    {\n        // Fill the buffer, and process it.\n        memcpy(buf + bufsize, data, 64 - bufsize);\n        bytes += 64 - bufsize;\n        data += 64 - bufsize;\n        ripemd160::Transform(s, buf);\n        bufsize = 0;\n    }\n    while (end >= data + 64)\n    {\n        // Process full chunks directly from the source.\n        ripemd160::Transform(s, data);\n        bytes += 64;\n        data += 64;\n    }\n    if (end > data)\n    {\n        // Fill the buffer with what remains.\n        memcpy(buf + bufsize, data, end - data);\n        bytes += end - data;\n    }\n    return *this;\n}\n\nvoid CRIPEMD160::Finalize(unsigned char hash[OUTPUT_SIZE])\n{\n    static const unsigned char pad[64] = {0x80};\n    unsigned char sizedesc[8];\n    WriteLE64(sizedesc, bytes << 3);\n    Write(pad, 1 + ((119 - (bytes % 64)) % 64));\n    Write(sizedesc, 8);\n    WriteLE32(hash, s[0]);\n    WriteLE32(hash + 4, s[1]);\n    WriteLE32(hash + 8, s[2]);\n    WriteLE32(hash + 12, s[3]);\n    WriteLE32(hash + 16, s[4]);\n}\n\nCRIPEMD160 &CRIPEMD160::Reset()\n{\n    bytes = 0;\n    ripemd160::Initialize(s);\n    return *this;\n}\n"
  },
  {
    "path": "src/UChainService/consensus/clone/crypto/ripemd160.h",
    "content": "// Copyright (c) 2014 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#ifndef BITCOIN_CRYPTO_RIPEMD160_H\n#define BITCOIN_CRYPTO_RIPEMD160_H\n\n#include <stdint.h>\n#include <stdlib.h>\n\n/** A hasher class for RIPEMD-160. */\nclass CRIPEMD160\n{\n  private:\n    uint32_t s[5];\n    unsigned char buf[64];\n    size_t bytes;\n\n  public:\n    static const size_t OUTPUT_SIZE = 20;\n\n    CRIPEMD160();\n    CRIPEMD160 &Write(const unsigned char *data, size_t len);\n    void Finalize(unsigned char hash[OUTPUT_SIZE]);\n    CRIPEMD160 &Reset();\n};\n\n#endif // BITCOIN_CRYPTO_RIPEMD160_H\n"
  },
  {
    "path": "src/UChainService/consensus/clone/crypto/sha1.cpp",
    "content": "// Copyright (c) 2014 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#include \"crypto/sha1.h\"\n\n#include \"crypto/common.h\"\n\n#include <string.h>\n\n// Internal implementation code.\nnamespace\n{\n/// Internal SHA-1 implementation.\nnamespace sha1\n{\n/** One round of SHA-1. */\nvoid inline Round(uint32_t a, uint32_t &b, uint32_t c, uint32_t d, uint32_t &e, uint32_t f, uint32_t k, uint32_t w)\n{\n    e += ((a << 5) | (a >> 27)) + f + k + w;\n    b = (b << 30) | (b >> 2);\n}\n\nuint32_t inline f1(uint32_t b, uint32_t c, uint32_t d) { return d ^ (b & (c ^ d)); }\nuint32_t inline f2(uint32_t b, uint32_t c, uint32_t d) { return b ^ c ^ d; }\nuint32_t inline f3(uint32_t b, uint32_t c, uint32_t d) { return (b & c) | (d & (b | c)); }\n\nuint32_t inline left(uint32_t x) { return (x << 1) | (x >> 31); }\n\n/** Initialize SHA-1 state. */\nvoid inline Initialize(uint32_t *s)\n{\n    s[0] = 0x67452301ul;\n    s[1] = 0xEFCDAB89ul;\n    s[2] = 0x98BADCFEul;\n    s[3] = 0x10325476ul;\n    s[4] = 0xC3D2E1F0ul;\n}\n\nconst uint32_t k1 = 0x5A827999ul;\nconst uint32_t k2 = 0x6ED9EBA1ul;\nconst uint32_t k3 = 0x8F1BBCDCul;\nconst uint32_t k4 = 0xCA62C1D6ul;\n\n/** Perform a SHA-1 transformation, processing a 64-byte chunk. */\nvoid Transform(uint32_t *s, const unsigned char *chunk)\n{\n    uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4];\n    uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;\n\n    Round(a, b, c, d, e, f1(b, c, d), k1, w0 = ReadBE32(chunk + 0));\n    Round(e, a, b, c, d, f1(a, b, c), k1, w1 = ReadBE32(chunk + 4));\n    Round(d, e, a, b, c, f1(e, a, b), k1, w2 = ReadBE32(chunk + 8));\n    Round(c, d, e, a, b, f1(d, e, a), k1, w3 = ReadBE32(chunk + 12));\n    Round(b, c, d, e, a, f1(c, d, e), k1, w4 = ReadBE32(chunk + 16));\n    Round(a, b, c, d, e, f1(b, c, d), k1, w5 = ReadBE32(chunk + 20));\n    Round(e, a, b, c, d, f1(a, b, c), k1, w6 = ReadBE32(chunk + 24));\n    Round(d, e, a, b, c, f1(e, a, b), k1, w7 = ReadBE32(chunk + 28));\n    Round(c, d, e, a, b, f1(d, e, a), k1, w8 = ReadBE32(chunk + 32));\n    Round(b, c, d, e, a, f1(c, d, e), k1, w9 = ReadBE32(chunk + 36));\n    Round(a, b, c, d, e, f1(b, c, d), k1, w10 = ReadBE32(chunk + 40));\n    Round(e, a, b, c, d, f1(a, b, c), k1, w11 = ReadBE32(chunk + 44));\n    Round(d, e, a, b, c, f1(e, a, b), k1, w12 = ReadBE32(chunk + 48));\n    Round(c, d, e, a, b, f1(d, e, a), k1, w13 = ReadBE32(chunk + 52));\n    Round(b, c, d, e, a, f1(c, d, e), k1, w14 = ReadBE32(chunk + 56));\n    Round(a, b, c, d, e, f1(b, c, d), k1, w15 = ReadBE32(chunk + 60));\n\n    Round(e, a, b, c, d, f1(a, b, c), k1, w0 = left(w0 ^ w13 ^ w8 ^ w2));\n    Round(d, e, a, b, c, f1(e, a, b), k1, w1 = left(w1 ^ w14 ^ w9 ^ w3));\n    Round(c, d, e, a, b, f1(d, e, a), k1, w2 = left(w2 ^ w15 ^ w10 ^ w4));\n    Round(b, c, d, e, a, f1(c, d, e), k1, w3 = left(w3 ^ w0 ^ w11 ^ w5));\n    Round(a, b, c, d, e, f2(b, c, d), k2, w4 = left(w4 ^ w1 ^ w12 ^ w6));\n    Round(e, a, b, c, d, f2(a, b, c), k2, w5 = left(w5 ^ w2 ^ w13 ^ w7));\n    Round(d, e, a, b, c, f2(e, a, b), k2, w6 = left(w6 ^ w3 ^ w14 ^ w8));\n    Round(c, d, e, a, b, f2(d, e, a), k2, w7 = left(w7 ^ w4 ^ w15 ^ w9));\n    Round(b, c, d, e, a, f2(c, d, e), k2, w8 = left(w8 ^ w5 ^ w0 ^ w10));\n    Round(a, b, c, d, e, f2(b, c, d), k2, w9 = left(w9 ^ w6 ^ w1 ^ w11));\n    Round(e, a, b, c, d, f2(a, b, c), k2, w10 = left(w10 ^ w7 ^ w2 ^ w12));\n    Round(d, e, a, b, c, f2(e, a, b), k2, w11 = left(w11 ^ w8 ^ w3 ^ w13));\n    Round(c, d, e, a, b, f2(d, e, a), k2, w12 = left(w12 ^ w9 ^ w4 ^ w14));\n    Round(b, c, d, e, a, f2(c, d, e), k2, w13 = left(w13 ^ w10 ^ w5 ^ w15));\n    Round(a, b, c, d, e, f2(b, c, d), k2, w14 = left(w14 ^ w11 ^ w6 ^ w0));\n    Round(e, a, b, c, d, f2(a, b, c), k2, w15 = left(w15 ^ w12 ^ w7 ^ w1));\n\n    Round(d, e, a, b, c, f2(e, a, b), k2, w0 = left(w0 ^ w13 ^ w8 ^ w2));\n    Round(c, d, e, a, b, f2(d, e, a), k2, w1 = left(w1 ^ w14 ^ w9 ^ w3));\n    Round(b, c, d, e, a, f2(c, d, e), k2, w2 = left(w2 ^ w15 ^ w10 ^ w4));\n    Round(a, b, c, d, e, f2(b, c, d), k2, w3 = left(w3 ^ w0 ^ w11 ^ w5));\n    Round(e, a, b, c, d, f2(a, b, c), k2, w4 = left(w4 ^ w1 ^ w12 ^ w6));\n    Round(d, e, a, b, c, f2(e, a, b), k2, w5 = left(w5 ^ w2 ^ w13 ^ w7));\n    Round(c, d, e, a, b, f2(d, e, a), k2, w6 = left(w6 ^ w3 ^ w14 ^ w8));\n    Round(b, c, d, e, a, f2(c, d, e), k2, w7 = left(w7 ^ w4 ^ w15 ^ w9));\n    Round(a, b, c, d, e, f3(b, c, d), k3, w8 = left(w8 ^ w5 ^ w0 ^ w10));\n    Round(e, a, b, c, d, f3(a, b, c), k3, w9 = left(w9 ^ w6 ^ w1 ^ w11));\n    Round(d, e, a, b, c, f3(e, a, b), k3, w10 = left(w10 ^ w7 ^ w2 ^ w12));\n    Round(c, d, e, a, b, f3(d, e, a), k3, w11 = left(w11 ^ w8 ^ w3 ^ w13));\n    Round(b, c, d, e, a, f3(c, d, e), k3, w12 = left(w12 ^ w9 ^ w4 ^ w14));\n    Round(a, b, c, d, e, f3(b, c, d), k3, w13 = left(w13 ^ w10 ^ w5 ^ w15));\n    Round(e, a, b, c, d, f3(a, b, c), k3, w14 = left(w14 ^ w11 ^ w6 ^ w0));\n    Round(d, e, a, b, c, f3(e, a, b), k3, w15 = left(w15 ^ w12 ^ w7 ^ w1));\n\n    Round(c, d, e, a, b, f3(d, e, a), k3, w0 = left(w0 ^ w13 ^ w8 ^ w2));\n    Round(b, c, d, e, a, f3(c, d, e), k3, w1 = left(w1 ^ w14 ^ w9 ^ w3));\n    Round(a, b, c, d, e, f3(b, c, d), k3, w2 = left(w2 ^ w15 ^ w10 ^ w4));\n    Round(e, a, b, c, d, f3(a, b, c), k3, w3 = left(w3 ^ w0 ^ w11 ^ w5));\n    Round(d, e, a, b, c, f3(e, a, b), k3, w4 = left(w4 ^ w1 ^ w12 ^ w6));\n    Round(c, d, e, a, b, f3(d, e, a), k3, w5 = left(w5 ^ w2 ^ w13 ^ w7));\n    Round(b, c, d, e, a, f3(c, d, e), k3, w6 = left(w6 ^ w3 ^ w14 ^ w8));\n    Round(a, b, c, d, e, f3(b, c, d), k3, w7 = left(w7 ^ w4 ^ w15 ^ w9));\n    Round(e, a, b, c, d, f3(a, b, c), k3, w8 = left(w8 ^ w5 ^ w0 ^ w10));\n    Round(d, e, a, b, c, f3(e, a, b), k3, w9 = left(w9 ^ w6 ^ w1 ^ w11));\n    Round(c, d, e, a, b, f3(d, e, a), k3, w10 = left(w10 ^ w7 ^ w2 ^ w12));\n    Round(b, c, d, e, a, f3(c, d, e), k3, w11 = left(w11 ^ w8 ^ w3 ^ w13));\n    Round(a, b, c, d, e, f2(b, c, d), k4, w12 = left(w12 ^ w9 ^ w4 ^ w14));\n    Round(e, a, b, c, d, f2(a, b, c), k4, w13 = left(w13 ^ w10 ^ w5 ^ w15));\n    Round(d, e, a, b, c, f2(e, a, b), k4, w14 = left(w14 ^ w11 ^ w6 ^ w0));\n    Round(c, d, e, a, b, f2(d, e, a), k4, w15 = left(w15 ^ w12 ^ w7 ^ w1));\n\n    Round(b, c, d, e, a, f2(c, d, e), k4, w0 = left(w0 ^ w13 ^ w8 ^ w2));\n    Round(a, b, c, d, e, f2(b, c, d), k4, w1 = left(w1 ^ w14 ^ w9 ^ w3));\n    Round(e, a, b, c, d, f2(a, b, c), k4, w2 = left(w2 ^ w15 ^ w10 ^ w4));\n    Round(d, e, a, b, c, f2(e, a, b), k4, w3 = left(w3 ^ w0 ^ w11 ^ w5));\n    Round(c, d, e, a, b, f2(d, e, a), k4, w4 = left(w4 ^ w1 ^ w12 ^ w6));\n    Round(b, c, d, e, a, f2(c, d, e), k4, w5 = left(w5 ^ w2 ^ w13 ^ w7));\n    Round(a, b, c, d, e, f2(b, c, d), k4, w6 = left(w6 ^ w3 ^ w14 ^ w8));\n    Round(e, a, b, c, d, f2(a, b, c), k4, w7 = left(w7 ^ w4 ^ w15 ^ w9));\n    Round(d, e, a, b, c, f2(e, a, b), k4, w8 = left(w8 ^ w5 ^ w0 ^ w10));\n    Round(c, d, e, a, b, f2(d, e, a), k4, w9 = left(w9 ^ w6 ^ w1 ^ w11));\n    Round(b, c, d, e, a, f2(c, d, e), k4, w10 = left(w10 ^ w7 ^ w2 ^ w12));\n    Round(a, b, c, d, e, f2(b, c, d), k4, w11 = left(w11 ^ w8 ^ w3 ^ w13));\n    Round(e, a, b, c, d, f2(a, b, c), k4, w12 = left(w12 ^ w9 ^ w4 ^ w14));\n    Round(d, e, a, b, c, f2(e, a, b), k4, left(w13 ^ w10 ^ w5 ^ w15));\n    Round(c, d, e, a, b, f2(d, e, a), k4, left(w14 ^ w11 ^ w6 ^ w0));\n    Round(b, c, d, e, a, f2(c, d, e), k4, left(w15 ^ w12 ^ w7 ^ w1));\n\n    s[0] += a;\n    s[1] += b;\n    s[2] += c;\n    s[3] += d;\n    s[4] += e;\n}\n\n} // namespace sha1\n\n} // namespace\n\n////// SHA1\n\nCSHA1::CSHA1() : bytes(0)\n{\n    sha1::Initialize(s);\n}\n\nCSHA1 &CSHA1::Write(const unsigned char *data, size_t len)\n{\n    const unsigned char *end = data + len;\n    size_t bufsize = bytes % 64;\n    if (bufsize && bufsize + len >= 64)\n    {\n        // Fill the buffer, and process it.\n        memcpy(buf + bufsize, data, 64 - bufsize);\n        bytes += 64 - bufsize;\n        data += 64 - bufsize;\n        sha1::Transform(s, buf);\n        bufsize = 0;\n    }\n    while (end >= data + 64)\n    {\n        // Process full chunks directly from the source.\n        sha1::Transform(s, data);\n        bytes += 64;\n        data += 64;\n    }\n    if (end > data)\n    {\n        // Fill the buffer with what remains.\n        memcpy(buf + bufsize, data, end - data);\n        bytes += end - data;\n    }\n    return *this;\n}\n\nvoid CSHA1::Finalize(unsigned char hash[OUTPUT_SIZE])\n{\n    static const unsigned char pad[64] = {0x80};\n    unsigned char sizedesc[8];\n    WriteBE64(sizedesc, bytes << 3);\n    Write(pad, 1 + ((119 - (bytes % 64)) % 64));\n    Write(sizedesc, 8);\n    WriteBE32(hash, s[0]);\n    WriteBE32(hash + 4, s[1]);\n    WriteBE32(hash + 8, s[2]);\n    WriteBE32(hash + 12, s[3]);\n    WriteBE32(hash + 16, s[4]);\n}\n\nCSHA1 &CSHA1::Reset()\n{\n    bytes = 0;\n    sha1::Initialize(s);\n    return *this;\n}\n"
  },
  {
    "path": "src/UChainService/consensus/clone/crypto/sha1.h",
    "content": "// Copyright (c) 2014 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#ifndef BITCOIN_CRYPTO_SHA1_H\n#define BITCOIN_CRYPTO_SHA1_H\n\n#include <stdint.h>\n#include <stdlib.h>\n\n/** A hasher class for SHA1. */\nclass CSHA1\n{\n  private:\n    uint32_t s[5];\n    unsigned char buf[64];\n    size_t bytes;\n\n  public:\n    static const size_t OUTPUT_SIZE = 20;\n\n    CSHA1();\n    CSHA1 &Write(const unsigned char *data, size_t len);\n    void Finalize(unsigned char hash[OUTPUT_SIZE]);\n    CSHA1 &Reset();\n};\n\n#endif // BITCOIN_CRYPTO_SHA1_H\n"
  },
  {
    "path": "src/UChainService/consensus/clone/crypto/sha256.cpp",
    "content": "// Copyright (c) 2014 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#include \"crypto/sha256.h\"\n\n#include \"crypto/common.h\"\n\n#include <string.h>\n\n// Internal implementation code.\nnamespace\n{\n/// Internal SHA-256 implementation.\nnamespace sha256\n{\nuint32_t inline Ch(uint32_t x, uint32_t y, uint32_t z) { return z ^ (x & (y ^ z)); }\nuint32_t inline Maj(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (z & (x | y)); }\nuint32_t inline Sigma0(uint32_t x) { return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10); }\nuint32_t inline Sigma1(uint32_t x) { return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7); }\nuint32_t inline sigma0(uint32_t x) { return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3); }\nuint32_t inline sigma1(uint32_t x) { return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10); }\n\n/** One round of SHA-256. */\nvoid inline Round(uint32_t a, uint32_t b, uint32_t c, uint32_t &d, uint32_t e, uint32_t f, uint32_t g, uint32_t &h, uint32_t k, uint32_t w)\n{\n    uint32_t t1 = h + Sigma1(e) + Ch(e, f, g) + k + w;\n    uint32_t t2 = Sigma0(a) + Maj(a, b, c);\n    d += t1;\n    h = t1 + t2;\n}\n\n/** Initialize SHA-256 state. */\nvoid inline Initialize(uint32_t *s)\n{\n    s[0] = 0x6a09e667ul;\n    s[1] = 0xbb67ae85ul;\n    s[2] = 0x3c6ef372ul;\n    s[3] = 0xa54ff53aul;\n    s[4] = 0x510e527ful;\n    s[5] = 0x9b05688cul;\n    s[6] = 0x1f83d9abul;\n    s[7] = 0x5be0cd19ul;\n}\n\n/** Perform one SHA-256 transformation, processing a 64-byte chunk. */\nvoid Transform(uint32_t *s, const unsigned char *chunk)\n{\n    uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];\n    uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;\n\n    Round(a, b, c, d, e, f, g, h, 0x428a2f98, w0 = ReadBE32(chunk + 0));\n    Round(h, a, b, c, d, e, f, g, 0x71374491, w1 = ReadBE32(chunk + 4));\n    Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w2 = ReadBE32(chunk + 8));\n    Round(f, g, h, a, b, c, d, e, 0xe9b5dba5, w3 = ReadBE32(chunk + 12));\n    Round(e, f, g, h, a, b, c, d, 0x3956c25b, w4 = ReadBE32(chunk + 16));\n    Round(d, e, f, g, h, a, b, c, 0x59f111f1, w5 = ReadBE32(chunk + 20));\n    Round(c, d, e, f, g, h, a, b, 0x923f82a4, w6 = ReadBE32(chunk + 24));\n    Round(b, c, d, e, f, g, h, a, 0xab1c5ed5, w7 = ReadBE32(chunk + 28));\n    Round(a, b, c, d, e, f, g, h, 0xd807aa98, w8 = ReadBE32(chunk + 32));\n    Round(h, a, b, c, d, e, f, g, 0x12835b01, w9 = ReadBE32(chunk + 36));\n    Round(g, h, a, b, c, d, e, f, 0x243185be, w10 = ReadBE32(chunk + 40));\n    Round(f, g, h, a, b, c, d, e, 0x550c7dc3, w11 = ReadBE32(chunk + 44));\n    Round(e, f, g, h, a, b, c, d, 0x72be5d74, w12 = ReadBE32(chunk + 48));\n    Round(d, e, f, g, h, a, b, c, 0x80deb1fe, w13 = ReadBE32(chunk + 52));\n    Round(c, d, e, f, g, h, a, b, 0x9bdc06a7, w14 = ReadBE32(chunk + 56));\n    Round(b, c, d, e, f, g, h, a, 0xc19bf174, w15 = ReadBE32(chunk + 60));\n\n    Round(a, b, c, d, e, f, g, h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0(w1));\n    Round(h, a, b, c, d, e, f, g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0(w2));\n    Round(g, h, a, b, c, d, e, f, 0x0fc19dc6, w2 += sigma1(w0) + w11 + sigma0(w3));\n    Round(f, g, h, a, b, c, d, e, 0x240ca1cc, w3 += sigma1(w1) + w12 + sigma0(w4));\n    Round(e, f, g, h, a, b, c, d, 0x2de92c6f, w4 += sigma1(w2) + w13 + sigma0(w5));\n    Round(d, e, f, g, h, a, b, c, 0x4a7484aa, w5 += sigma1(w3) + w14 + sigma0(w6));\n    Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w6 += sigma1(w4) + w15 + sigma0(w7));\n    Round(b, c, d, e, f, g, h, a, 0x76f988da, w7 += sigma1(w5) + w0 + sigma0(w8));\n    Round(a, b, c, d, e, f, g, h, 0x983e5152, w8 += sigma1(w6) + w1 + sigma0(w9));\n    Round(h, a, b, c, d, e, f, g, 0xa831c66d, w9 += sigma1(w7) + w2 + sigma0(w10));\n    Round(g, h, a, b, c, d, e, f, 0xb00327c8, w10 += sigma1(w8) + w3 + sigma0(w11));\n    Round(f, g, h, a, b, c, d, e, 0xbf597fc7, w11 += sigma1(w9) + w4 + sigma0(w12));\n    Round(e, f, g, h, a, b, c, d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13));\n    Round(d, e, f, g, h, a, b, c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14));\n    Round(c, d, e, f, g, h, a, b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15));\n    Round(b, c, d, e, f, g, h, a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0(w0));\n\n    Round(a, b, c, d, e, f, g, h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0(w1));\n    Round(h, a, b, c, d, e, f, g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0(w2));\n    Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w2 += sigma1(w0) + w11 + sigma0(w3));\n    Round(f, g, h, a, b, c, d, e, 0x53380d13, w3 += sigma1(w1) + w12 + sigma0(w4));\n    Round(e, f, g, h, a, b, c, d, 0x650a7354, w4 += sigma1(w2) + w13 + sigma0(w5));\n    Round(d, e, f, g, h, a, b, c, 0x766a0abb, w5 += sigma1(w3) + w14 + sigma0(w6));\n    Round(c, d, e, f, g, h, a, b, 0x81c2c92e, w6 += sigma1(w4) + w15 + sigma0(w7));\n    Round(b, c, d, e, f, g, h, a, 0x92722c85, w7 += sigma1(w5) + w0 + sigma0(w8));\n    Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w8 += sigma1(w6) + w1 + sigma0(w9));\n    Round(h, a, b, c, d, e, f, g, 0xa81a664b, w9 += sigma1(w7) + w2 + sigma0(w10));\n    Round(g, h, a, b, c, d, e, f, 0xc24b8b70, w10 += sigma1(w8) + w3 + sigma0(w11));\n    Round(f, g, h, a, b, c, d, e, 0xc76c51a3, w11 += sigma1(w9) + w4 + sigma0(w12));\n    Round(e, f, g, h, a, b, c, d, 0xd192e819, w12 += sigma1(w10) + w5 + sigma0(w13));\n    Round(d, e, f, g, h, a, b, c, 0xd6990624, w13 += sigma1(w11) + w6 + sigma0(w14));\n    Round(c, d, e, f, g, h, a, b, 0xf40e3585, w14 += sigma1(w12) + w7 + sigma0(w15));\n    Round(b, c, d, e, f, g, h, a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0(w0));\n\n    Round(a, b, c, d, e, f, g, h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0(w1));\n    Round(h, a, b, c, d, e, f, g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0(w2));\n    Round(g, h, a, b, c, d, e, f, 0x2748774c, w2 += sigma1(w0) + w11 + sigma0(w3));\n    Round(f, g, h, a, b, c, d, e, 0x34b0bcb5, w3 += sigma1(w1) + w12 + sigma0(w4));\n    Round(e, f, g, h, a, b, c, d, 0x391c0cb3, w4 += sigma1(w2) + w13 + sigma0(w5));\n    Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w5 += sigma1(w3) + w14 + sigma0(w6));\n    Round(c, d, e, f, g, h, a, b, 0x5b9cca4f, w6 += sigma1(w4) + w15 + sigma0(w7));\n    Round(b, c, d, e, f, g, h, a, 0x682e6ff3, w7 += sigma1(w5) + w0 + sigma0(w8));\n    Round(a, b, c, d, e, f, g, h, 0x748f82ee, w8 += sigma1(w6) + w1 + sigma0(w9));\n    Round(h, a, b, c, d, e, f, g, 0x78a5636f, w9 += sigma1(w7) + w2 + sigma0(w10));\n    Round(g, h, a, b, c, d, e, f, 0x84c87814, w10 += sigma1(w8) + w3 + sigma0(w11));\n    Round(f, g, h, a, b, c, d, e, 0x8cc70208, w11 += sigma1(w9) + w4 + sigma0(w12));\n    Round(e, f, g, h, a, b, c, d, 0x90befffa, w12 += sigma1(w10) + w5 + sigma0(w13));\n    Round(d, e, f, g, h, a, b, c, 0xa4506ceb, w13 += sigma1(w11) + w6 + sigma0(w14));\n    Round(c, d, e, f, g, h, a, b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15));\n    Round(b, c, d, e, f, g, h, a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0(w0));\n\n    s[0] += a;\n    s[1] += b;\n    s[2] += c;\n    s[3] += d;\n    s[4] += e;\n    s[5] += f;\n    s[6] += g;\n    s[7] += h;\n}\n\n} // namespace sha256\n} // namespace\n\n////// SHA-256\n\nCSHA256::CSHA256() : bytes(0)\n{\n    sha256::Initialize(s);\n}\n\nCSHA256 &CSHA256::Write(const unsigned char *data, size_t len)\n{\n    const unsigned char *end = data + len;\n    size_t bufsize = bytes % 64;\n    if (bufsize && bufsize + len >= 64)\n    {\n        // Fill the buffer, and process it.\n        memcpy(buf + bufsize, data, 64 - bufsize);\n        bytes += 64 - bufsize;\n        data += 64 - bufsize;\n        sha256::Transform(s, buf);\n        bufsize = 0;\n    }\n    while (end >= data + 64)\n    {\n        // Process full chunks directly from the source.\n        sha256::Transform(s, data);\n        bytes += 64;\n        data += 64;\n    }\n    if (end > data)\n    {\n        // Fill the buffer with what remains.\n        memcpy(buf + bufsize, data, end - data);\n        bytes += end - data;\n    }\n    return *this;\n}\n\nvoid CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE])\n{\n    static const unsigned char pad[64] = {0x80};\n    unsigned char sizedesc[8];\n    WriteBE64(sizedesc, bytes << 3);\n    Write(pad, 1 + ((119 - (bytes % 64)) % 64));\n    Write(sizedesc, 8);\n    WriteBE32(hash, s[0]);\n    WriteBE32(hash + 4, s[1]);\n    WriteBE32(hash + 8, s[2]);\n    WriteBE32(hash + 12, s[3]);\n    WriteBE32(hash + 16, s[4]);\n    WriteBE32(hash + 20, s[5]);\n    WriteBE32(hash + 24, s[6]);\n    WriteBE32(hash + 28, s[7]);\n}\n\nCSHA256 &CSHA256::Reset()\n{\n    bytes = 0;\n    sha256::Initialize(s);\n    return *this;\n}\n"
  },
  {
    "path": "src/UChainService/consensus/clone/crypto/sha256.h",
    "content": "// Copyright (c) 2014 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#ifndef BITCOIN_CRYPTO_SHA256_H\n#define BITCOIN_CRYPTO_SHA256_H\n\n#include <stdint.h>\n#include <stdlib.h>\n\n/** A hasher class for SHA-256. */\nclass CSHA256\n{\n  private:\n    uint32_t s[8];\n    unsigned char buf[64];\n    size_t bytes;\n\n  public:\n    static const size_t OUTPUT_SIZE = 32;\n\n    CSHA256();\n    CSHA256 &Write(const unsigned char *data, size_t len);\n    void Finalize(unsigned char hash[OUTPUT_SIZE]);\n    CSHA256 &Reset();\n};\n\n#endif // BITCOIN_CRYPTO_SHA256_H\n"
  },
  {
    "path": "src/UChainService/consensus/clone/crypto/sha512.cpp",
    "content": "// Copyright (c) 2014 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#include \"crypto/sha512.h\"\n\n#include \"crypto/common.h\"\n\n#include <string.h>\n\n// Internal implementation code.\nnamespace\n{\n/// Internal SHA-512 implementation.\nnamespace sha512\n{\nuint64_t inline Ch(uint64_t x, uint64_t y, uint64_t z) { return z ^ (x & (y ^ z)); }\nuint64_t inline Maj(uint64_t x, uint64_t y, uint64_t z) { return (x & y) | (z & (x | y)); }\nuint64_t inline Sigma0(uint64_t x) { return (x >> 28 | x << 36) ^ (x >> 34 | x << 30) ^ (x >> 39 | x << 25); }\nuint64_t inline Sigma1(uint64_t x) { return (x >> 14 | x << 50) ^ (x >> 18 | x << 46) ^ (x >> 41 | x << 23); }\nuint64_t inline sigma0(uint64_t x) { return (x >> 1 | x << 63) ^ (x >> 8 | x << 56) ^ (x >> 7); }\nuint64_t inline sigma1(uint64_t x) { return (x >> 19 | x << 45) ^ (x >> 61 | x << 3) ^ (x >> 6); }\n\n/** One round of SHA-512. */\nvoid inline Round(uint64_t a, uint64_t b, uint64_t c, uint64_t &d, uint64_t e, uint64_t f, uint64_t g, uint64_t &h, uint64_t k, uint64_t w)\n{\n    uint64_t t1 = h + Sigma1(e) + Ch(e, f, g) + k + w;\n    uint64_t t2 = Sigma0(a) + Maj(a, b, c);\n    d += t1;\n    h = t1 + t2;\n}\n\n/** Initialize SHA-256 state. */\nvoid inline Initialize(uint64_t *s)\n{\n    s[0] = 0x6a09e667f3bcc908ull;\n    s[1] = 0xbb67ae8584caa73bull;\n    s[2] = 0x3c6ef372fe94f82bull;\n    s[3] = 0xa54ff53a5f1d36f1ull;\n    s[4] = 0x510e527fade682d1ull;\n    s[5] = 0x9b05688c2b3e6c1full;\n    s[6] = 0x1f83d9abfb41bd6bull;\n    s[7] = 0x5be0cd19137e2179ull;\n}\n\n/** Perform one SHA-512 transformation, processing a 128-byte chunk. */\nvoid Transform(uint64_t *s, const unsigned char *chunk)\n{\n    uint64_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];\n    uint64_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;\n\n    Round(a, b, c, d, e, f, g, h, 0x428a2f98d728ae22ull, w0 = ReadBE64(chunk + 0));\n    Round(h, a, b, c, d, e, f, g, 0x7137449123ef65cdull, w1 = ReadBE64(chunk + 8));\n    Round(g, h, a, b, c, d, e, f, 0xb5c0fbcfec4d3b2full, w2 = ReadBE64(chunk + 16));\n    Round(f, g, h, a, b, c, d, e, 0xe9b5dba58189dbbcull, w3 = ReadBE64(chunk + 24));\n    Round(e, f, g, h, a, b, c, d, 0x3956c25bf348b538ull, w4 = ReadBE64(chunk + 32));\n    Round(d, e, f, g, h, a, b, c, 0x59f111f1b605d019ull, w5 = ReadBE64(chunk + 40));\n    Round(c, d, e, f, g, h, a, b, 0x923f82a4af194f9bull, w6 = ReadBE64(chunk + 48));\n    Round(b, c, d, e, f, g, h, a, 0xab1c5ed5da6d8118ull, w7 = ReadBE64(chunk + 56));\n    Round(a, b, c, d, e, f, g, h, 0xd807aa98a3030242ull, w8 = ReadBE64(chunk + 64));\n    Round(h, a, b, c, d, e, f, g, 0x12835b0145706fbeull, w9 = ReadBE64(chunk + 72));\n    Round(g, h, a, b, c, d, e, f, 0x243185be4ee4b28cull, w10 = ReadBE64(chunk + 80));\n    Round(f, g, h, a, b, c, d, e, 0x550c7dc3d5ffb4e2ull, w11 = ReadBE64(chunk + 88));\n    Round(e, f, g, h, a, b, c, d, 0x72be5d74f27b896full, w12 = ReadBE64(chunk + 96));\n    Round(d, e, f, g, h, a, b, c, 0x80deb1fe3b1696b1ull, w13 = ReadBE64(chunk + 104));\n    Round(c, d, e, f, g, h, a, b, 0x9bdc06a725c71235ull, w14 = ReadBE64(chunk + 112));\n    Round(b, c, d, e, f, g, h, a, 0xc19bf174cf692694ull, w15 = ReadBE64(chunk + 120));\n\n    Round(a, b, c, d, e, f, g, h, 0xe49b69c19ef14ad2ull, w0 += sigma1(w14) + w9 + sigma0(w1));\n    Round(h, a, b, c, d, e, f, g, 0xefbe4786384f25e3ull, w1 += sigma1(w15) + w10 + sigma0(w2));\n    Round(g, h, a, b, c, d, e, f, 0x0fc19dc68b8cd5b5ull, w2 += sigma1(w0) + w11 + sigma0(w3));\n    Round(f, g, h, a, b, c, d, e, 0x240ca1cc77ac9c65ull, w3 += sigma1(w1) + w12 + sigma0(w4));\n    Round(e, f, g, h, a, b, c, d, 0x2de92c6f592b0275ull, w4 += sigma1(w2) + w13 + sigma0(w5));\n    Round(d, e, f, g, h, a, b, c, 0x4a7484aa6ea6e483ull, w5 += sigma1(w3) + w14 + sigma0(w6));\n    Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcbd41fbd4ull, w6 += sigma1(w4) + w15 + sigma0(w7));\n    Round(b, c, d, e, f, g, h, a, 0x76f988da831153b5ull, w7 += sigma1(w5) + w0 + sigma0(w8));\n    Round(a, b, c, d, e, f, g, h, 0x983e5152ee66dfabull, w8 += sigma1(w6) + w1 + sigma0(w9));\n    Round(h, a, b, c, d, e, f, g, 0xa831c66d2db43210ull, w9 += sigma1(w7) + w2 + sigma0(w10));\n    Round(g, h, a, b, c, d, e, f, 0xb00327c898fb213full, w10 += sigma1(w8) + w3 + sigma0(w11));\n    Round(f, g, h, a, b, c, d, e, 0xbf597fc7beef0ee4ull, w11 += sigma1(w9) + w4 + sigma0(w12));\n    Round(e, f, g, h, a, b, c, d, 0xc6e00bf33da88fc2ull, w12 += sigma1(w10) + w5 + sigma0(w13));\n    Round(d, e, f, g, h, a, b, c, 0xd5a79147930aa725ull, w13 += sigma1(w11) + w6 + sigma0(w14));\n    Round(c, d, e, f, g, h, a, b, 0x06ca6351e003826full, w14 += sigma1(w12) + w7 + sigma0(w15));\n    Round(b, c, d, e, f, g, h, a, 0x142929670a0e6e70ull, w15 += sigma1(w13) + w8 + sigma0(w0));\n\n    Round(a, b, c, d, e, f, g, h, 0x27b70a8546d22ffcull, w0 += sigma1(w14) + w9 + sigma0(w1));\n    Round(h, a, b, c, d, e, f, g, 0x2e1b21385c26c926ull, w1 += sigma1(w15) + w10 + sigma0(w2));\n    Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc5ac42aedull, w2 += sigma1(w0) + w11 + sigma0(w3));\n    Round(f, g, h, a, b, c, d, e, 0x53380d139d95b3dfull, w3 += sigma1(w1) + w12 + sigma0(w4));\n    Round(e, f, g, h, a, b, c, d, 0x650a73548baf63deull, w4 += sigma1(w2) + w13 + sigma0(w5));\n    Round(d, e, f, g, h, a, b, c, 0x766a0abb3c77b2a8ull, w5 += sigma1(w3) + w14 + sigma0(w6));\n    Round(c, d, e, f, g, h, a, b, 0x81c2c92e47edaee6ull, w6 += sigma1(w4) + w15 + sigma0(w7));\n    Round(b, c, d, e, f, g, h, a, 0x92722c851482353bull, w7 += sigma1(w5) + w0 + sigma0(w8));\n    Round(a, b, c, d, e, f, g, h, 0xa2bfe8a14cf10364ull, w8 += sigma1(w6) + w1 + sigma0(w9));\n    Round(h, a, b, c, d, e, f, g, 0xa81a664bbc423001ull, w9 += sigma1(w7) + w2 + sigma0(w10));\n    Round(g, h, a, b, c, d, e, f, 0xc24b8b70d0f89791ull, w10 += sigma1(w8) + w3 + sigma0(w11));\n    Round(f, g, h, a, b, c, d, e, 0xc76c51a30654be30ull, w11 += sigma1(w9) + w4 + sigma0(w12));\n    Round(e, f, g, h, a, b, c, d, 0xd192e819d6ef5218ull, w12 += sigma1(w10) + w5 + sigma0(w13));\n    Round(d, e, f, g, h, a, b, c, 0xd69906245565a910ull, w13 += sigma1(w11) + w6 + sigma0(w14));\n    Round(c, d, e, f, g, h, a, b, 0xf40e35855771202aull, w14 += sigma1(w12) + w7 + sigma0(w15));\n    Round(b, c, d, e, f, g, h, a, 0x106aa07032bbd1b8ull, w15 += sigma1(w13) + w8 + sigma0(w0));\n\n    Round(a, b, c, d, e, f, g, h, 0x19a4c116b8d2d0c8ull, w0 += sigma1(w14) + w9 + sigma0(w1));\n    Round(h, a, b, c, d, e, f, g, 0x1e376c085141ab53ull, w1 += sigma1(w15) + w10 + sigma0(w2));\n    Round(g, h, a, b, c, d, e, f, 0x2748774cdf8eeb99ull, w2 += sigma1(w0) + w11 + sigma0(w3));\n    Round(f, g, h, a, b, c, d, e, 0x34b0bcb5e19b48a8ull, w3 += sigma1(w1) + w12 + sigma0(w4));\n    Round(e, f, g, h, a, b, c, d, 0x391c0cb3c5c95a63ull, w4 += sigma1(w2) + w13 + sigma0(w5));\n    Round(d, e, f, g, h, a, b, c, 0x4ed8aa4ae3418acbull, w5 += sigma1(w3) + w14 + sigma0(w6));\n    Round(c, d, e, f, g, h, a, b, 0x5b9cca4f7763e373ull, w6 += sigma1(w4) + w15 + sigma0(w7));\n    Round(b, c, d, e, f, g, h, a, 0x682e6ff3d6b2b8a3ull, w7 += sigma1(w5) + w0 + sigma0(w8));\n    Round(a, b, c, d, e, f, g, h, 0x748f82ee5defb2fcull, w8 += sigma1(w6) + w1 + sigma0(w9));\n    Round(h, a, b, c, d, e, f, g, 0x78a5636f43172f60ull, w9 += sigma1(w7) + w2 + sigma0(w10));\n    Round(g, h, a, b, c, d, e, f, 0x84c87814a1f0ab72ull, w10 += sigma1(w8) + w3 + sigma0(w11));\n    Round(f, g, h, a, b, c, d, e, 0x8cc702081a6439ecull, w11 += sigma1(w9) + w4 + sigma0(w12));\n    Round(e, f, g, h, a, b, c, d, 0x90befffa23631e28ull, w12 += sigma1(w10) + w5 + sigma0(w13));\n    Round(d, e, f, g, h, a, b, c, 0xa4506cebde82bde9ull, w13 += sigma1(w11) + w6 + sigma0(w14));\n    Round(c, d, e, f, g, h, a, b, 0xbef9a3f7b2c67915ull, w14 += sigma1(w12) + w7 + sigma0(w15));\n    Round(b, c, d, e, f, g, h, a, 0xc67178f2e372532bull, w15 += sigma1(w13) + w8 + sigma0(w0));\n\n    Round(a, b, c, d, e, f, g, h, 0xca273eceea26619cull, w0 += sigma1(w14) + w9 + sigma0(w1));\n    Round(h, a, b, c, d, e, f, g, 0xd186b8c721c0c207ull, w1 += sigma1(w15) + w10 + sigma0(w2));\n    Round(g, h, a, b, c, d, e, f, 0xeada7dd6cde0eb1eull, w2 += sigma1(w0) + w11 + sigma0(w3));\n    Round(f, g, h, a, b, c, d, e, 0xf57d4f7fee6ed178ull, w3 += sigma1(w1) + w12 + sigma0(w4));\n    Round(e, f, g, h, a, b, c, d, 0x06f067aa72176fbaull, w4 += sigma1(w2) + w13 + sigma0(w5));\n    Round(d, e, f, g, h, a, b, c, 0x0a637dc5a2c898a6ull, w5 += sigma1(w3) + w14 + sigma0(w6));\n    Round(c, d, e, f, g, h, a, b, 0x113f9804bef90daeull, w6 += sigma1(w4) + w15 + sigma0(w7));\n    Round(b, c, d, e, f, g, h, a, 0x1b710b35131c471bull, w7 += sigma1(w5) + w0 + sigma0(w8));\n    Round(a, b, c, d, e, f, g, h, 0x28db77f523047d84ull, w8 += sigma1(w6) + w1 + sigma0(w9));\n    Round(h, a, b, c, d, e, f, g, 0x32caab7b40c72493ull, w9 += sigma1(w7) + w2 + sigma0(w10));\n    Round(g, h, a, b, c, d, e, f, 0x3c9ebe0a15c9bebcull, w10 += sigma1(w8) + w3 + sigma0(w11));\n    Round(f, g, h, a, b, c, d, e, 0x431d67c49c100d4cull, w11 += sigma1(w9) + w4 + sigma0(w12));\n    Round(e, f, g, h, a, b, c, d, 0x4cc5d4becb3e42b6ull, w12 += sigma1(w10) + w5 + sigma0(w13));\n    Round(d, e, f, g, h, a, b, c, 0x597f299cfc657e2aull, w13 += sigma1(w11) + w6 + sigma0(w14));\n    Round(c, d, e, f, g, h, a, b, 0x5fcb6fab3ad6faecull, w14 + sigma1(w12) + w7 + sigma0(w15));\n    Round(b, c, d, e, f, g, h, a, 0x6c44198c4a475817ull, w15 + sigma1(w13) + w8 + sigma0(w0));\n\n    s[0] += a;\n    s[1] += b;\n    s[2] += c;\n    s[3] += d;\n    s[4] += e;\n    s[5] += f;\n    s[6] += g;\n    s[7] += h;\n}\n\n} // namespace sha512\n\n} // namespace\n\n////// SHA-512\n\nCSHA512::CSHA512() : bytes(0)\n{\n    sha512::Initialize(s);\n}\n\nCSHA512 &CSHA512::Write(const unsigned char *data, size_t len)\n{\n    const unsigned char *end = data + len;\n    size_t bufsize = bytes % 128;\n    if (bufsize && bufsize + len >= 128)\n    {\n        // Fill the buffer, and process it.\n        memcpy(buf + bufsize, data, 128 - bufsize);\n        bytes += 128 - bufsize;\n        data += 128 - bufsize;\n        sha512::Transform(s, buf);\n        bufsize = 0;\n    }\n    while (end >= data + 128)\n    {\n        // Process full chunks directly from the source.\n        sha512::Transform(s, data);\n        data += 128;\n        bytes += 128;\n    }\n    if (end > data)\n    {\n        // Fill the buffer with what remains.\n        memcpy(buf + bufsize, data, end - data);\n        bytes += end - data;\n    }\n    return *this;\n}\n\nvoid CSHA512::Finalize(unsigned char hash[OUTPUT_SIZE])\n{\n    static const unsigned char pad[128] = {0x80};\n    unsigned char sizedesc[16] = {0x00};\n    WriteBE64(sizedesc + 8, bytes << 3);\n    Write(pad, 1 + ((239 - (bytes % 128)) % 128));\n    Write(sizedesc, 16);\n    WriteBE64(hash, s[0]);\n    WriteBE64(hash + 8, s[1]);\n    WriteBE64(hash + 16, s[2]);\n    WriteBE64(hash + 24, s[3]);\n    WriteBE64(hash + 32, s[4]);\n    WriteBE64(hash + 40, s[5]);\n    WriteBE64(hash + 48, s[6]);\n    WriteBE64(hash + 56, s[7]);\n}\n\nCSHA512 &CSHA512::Reset()\n{\n    bytes = 0;\n    sha512::Initialize(s);\n    return *this;\n}\n"
  },
  {
    "path": "src/UChainService/consensus/clone/crypto/sha512.h",
    "content": "// Copyright (c) 2014 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#ifndef BITCOIN_CRYPTO_SHA512_H\n#define BITCOIN_CRYPTO_SHA512_H\n\n#include <stdint.h>\n#include <stdlib.h>\n\n/** A hasher class for SHA-512. */\nclass CSHA512\n{\n  private:\n    uint64_t s[8];\n    unsigned char buf[128];\n    size_t bytes;\n\n  public:\n    static const size_t OUTPUT_SIZE = 64;\n\n    CSHA512();\n    CSHA512 &Write(const unsigned char *data, size_t len);\n    void Finalize(unsigned char hash[OUTPUT_SIZE]);\n    CSHA512 &Reset();\n};\n\n#endif // BITCOIN_CRYPTO_SHA512_H\n"
  },
  {
    "path": "src/UChainService/consensus/clone/hash.cpp",
    "content": "// Copyright (c) 2013-2015 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#include \"hash.h\"\n#include \"crypto/common.h\"\n#include \"crypto/hmac_sha512.h\"\n#include \"pubkey.h\"\n\ninline uint32_t ROTL32(uint32_t x, int8_t r)\n{\n    return (x << r) | (x >> (32 - r));\n}\n\nunsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char> &vDataToHash)\n{\n    // The following is MurmurHash3 (x86_32), see http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp\n    uint32_t h1 = nHashSeed;\n    if (vDataToHash.size() > 0)\n    {\n        const uint32_t c1 = 0xcc9e2d51;\n        const uint32_t c2 = 0x1b873593;\n\n        const int nblocks = vDataToHash.size() / 4;\n\n        //----------\n        // body\n        const uint8_t *blocks = &vDataToHash[0] + nblocks * 4;\n\n        for (int i = -nblocks; i; i++)\n        {\n            uint32_t k1 = ReadLE32(blocks + i * 4);\n\n            k1 *= c1;\n            k1 = ROTL32(k1, 15);\n            k1 *= c2;\n\n            h1 ^= k1;\n            h1 = ROTL32(h1, 13);\n            h1 = h1 * 5 + 0xe6546b64;\n        }\n\n        //----------\n        // tail\n        const uint8_t *tail = (const uint8_t *)(&vDataToHash[0] + nblocks * 4);\n\n        uint32_t k1 = 0;\n\n        switch (vDataToHash.size() & 3)\n        {\n        case 3:\n            k1 ^= tail[2] << 16;\n        case 2:\n            k1 ^= tail[1] << 8;\n        case 1:\n            k1 ^= tail[0];\n            k1 *= c1;\n            k1 = ROTL32(k1, 15);\n            k1 *= c2;\n            h1 ^= k1;\n        };\n    }\n\n    //----------\n    // finalization\n    h1 ^= vDataToHash.size();\n    h1 ^= h1 >> 16;\n    h1 *= 0x85ebca6b;\n    h1 ^= h1 >> 13;\n    h1 *= 0xc2b2ae35;\n    h1 ^= h1 >> 16;\n\n    return h1;\n}\n\nvoid BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64])\n{\n    unsigned char num[4];\n    num[0] = (nChild >> 24) & 0xFF;\n    num[1] = (nChild >> 16) & 0xFF;\n    num[2] = (nChild >> 8) & 0xFF;\n    num[3] = (nChild >> 0) & 0xFF;\n    CHMAC_SHA512(chainCode.begin(), chainCode.size()).Write(&header, 1).Write(data, 32).Write(num, 4).Finalize(output);\n}\n"
  },
  {
    "path": "src/UChainService/consensus/clone/hash.h",
    "content": "// Copyright (c) 2009-2010 Satoshi Nakamoto\n// Copyright (c) 2009-2015 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#ifndef BITCOIN_HASH_H\n#define BITCOIN_HASH_H\n\n#include \"crypto/ripemd160.h\"\n#include \"crypto/sha256.h\"\n#include \"prevector.h\"\n#include \"serialize.h\"\n#include \"uint256.h\"\n#include \"version.h\"\n\n#include <vector>\n\ntypedef uint256 ChainCode;\n\n/** A hasher class for Bitcoin's 256-bit hash (double SHA-256). */\nclass CHash256\n{\n  private:\n    CSHA256 sha;\n\n  public:\n    static const size_t OUTPUT_SIZE = CSHA256::OUTPUT_SIZE;\n\n    void Finalize(unsigned char hash[OUTPUT_SIZE])\n    {\n        unsigned char buf[sha.OUTPUT_SIZE];\n        sha.Finalize(buf);\n        sha.Reset().Write(buf, sha.OUTPUT_SIZE).Finalize(hash);\n    }\n\n    CHash256 &Write(const unsigned char *data, size_t len)\n    {\n        sha.Write(data, len);\n        return *this;\n    }\n\n    CHash256 &Reset()\n    {\n        sha.Reset();\n        return *this;\n    }\n};\n\n/** A hasher class for Bitcoin's 160-bit hash (SHA-256 + RIPEMD-160). */\nclass CHash160\n{\n  private:\n    CSHA256 sha;\n\n  public:\n    static const size_t OUTPUT_SIZE = CRIPEMD160::OUTPUT_SIZE;\n\n    void Finalize(unsigned char hash[OUTPUT_SIZE])\n    {\n        unsigned char buf[sha.OUTPUT_SIZE];\n        sha.Finalize(buf);\n        CRIPEMD160().Write(buf, sha.OUTPUT_SIZE).Finalize(hash);\n    }\n\n    CHash160 &Write(const unsigned char *data, size_t len)\n    {\n        sha.Write(data, len);\n        return *this;\n    }\n\n    CHash160 &Reset()\n    {\n        sha.Reset();\n        return *this;\n    }\n};\n\n/** Compute the 256-bit hash of an object. */\ntemplate <typename T1>\ninline uint256 Hash(const T1 pbegin, const T1 pend)\n{\n    static const unsigned char pblank[1] = {};\n    uint256 result;\n    CHash256().Write(pbegin == pend ? pblank : (const unsigned char *)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0])).Finalize((unsigned char *)&result);\n    return result;\n}\n\n/** Compute the 256-bit hash of the concatenation of two objects. */\ntemplate <typename T1, typename T2>\ninline uint256 Hash(const T1 p1begin, const T1 p1end,\n                    const T2 p2begin, const T2 p2end)\n{\n    static const unsigned char pblank[1] = {};\n    uint256 result;\n    CHash256().Write(p1begin == p1end ? pblank : (const unsigned char *)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0])).Write(p2begin == p2end ? pblank : (const unsigned char *)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0])).Finalize((unsigned char *)&result);\n    return result;\n}\n\n/** Compute the 256-bit hash of the concatenation of three objects. */\ntemplate <typename T1, typename T2, typename T3>\ninline uint256 Hash(const T1 p1begin, const T1 p1end,\n                    const T2 p2begin, const T2 p2end,\n                    const T3 p3begin, const T3 p3end)\n{\n    static const unsigned char pblank[1] = {};\n    uint256 result;\n    CHash256().Write(p1begin == p1end ? pblank : (const unsigned char *)&p1begin[0], (p1end - p1begin) * sizeof(p1begin[0])).Write(p2begin == p2end ? pblank : (const unsigned char *)&p2begin[0], (p2end - p2begin) * sizeof(p2begin[0])).Write(p3begin == p3end ? pblank : (const unsigned char *)&p3begin[0], (p3end - p3begin) * sizeof(p3begin[0])).Finalize((unsigned char *)&result);\n    return result;\n}\n\n/** Compute the 160-bit hash an object. */\ntemplate <typename T1>\ninline uint160 Hash160(const T1 pbegin, const T1 pend)\n{\n    static unsigned char pblank[1] = {};\n    uint160 result;\n    CHash160().Write(pbegin == pend ? pblank : (const unsigned char *)&pbegin[0], (pend - pbegin) * sizeof(pbegin[0])).Finalize((unsigned char *)&result);\n    return result;\n}\n\n/** Compute the 160-bit hash of a vector. */\ninline uint160 Hash160(const std::vector<unsigned char> &vch)\n{\n    return Hash160(vch.begin(), vch.end());\n}\n\n/** Compute the 160-bit hash of a vector. */\ntemplate <unsigned int N>\ninline uint160 Hash160(const prevector<N, unsigned char> &vch)\n{\n    return Hash160(vch.begin(), vch.end());\n}\n\n/** A writer stream (for serialization) that computes a 256-bit hash. */\nclass CHashWriter\n{\n  private:\n    CHash256 ctx;\n\n  public:\n    int nType;\n    int nVersion;\n\n    CHashWriter(int nTypeIn, int nVersionIn) : nType(nTypeIn), nVersion(nVersionIn) {}\n\n    CHashWriter &write(const char *pch, size_t size)\n    {\n        ctx.Write((const unsigned char *)pch, size);\n        return (*this);\n    }\n\n    // invalidates the object\n    uint256 GetHash()\n    {\n        uint256 result;\n        ctx.Finalize((unsigned char *)&result);\n        return result;\n    }\n\n    template <typename T>\n    CHashWriter &operator<<(const T &obj)\n    {\n        // Serialize to this stream\n        ::Serialize(*this, obj, nType, nVersion);\n        return (*this);\n    }\n};\n\n/** Compute the 256-bit hash of an object's serialization. */\ntemplate <typename T>\nuint256 SerializeHash(const T &obj, int nType = SER_GETHASH, int nVersion = PROTOCOL_VERSION)\n{\n    CHashWriter ss(nType, nVersion);\n    ss << obj;\n    return ss.GetHash();\n}\n\nunsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char> &vDataToHash);\n\nvoid BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64]);\n\n#endif // BITCOIN_HASH_H\n"
  },
  {
    "path": "src/UChainService/consensus/clone/prevector.h",
    "content": "#ifndef _BITCOIN_PREVECTOR_H_\n#define _BITCOIN_PREVECTOR_H_\n\n#include <stdlib.h>\n#include <stdint.h>\n#include <string.h>\n\n#include <iterator>\n\n#pragma pack(push, 1)\n/** Implements a drop-in replacement for std::vector<T> which stores up to N\n *  elements directly (without heap allocation). The types Size and Diff are\n *  used to store element counts, and can be any unsigned + signed type.\n *\n *  Storage layout is either:\n *  - Direct allocation:\n *    - Size _size: the number of used elements (between 0 and N)\n *    - T direct[N]: an array of N elements of type T\n *      (only the first _size are initialized).\n *  - Indirect allocation:\n *    - Size _size: the number of used elements plus N + 1\n *    - Size capacity: the number of allocated elements\n *    - T* indirect: a pointer to an array of capacity elements of type T\n *      (only the first _size are initialized).\n *\n *  The data type T must be movable by memmove/realloc(). Once we switch to C++,\n *  move constructors can be used instead.\n */\ntemplate <unsigned int N, typename T, typename Size = uint32_t, typename Diff = int32_t>\nclass prevector\n{\n  public:\n    typedef Size size_type;\n    typedef Diff difference_type;\n    typedef T value_type;\n    typedef value_type &reference;\n    typedef const value_type &const_reference;\n    typedef value_type *pointer;\n    typedef const value_type *const_pointer;\n\n    class iterator\n    {\n        T *ptr;\n\n      public:\n        typedef Diff difference_type;\n        typedef T value_type;\n        typedef T *pointer;\n        typedef T &reference;\n        typedef std::random_access_iterator_tag iterator_category;\n        iterator(T *ptr_) : ptr(ptr_) {}\n        T &operator*() const { return *ptr; }\n        T *operator->() const { return ptr; }\n        T &operator[](size_type pos) { return ptr[pos]; }\n        const T &operator[](size_type pos) const { return ptr[pos]; }\n        iterator &operator++()\n        {\n            ptr++;\n            return *this;\n        }\n        iterator &operator--()\n        {\n            ptr--;\n            return *this;\n        }\n        iterator operator++(int)\n        {\n            iterator copy(*this);\n            ++(*this);\n            return copy;\n        }\n        iterator operator--(int)\n        {\n            iterator copy(*this);\n            --(*this);\n            return copy;\n        }\n        difference_type friend operator-(iterator a, iterator b) { return (&(*a) - &(*b)); }\n        iterator operator+(size_type n) { return iterator(ptr + n); }\n        iterator &operator+=(size_type n)\n        {\n            ptr += n;\n            return *this;\n        }\n        iterator operator-(size_type n) { return iterator(ptr - n); }\n        iterator &operator-=(size_type n)\n        {\n            ptr -= n;\n            return *this;\n        }\n        bool operator==(iterator x) const { return ptr == x.ptr; }\n        bool operator!=(iterator x) const { return ptr != x.ptr; }\n        bool operator>=(iterator x) const { return ptr >= x.ptr; }\n        bool operator<=(iterator x) const { return ptr <= x.ptr; }\n        bool operator>(iterator x) const { return ptr > x.ptr; }\n        bool operator<(iterator x) const { return ptr < x.ptr; }\n    };\n\n    class reverse_iterator\n    {\n        T *ptr;\n\n      public:\n        typedef Diff difference_type;\n        typedef T value_type;\n        typedef T *pointer;\n        typedef T &reference;\n        typedef std::bidirectional_iterator_tag iterator_category;\n        reverse_iterator(T *ptr_) : ptr(ptr_) {}\n        T &operator*() { return *ptr; }\n        const T &operator*() const { return *ptr; }\n        T *operator->() { return ptr; }\n        const T *operator->() const { return ptr; }\n        reverse_iterator &operator--()\n        {\n            ptr++;\n            return *this;\n        }\n        reverse_iterator &operator++()\n        {\n            ptr--;\n            return *this;\n        }\n        reverse_iterator operator++(int)\n        {\n            reverse_iterator copy(*this);\n            ++(*this);\n            return copy;\n        }\n        reverse_iterator operator--(int)\n        {\n            reverse_iterator copy(*this);\n            --(*this);\n            return copy;\n        }\n        bool operator==(reverse_iterator x) const { return ptr == x.ptr; }\n        bool operator!=(reverse_iterator x) const { return ptr != x.ptr; }\n    };\n\n    class const_iterator\n    {\n        const T *ptr;\n\n      public:\n        typedef Diff difference_type;\n        typedef const T value_type;\n        typedef const T *pointer;\n        typedef const T &reference;\n        typedef std::random_access_iterator_tag iterator_category;\n        const_iterator(const T *ptr_) : ptr(ptr_) {}\n        const_iterator(iterator x) : ptr(&(*x)) {}\n        const T &operator*() const { return *ptr; }\n        const T *operator->() const { return ptr; }\n        const T &operator[](size_type pos) const { return ptr[pos]; }\n        const_iterator &operator++()\n        {\n            ptr++;\n            return *this;\n        }\n        const_iterator &operator--()\n        {\n            ptr--;\n            return *this;\n        }\n        const_iterator operator++(int)\n        {\n            const_iterator copy(*this);\n            ++(*this);\n            return copy;\n        }\n        const_iterator operator--(int)\n        {\n            const_iterator copy(*this);\n            --(*this);\n            return copy;\n        }\n        difference_type friend operator-(const_iterator a, const_iterator b) { return (&(*a) - &(*b)); }\n        const_iterator operator+(size_type n) { return const_iterator(ptr + n); }\n        const_iterator &operator+=(size_type n)\n        {\n            ptr += n;\n            return *this;\n        }\n        const_iterator operator-(size_type n) { return const_iterator(ptr - n); }\n        const_iterator &operator-=(size_type n)\n        {\n            ptr -= n;\n            return *this;\n        }\n        bool operator==(const_iterator x) const { return ptr == x.ptr; }\n        bool operator!=(const_iterator x) const { return ptr != x.ptr; }\n        bool operator>=(const_iterator x) const { return ptr >= x.ptr; }\n        bool operator<=(const_iterator x) const { return ptr <= x.ptr; }\n        bool operator>(const_iterator x) const { return ptr > x.ptr; }\n        bool operator<(const_iterator x) const { return ptr < x.ptr; }\n    };\n\n    class const_reverse_iterator\n    {\n        const T *ptr;\n\n      public:\n        typedef Diff difference_type;\n        typedef const T value_type;\n        typedef const T *pointer;\n        typedef const T &reference;\n        typedef std::bidirectional_iterator_tag iterator_category;\n        const_reverse_iterator(T *ptr_) : ptr(ptr_) {}\n        const_reverse_iterator(reverse_iterator x) : ptr(&(*x)) {}\n        const T &operator*() const { return *ptr; }\n        const T *operator->() const { return ptr; }\n        const_reverse_iterator &operator--()\n        {\n            ptr++;\n            return *this;\n        }\n        const_reverse_iterator &operator++()\n        {\n            ptr--;\n            return *this;\n        }\n        const_reverse_iterator operator++(int)\n        {\n            const_reverse_iterator copy(*this);\n            ++(*this);\n            return copy;\n        }\n        const_reverse_iterator operator--(int)\n        {\n            const_reverse_iterator copy(*this);\n            --(*this);\n            return copy;\n        }\n        bool operator==(const_reverse_iterator x) const { return ptr == x.ptr; }\n        bool operator!=(const_reverse_iterator x) const { return ptr != x.ptr; }\n    };\n\n  private:\n    size_type _size;\n    union direct_or_indirect {\n        char direct[sizeof(T) * N];\n        struct\n        {\n            size_type capacity;\n            char *indirect;\n        };\n    } _union;\n\n    T *direct_ptr(difference_type pos) { return reinterpret_cast<T *>(_union.direct) + pos; }\n    const T *direct_ptr(difference_type pos) const { return reinterpret_cast<const T *>(_union.direct) + pos; }\n    T *indirect_ptr(difference_type pos) { return reinterpret_cast<T *>(_union.indirect) + pos; }\n    const T *indirect_ptr(difference_type pos) const { return reinterpret_cast<const T *>(_union.indirect) + pos; }\n    bool is_direct() const { return _size <= N; }\n\n    void change_capacity(size_type new_capacity)\n    {\n        if (new_capacity <= N)\n        {\n            if (!is_direct())\n            {\n                T *indirect = indirect_ptr(0);\n                T *src = indirect;\n                T *dst = direct_ptr(0);\n                memcpy(dst, src, size() * sizeof(T));\n                free(indirect);\n                _size -= N + 1;\n            }\n        }\n        else\n        {\n            if (!is_direct())\n            {\n                _union.indirect = static_cast<char *>(realloc(_union.indirect, ((size_t)sizeof(T)) * new_capacity));\n                _union.capacity = new_capacity;\n            }\n            else\n            {\n                char *new_indirect = static_cast<char *>(malloc(((size_t)sizeof(T)) * new_capacity));\n                T *src = direct_ptr(0);\n                T *dst = reinterpret_cast<T *>(new_indirect);\n                memcpy(dst, src, size() * sizeof(T));\n                _union.indirect = new_indirect;\n                _union.capacity = new_capacity;\n                _size += N + 1;\n            }\n        }\n    }\n\n    T *item_ptr(difference_type pos) { return is_direct() ? direct_ptr(pos) : indirect_ptr(pos); }\n    const T *item_ptr(difference_type pos) const { return is_direct() ? direct_ptr(pos) : indirect_ptr(pos); }\n\n  public:\n    void assign(size_type n, const T &val)\n    {\n        clear();\n        if (capacity() < n)\n        {\n            change_capacity(n);\n        }\n        while (size() < n)\n        {\n            _size++;\n            new (static_cast<void *>(item_ptr(size() - 1))) T(val);\n        }\n    }\n\n    template <typename InputIterator>\n    void assign(InputIterator first, InputIterator last)\n    {\n        size_type n = last - first;\n        clear();\n        if (capacity() < n)\n        {\n            change_capacity(n);\n        }\n        while (first != last)\n        {\n            _size++;\n            new (static_cast<void *>(item_ptr(size() - 1))) T(*first);\n            ++first;\n        }\n    }\n\n    prevector() : _size(0) {}\n\n    explicit prevector(size_type n) : _size(0)\n    {\n        resize(n);\n    }\n\n    explicit prevector(size_type n, const T &val = T()) : _size(0)\n    {\n        change_capacity(n);\n        while (size() < n)\n        {\n            _size++;\n            new (static_cast<void *>(item_ptr(size() - 1))) T(val);\n        }\n    }\n\n    template <typename InputIterator>\n    prevector(InputIterator first, InputIterator last) : _size(0)\n    {\n        size_type n = last - first;\n        change_capacity(n);\n        while (first != last)\n        {\n            _size++;\n            new (static_cast<void *>(item_ptr(size() - 1))) T(*first);\n            ++first;\n        }\n    }\n\n    prevector(const prevector<N, T, Size, Diff> &other) : _size(0)\n    {\n        change_capacity(other.size());\n        const_iterator it = other.begin();\n        while (it != other.end())\n        {\n            _size++;\n            new (static_cast<void *>(item_ptr(size() - 1))) T(*it);\n            ++it;\n        }\n    }\n\n    prevector &operator=(const prevector<N, T, Size, Diff> &other)\n    {\n        if (&other == this)\n        {\n            return *this;\n        }\n        resize(0);\n        change_capacity(other.size());\n        const_iterator it = other.begin();\n        while (it != other.end())\n        {\n            _size++;\n            new (static_cast<void *>(item_ptr(size() - 1))) T(*it);\n            ++it;\n        }\n        return *this;\n    }\n\n    size_type size() const\n    {\n        return is_direct() ? _size : _size - N - 1;\n    }\n\n    bool empty() const\n    {\n        return size() == 0;\n    }\n\n    iterator begin() { return iterator(item_ptr(0)); }\n    const_iterator begin() const { return const_iterator(item_ptr(0)); }\n    iterator end() { return iterator(item_ptr(size())); }\n    const_iterator end() const { return const_iterator(item_ptr(size())); }\n\n    reverse_iterator rbegin() { return reverse_iterator(item_ptr(size() - 1)); }\n    const_reverse_iterator rbegin() const { return const_reverse_iterator(item_ptr(size() - 1)); }\n    reverse_iterator rend() { return reverse_iterator(item_ptr(-1)); }\n    const_reverse_iterator rend() const { return const_reverse_iterator(item_ptr(-1)); }\n\n    size_t capacity() const\n    {\n        if (is_direct())\n        {\n            return N;\n        }\n        else\n        {\n            return _union.capacity;\n        }\n    }\n\n    T &operator[](size_type pos)\n    {\n        return *item_ptr(pos);\n    }\n\n    const T &operator[](size_type pos) const\n    {\n        return *item_ptr(pos);\n    }\n\n    void resize(size_type new_size)\n    {\n        while (size() > new_size)\n        {\n            item_ptr(size() - 1)->~T();\n            _size--;\n        }\n        if (new_size > capacity())\n        {\n            change_capacity(new_size);\n        }\n        while (size() < new_size)\n        {\n            _size++;\n            new (static_cast<void *>(item_ptr(size() - 1))) T();\n        }\n    }\n\n    void reserve(size_type new_capacity)\n    {\n        if (new_capacity > capacity())\n        {\n            change_capacity(new_capacity);\n        }\n    }\n\n    void shrink_to_fit()\n    {\n        change_capacity(size());\n    }\n\n    void clear()\n    {\n        resize(0);\n    }\n\n    iterator insert(iterator pos, const T &value)\n    {\n        size_type p = pos - begin();\n        size_type new_size = size() + 1;\n        if (capacity() < new_size)\n        {\n            change_capacity(new_size + (new_size >> 1));\n        }\n        memmove(item_ptr(p + 1), item_ptr(p), (size() - p) * sizeof(T));\n        _size++;\n        new (static_cast<void *>(item_ptr(p))) T(value);\n        return iterator(item_ptr(p));\n    }\n\n    void insert(iterator pos, size_type count, const T &value)\n    {\n        size_type p = pos - begin();\n        size_type new_size = size() + count;\n        if (capacity() < new_size)\n        {\n            change_capacity(new_size + (new_size >> 1));\n        }\n        memmove(item_ptr(p + count), item_ptr(p), (size() - p) * sizeof(T));\n        _size += count;\n        for (size_type i = 0; i < count; i++)\n        {\n            new (static_cast<void *>(item_ptr(p + i))) T(value);\n        }\n    }\n\n    template <typename InputIterator>\n    void insert(iterator pos, InputIterator first, InputIterator last)\n    {\n        size_type p = pos - begin();\n        difference_type count = last - first;\n        size_type new_size = size() + count;\n        if (capacity() < new_size)\n        {\n            change_capacity(new_size + (new_size >> 1));\n        }\n        memmove(item_ptr(p + count), item_ptr(p), (size() - p) * sizeof(T));\n        _size += count;\n        while (first != last)\n        {\n            new (static_cast<void *>(item_ptr(p))) T(*first);\n            ++p;\n            ++first;\n        }\n    }\n\n    iterator erase(iterator pos)\n    {\n        (*pos).~T();\n        memmove(&(*pos), &(*pos) + 1, ((char *)&(*end())) - ((char *)(1 + &(*pos))));\n        _size--;\n        return pos;\n    }\n\n    iterator erase(iterator first, iterator last)\n    {\n        iterator p = first;\n        char *endp = (char *)&(*end());\n        while (p != last)\n        {\n            (*p).~T();\n            _size--;\n            ++p;\n        }\n        memmove(&(*first), &(*last), endp - ((char *)(&(*last))));\n        return first;\n    }\n\n    void push_back(const T &value)\n    {\n        size_type new_size = size() + 1;\n        if (capacity() < new_size)\n        {\n            change_capacity(new_size + (new_size >> 1));\n        }\n        new (item_ptr(size())) T(value);\n        _size++;\n    }\n\n    void pop_back()\n    {\n        _size--;\n    }\n\n    T &front()\n    {\n        return *item_ptr(0);\n    }\n\n    const T &front() const\n    {\n        return *item_ptr(0);\n    }\n\n    T &back()\n    {\n        return *item_ptr(size() - 1);\n    }\n\n    const T &back() const\n    {\n        return *item_ptr(size() - 1);\n    }\n\n    void swap(prevector<N, T, Size, Diff> &other)\n    {\n        if (_size & other._size & 1)\n        {\n            std::swap(_union.capacity, other._union.capacity);\n            std::swap(_union.indirect, other._union.indirect);\n        }\n        else\n        {\n            std::swap(_union, other._union);\n        }\n        std::swap(_size, other._size);\n    }\n\n    ~prevector()\n    {\n        clear();\n        if (!is_direct())\n        {\n            free(_union.indirect);\n            _union.indirect = NULL;\n        }\n    }\n\n    bool operator==(const prevector<N, T, Size, Diff> &other) const\n    {\n        if (other.size() != size())\n        {\n            return false;\n        }\n        const_iterator b1 = begin();\n        const_iterator b2 = other.begin();\n        const_iterator e1 = end();\n        while (b1 != e1)\n        {\n            if ((*b1) != (*b2))\n            {\n                return false;\n            }\n            ++b1;\n            ++b2;\n        }\n        return true;\n    }\n\n    bool operator!=(const prevector<N, T, Size, Diff> &other) const\n    {\n        return !(*this == other);\n    }\n\n    bool operator<(const prevector<N, T, Size, Diff> &other) const\n    {\n        if (size() < other.size())\n        {\n            return true;\n        }\n        if (size() > other.size())\n        {\n            return false;\n        }\n        const_iterator b1 = begin();\n        const_iterator b2 = other.begin();\n        const_iterator e1 = end();\n        while (b1 != e1)\n        {\n            if ((*b1) < (*b2))\n            {\n                return true;\n            }\n            if ((*b2) < (*b1))\n            {\n                return false;\n            }\n            ++b1;\n            ++b2;\n        }\n        return false;\n    }\n\n    size_t allocated_memory() const\n    {\n        if (is_direct())\n        {\n            return 0;\n        }\n        else\n        {\n            return ((size_t)(sizeof(T))) * _union.capacity;\n        }\n    }\n};\n#pragma pack(pop)\n\n#endif\n"
  },
  {
    "path": "src/UChainService/consensus/clone/primitives/transaction.cpp",
    "content": "// Copyright (c) 2009-2010 Satoshi Nakamoto\n// Copyright (c) 2009-2015 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#include \"primitives/transaction.h\"\n\n#include \"hash.h\"\n#include \"tinyformat.h\"\n#include \"utilstrencodings.h\"\n\nstd::string COutPoint::ToString() const\n{\n    return strprintf(\"COutPoint(%s, %u)\", hash.ToString().substr(0, 10), n);\n}\n\nCTxIn::CTxIn(COutPoint prevoutIn, CScript scriptSigIn, uint32_t nSequenceIn)\n{\n    prevout = prevoutIn;\n    scriptSig = scriptSigIn;\n    nSequence = nSequenceIn;\n}\n\nCTxIn::CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn, uint32_t nSequenceIn)\n{\n    prevout = COutPoint(hashPrevTx, nOut);\n    scriptSig = scriptSigIn;\n    nSequence = nSequenceIn;\n}\n\nstd::string CTxIn::ToString() const\n{\n    std::string str;\n    str += \"CTxIn(\";\n    str += prevout.ToString();\n    if (prevout.IsNull())\n        str += strprintf(\", coinbase %s\", HexStr(scriptSig));\n    else\n        str += strprintf(\", scriptSig=%s\", HexStr(scriptSig).substr(0, 24));\n    if (nSequence != std::numeric_limits<unsigned int>::max())\n        str += strprintf(\", nSequence=%u\", nSequence);\n    str += \")\";\n    return str;\n}\n\nCTxOut::CTxOut(const CAmount &nValueIn, CScript scriptPubKeyIn)\n{\n    nValue = nValueIn;\n    scriptPubKey = scriptPubKeyIn;\n}\n\nuint256 CTxOut::GetHash() const\n{\n    return SerializeHash(*this);\n}\n\nstd::string CTxOut::ToString() const\n{\n    return strprintf(\"CTxOut(nValue=%d.%08d, scriptPubKey=%s)\", nValue / COIN, nValue % COIN, HexStr(scriptPubKey).substr(0, 30));\n}\n\nCMutableTransaction::CMutableTransaction() : nVersion(CTransaction::CURRENT_VERSION), nLockTime(0) {}\nCMutableTransaction::CMutableTransaction(const CTransaction &tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime) {}\n\nuint256 CMutableTransaction::GetHash() const\n{\n    return SerializeHash(*this);\n}\n\nvoid CTransaction::UpdateHash() const\n{\n    *const_cast<uint256 *>(&hash) = SerializeHash(*this);\n}\n\nCTransaction::CTransaction() : nVersion(CTransaction::CURRENT_VERSION), vin(), vout(), nLockTime(0) {}\n\nCTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime)\n{\n    UpdateHash();\n}\n\nCTransaction &CTransaction::operator=(const CTransaction &tx)\n{\n    *const_cast<int *>(&nVersion) = tx.nVersion;\n    *const_cast<std::vector<CTxIn> *>(&vin) = tx.vin;\n    *const_cast<std::vector<CTxOut> *>(&vout) = tx.vout;\n    *const_cast<unsigned int *>(&nLockTime) = tx.nLockTime;\n    *const_cast<uint256 *>(&hash) = tx.hash;\n    return *this;\n}\n\nCAmount CTransaction::GetValueOut() const\n{\n    CAmount nValueOut = 0;\n    for (std::vector<CTxOut>::const_iterator it(vout.begin()); it != vout.end(); ++it)\n    {\n        nValueOut += it->nValue;\n        if (!MoneyRange(it->nValue) || !MoneyRange(nValueOut))\n            throw std::runtime_error(\"CTransaction::GetValueOut(): value out of range\");\n    }\n    return nValueOut;\n}\n\ndouble CTransaction::ComputePriority(double dPriorityInputs, unsigned int nTxSize) const\n{\n    nTxSize = CalculateModifiedSize(nTxSize);\n    if (nTxSize == 0)\n        return 0.0;\n\n    return dPriorityInputs / nTxSize;\n}\n\nunsigned int CTransaction::CalculateModifiedSize(unsigned int nTxSize) const\n{\n    // In order to avoid disincentivizing cleaning up the UTXO set we don't count\n    // the constant overhead for each txin and up to 110 bytes of scriptSig (which\n    // is enough to cover a compressed pubkey p2sh redemption) for priority.\n    // Providing any more cleanup incentive than making additional inputs free would\n    // risk encouraging people to create junk outputs to redeem later.\n    if (nTxSize == 0)\n        nTxSize = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION);\n    for (std::vector<CTxIn>::const_iterator it(vin.begin()); it != vin.end(); ++it)\n    {\n        unsigned int offset = 41U + std::min(110U, (unsigned int)it->scriptSig.size());\n        if (nTxSize > offset)\n            nTxSize -= offset;\n    }\n    return nTxSize;\n}\n\nstd::string CTransaction::ToString() const\n{\n    std::string str;\n    str += strprintf(\"CTransaction(hash=%s, ver=%d, vin.size=%u, vout.size=%u, nLockTime=%u)\\n\",\n                     GetHash().ToString().substr(0, 10),\n                     nVersion,\n                     vin.size(),\n                     vout.size(),\n                     nLockTime);\n    for (unsigned int i = 0; i < vin.size(); i++)\n        str += \"    \" + vin[i].ToString() + \"\\n\";\n    for (unsigned int i = 0; i < vout.size(); i++)\n        str += \"    \" + vout[i].ToString() + \"\\n\";\n    return str;\n}\n"
  },
  {
    "path": "src/UChainService/consensus/clone/primitives/transaction.h",
    "content": "// Copyright (c) 2009-2010 Satoshi Nakamoto\n// Copyright (c) 2009-2015 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#ifndef BITCOIN_PRIMITIVES_TRANSACTION_H\n#define BITCOIN_PRIMITIVES_TRANSACTION_H\n\n#include \"amount.h\"\n#include \"script/script.h\"\n#include \"serialize.h\"\n#include \"uint256.h\"\n#include <UChainService/txs/asset.hpp>\n\n/** An outpoint - a combination of a transaction hash and an index n into its vout */\nclass COutPoint\n{\n  public:\n    uint256 hash;\n    uint32_t n;\n\n    COutPoint() { SetNull(); }\n    COutPoint(uint256 hashIn, uint32_t nIn)\n    {\n        hash = hashIn;\n        n = nIn;\n    }\n\n    ADD_SERIALIZE_METHODS;\n\n    template <typename Stream, typename Operation>\n    inline void SerializationOp(Stream &s, Operation ser_action, int nType, int nVersion)\n    {\n        READWRITE(hash);\n        READWRITE(n);\n    }\n\n    void SetNull()\n    {\n        hash.SetNull();\n        n = (uint32_t)-1;\n    }\n    bool IsNull() const { return (hash.IsNull() && n == (uint32_t)-1); }\n\n    friend bool operator<(const COutPoint &a, const COutPoint &b)\n    {\n        return (a.hash < b.hash || (a.hash == b.hash && a.n < b.n));\n    }\n\n    friend bool operator==(const COutPoint &a, const COutPoint &b)\n    {\n        return (a.hash == b.hash && a.n == b.n);\n    }\n\n    friend bool operator!=(const COutPoint &a, const COutPoint &b)\n    {\n        return !(a == b);\n    }\n\n    std::string ToString() const;\n};\n\n/** An input of a transaction.  It contains the location of the previous\n * transaction's output that it claims and a signature that matches the\n * output's public key.\n */\nclass CTxIn\n{\n  public:\n    COutPoint prevout;\n    CScript scriptSig;\n    uint32_t nSequence;\n\n    CTxIn()\n    {\n        nSequence = std::numeric_limits<unsigned int>::max();\n    }\n\n    explicit CTxIn(COutPoint prevoutIn, CScript scriptSigIn = CScript(), uint32_t nSequenceIn = std::numeric_limits<unsigned int>::max());\n    CTxIn(uint256 hashPrevTx, uint32_t nOut, CScript scriptSigIn = CScript(), uint32_t nSequenceIn = std::numeric_limits<uint32_t>::max());\n\n    ADD_SERIALIZE_METHODS;\n\n    template <typename Stream, typename Operation>\n    inline void SerializationOp(Stream &s, Operation ser_action, int nType, int nVersion)\n    {\n        READWRITE(prevout);\n        READWRITE(*(CScriptBase *)(&scriptSig));\n        READWRITE(nSequence);\n    }\n\n    bool IsFinal() const\n    {\n        return (nSequence == std::numeric_limits<uint32_t>::max());\n    }\n\n    friend bool operator==(const CTxIn &a, const CTxIn &b)\n    {\n        return (a.prevout == b.prevout &&\n                a.scriptSig == b.scriptSig &&\n                a.nSequence == b.nSequence);\n    }\n\n    friend bool operator!=(const CTxIn &a, const CTxIn &b)\n    {\n        return !(a == b);\n    }\n\n    std::string ToString() const;\n};\nclass CTokenDetail\n{\n  public:\n    std::string symbol;\n    uint64_t maximum_supply;\n    uint32_t token_type;\n    std::string issuer;\n    std::string address;\n    std::string description;\n\n    ADD_SERIALIZE_METHODS;\n\n    template <typename Stream, typename Operation>\n    inline void SerializationOp(Stream &s, Operation ser_action, int nType, int nVersion)\n    {\n        READWRITE(symbol);\n        READWRITE(maximum_supply);\n        READWRITE(token_type);\n        READWRITE(issuer);\n        READWRITE(address);\n        READWRITE(description);\n    }\n};\nclass CTokenTransfer\n{\n  public:\n    std::string address; // symbol  -- in block\n    uint64_t quantity;   // -- in block\n\n    ADD_SERIALIZE_METHODS;\n\n    template <typename Stream, typename Operation>\n    inline void SerializationOp(Stream &s, Operation ser_action, int nType, int nVersion)\n    {\n        READWRITE(address);\n        READWRITE(quantity);\n    }\n};\n\nclass CToken\n{\n  public:\n    uint32_t status;\n    CTokenDetail detail;\n    CTokenTransfer trans;\n\n    size_t GetSerializeSize(int nType, int nVersion) const\n    {\n        CSizeComputer s(nType, nVersion);\n        NCONST_PTR(this)->Serialize(s, nType, nVersion);\n        return s.size();\n    }\n    template <typename Stream>\n    void Serialize(Stream &s, int nType, int nVersion) const\n    {\n        //NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize(), nType, nVersion);\n        (::SerReadWrite(s, (status), nType, nVersion, CSerActionSerialize()));\n        switch (status)\n        {\n        case 1: // asset detail\n            (::SerReadWrite(s, (*(CTokenDetail *)(&detail)), nType, nVersion, CSerActionSerialize()));\n            break;\n        case 2: // asset transfer\n            (::SerReadWrite(s, (*(CTokenTransfer *)(&trans)), nType, nVersion, CSerActionSerialize()));\n            break;\n        };\n    }\n    template <typename Stream>\n    void Unserialize(Stream &s, int nType, int nVersion)\n    {\n        //SerializationOp(s, CSerActionUnserialize(), nType, nVersion);\n        (::SerReadWrite(s, (status), nType, nVersion, CSerActionUnserialize()));\n        switch (status)\n        {\n        case 1: // asset detail\n            (::SerReadWrite(s, (*(CTokenDetail *)(&detail)), nType, nVersion, CSerActionUnserialize()));\n            break;\n        case 2: // asset transfer\n            (::SerReadWrite(s, (*(CTokenTransfer *)(&trans)), nType, nVersion, CSerActionUnserialize()));\n            break;\n        };\n    }\n};\nclass CMessage\n{\n  public:\n    std::string content;\n\n    ADD_SERIALIZE_METHODS;\n\n    template <typename Stream, typename Operation>\n    inline void SerializationOp(Stream &s, Operation ser_action, int nType, int nVersion)\n    {\n        READWRITE(content);\n    }\n};\n\nclass CTokenCert\n{\n  public:\n    std::string symbol;\n    std::string owner;\n    std::string address;\n    uint32_t type;\n    uint8_t status;\n\n    ADD_SERIALIZE_METHODS;\n\n    template <typename Stream, typename Operation>\n    inline void SerializationOp(Stream &s, Operation ser_action, int nType, int nVersion)\n    {\n        READWRITE(symbol);\n        READWRITE(owner);\n        READWRITE(address);\n        READWRITE(type);\n        READWRITE(status);\n    }\n};\n\nclass CTokenCandidate\n{\n  public:\n    uint8_t status;\n    std::string symbol;\n    std::string address;\n    std::string content;\n\n    ADD_SERIALIZE_METHODS;\n\n    template <typename Stream, typename Operation>\n    inline void SerializationOp(Stream &s, Operation ser_action, int nType, int nVersion)\n    {\n        READWRITE(status);\n        READWRITE(symbol);\n        READWRITE(address);\n        if (status == CANDIDATE_STATUS_REGISTER)\n        {\n            READWRITE(content);\n        }\n    }\n};\n\nclass CUidDetail\n{\n  public:\n    std::string symbol;\n    std::string address;\n\n    ADD_SERIALIZE_METHODS;\n\n    template <typename Stream, typename Operation>\n    inline void SerializationOp(Stream &s, Operation ser_action, int nType, int nVersion)\n    {\n        READWRITE(symbol);\n        READWRITE(address);\n    }\n};\n\nclass CUidTransfer\n{\n  public:\n    std::string symbol;\n    std::string address;\n\n    ADD_SERIALIZE_METHODS;\n\n    template <typename Stream, typename Operation>\n    inline void SerializationOp(Stream &s, Operation ser_action, int nType, int nVersion)\n    {\n        READWRITE(symbol);\n        READWRITE(address);\n    }\n};\n\nclass CUid\n{\n  public:\n    uint32_t status;\n    CUidDetail detail;\n    CUidTransfer trans;\n\n    size_t GetSerializeSize(int nType, int nVersion) const\n    {\n        CSizeComputer s(nType, nVersion);\n        NCONST_PTR(this)->Serialize(s, nType, nVersion);\n        return s.size();\n    }\n    template <typename Stream>\n    void Serialize(Stream &s, int nType, int nVersion) const\n    {\n        //NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize(), nType, nVersion);\n        (::SerReadWrite(s, (status), nType, nVersion, CSerActionSerialize()));\n        switch (status)\n        {\n        case 1: // uid detail\n            (::SerReadWrite(s, (*(CUidDetail *)(&detail)), nType, nVersion, CSerActionSerialize()));\n            break;\n        case 2: // uid transfer\n            (::SerReadWrite(s, (*(CUidTransfer *)(&trans)), nType, nVersion, CSerActionSerialize()));\n            break;\n        };\n    }\n    template <typename Stream>\n    void Unserialize(Stream &s, int nType, int nVersion)\n    {\n        //SerializationOp(s, CSerActionUnserialize(), nType, nVersion);\n        (::SerReadWrite(s, (status), nType, nVersion, CSerActionUnserialize()));\n        switch (status)\n        {\n        case 1: // uid detail\n            (::SerReadWrite(s, (*(CUidDetail *)(&detail)), nType, nVersion, CSerActionUnserialize()));\n            break;\n        case 2: // uid transfer\n            (::SerReadWrite(s, (*(CUidTransfer *)(&trans)), nType, nVersion, CSerActionUnserialize()));\n            break;\n        };\n    }\n};\n/** An output of a transaction.  It contains the public key that the next input\n * must be able to sign with to claim it.\n */\nclass CTxOut\n{\n  public:\n    CAmount nValue;\n    CScript scriptPubKey;\n    // add for asset\n    uint32_t version;\n    uint32_t type;\n    std::string fromuid;\n    std::string touid;\n\n    CToken asset;\n    CTokenCert assetcert;\n    CTokenCandidate mit;\n    CUid uid;\n    CMessage message;\n\n    CTxOut()\n    {\n        SetNull();\n    }\n\n    CTxOut(const CAmount &nValueIn, CScript scriptPubKeyIn);\n\n    //ADD_SERIALIZE_METHODS;\n    size_t GetSerializeSize(int nType, int nVersion) const\n    {\n        CSizeComputer s(nType, nVersion);\n        NCONST_PTR(this)->Serialize(s, nType, nVersion);\n        return s.size();\n    }\n    template <typename Stream>\n    void Serialize(Stream &s, int nType, int nVersion) const\n    {\n        //NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize(), nType, nVersion);\n        (::SerReadWrite(s, (nValue), nType, nVersion, CSerActionSerialize()));\n        (::SerReadWrite(s, (*(CScriptBase *)(&scriptPubKey)), nType, nVersion, CSerActionSerialize()));\n        (::SerReadWrite(s, (version), nType, nVersion, CSerActionSerialize()));\n        (::SerReadWrite(s, (type), nType, nVersion, CSerActionSerialize()));\n        if (version == UID_ASSET_VERIFY_VERSION)\n        {\n            (::SerReadWrite(s, (fromuid), nType, nVersion, CSerActionSerialize()));\n            (::SerReadWrite(s, (touid), nType, nVersion, CSerActionSerialize()));\n        }\n\n        switch (type)\n        {\n        case 0: // ucn\n        case 1: // ucn award\n            // not data left\n            break;\n        case 2: // asset\n            (::SerReadWrite(s, (*(CToken *)(&asset)), nType, nVersion, CSerActionSerialize()));\n            break;\n        case 3: // message\n            (::SerReadWrite(s, (*(CMessage *)(&message)), nType, nVersion, CSerActionSerialize()));\n            break;\n        case 4: //uid\n            (::SerReadWrite(s, (*(CUid *)(&uid)), nType, nVersion, CSerActionSerialize()));\n            break;\n        case 5: // asset cert\n            (::SerReadWrite(s, (*(CTokenCert *)(&assetcert)), nType, nVersion, CSerActionSerialize()));\n            break;\n        case 6: // mit\n            (::SerReadWrite(s, (*(CTokenCandidate *)(&mit)), nType, nVersion, CSerActionSerialize()));\n            break;\n        };\n    }\n    template <typename Stream>\n    void Unserialize(Stream &s, int nType, int nVersion)\n    {\n        //SerializationOp(s, CSerActionUnserialize(), nType, nVersion);\n        (::SerReadWrite(s, (nValue), nType, nVersion, CSerActionUnserialize()));\n        (::SerReadWrite(s, (*(CScriptBase *)(&scriptPubKey)), nType, nVersion, CSerActionUnserialize()));\n        (::SerReadWrite(s, (version), nType, nVersion, CSerActionUnserialize()));\n        (::SerReadWrite(s, (type), nType, nVersion, CSerActionUnserialize()));\n        if (version == UID_ASSET_VERIFY_VERSION)\n        {\n            (::SerReadWrite(s, (fromuid), nType, nVersion, CSerActionUnserialize()));\n            (::SerReadWrite(s, (touid), nType, nVersion, CSerActionUnserialize()));\n        }\n        switch (type)\n        {\n        case 0: // ucn\n        case 1: // ucn award\n            // not data left\n            break;\n        case 2: // asset\n            (::SerReadWrite(s, (*(CToken *)(&asset)), nType, nVersion, CSerActionUnserialize()));\n            break;\n        case 3: // message\n            (::SerReadWrite(s, (*(CMessage *)(&message)), nType, nVersion, CSerActionUnserialize()));\n            break;\n        case 4: // uid\n            (::SerReadWrite(s, (*(CUid *)(&uid)), nType, nVersion, CSerActionUnserialize()));\n            break;\n        case 5: // asset cert\n            (::SerReadWrite(s, (*(CTokenCert *)(&assetcert)), nType, nVersion, CSerActionUnserialize()));\n            break;\n        case 6: // mit\n            (::SerReadWrite(s, (*(CTokenCandidate *)(&mit)), nType, nVersion, CSerActionUnserialize()));\n            break;\n        };\n    }\n\n    void SetNull()\n    {\n        nValue = -1;\n        scriptPubKey.clear();\n    }\n\n    bool IsNull() const\n    {\n        return (nValue == -1);\n    }\n\n    uint256 GetHash() const;\n\n    CAmount GetDustThreshold(const CFeeRate &minRelayTxFee) const\n    {\n        // \"Dust\" is defined in terms of CTransaction::minRelayTxFee,\n        // which has units satoshis-per-kilobyte.\n        // If you'd pay more than 1/3 in fees\n        // to spend something, then we consider it dust.\n        // A typical spendable txout is 34 bytes big, and will\n        // need a CTxIn of at least 148 bytes to spend:\n        // so dust is a spendable txout less than\n        // 546*minRelayTxFee/1000 (in satoshis)\n        if (scriptPubKey.IsUnspendable())\n            return 0;\n\n        size_t nSize = GetSerializeSize(SER_DISK, 0) + 148u;\n        return 3 * minRelayTxFee.GetFee(nSize);\n    }\n\n    bool IsDust(const CFeeRate &minRelayTxFee) const\n    {\n        return (nValue < GetDustThreshold(minRelayTxFee));\n    }\n\n    friend bool operator==(const CTxOut &a, const CTxOut &b)\n    {\n        return (a.nValue == b.nValue &&\n                a.scriptPubKey == b.scriptPubKey);\n    }\n\n    friend bool operator!=(const CTxOut &a, const CTxOut &b)\n    {\n        return !(a == b);\n    }\n\n    std::string ToString() const;\n};\n#if 0 // old CTxOut\nclass CTxOut\n{\npublic:\n    CAmount nValue;\n    CScript scriptPubKey;\n\n    CTxOut()\n    {\n        SetNull();\n    }\n\n    CTxOut(const CAmount& nValueIn, CScript scriptPubKeyIn);\n\n    ADD_SERIALIZE_METHODS;\n\n    template <typename Stream, typename Operation>\n    inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {\n        READWRITE(nValue);\n        READWRITE(*(CScriptBase*)(&scriptPubKey));\n    }\n\n    void SetNull()\n    {\n        nValue = -1;\n        scriptPubKey.clear();\n    }\n\n    bool IsNull() const\n    {\n        return (nValue == -1);\n    }\n\n    uint256 GetHash() const;\n\n    CAmount GetDustThreshold(const CFeeRate &minRelayTxFee) const\n    {\n        // \"Dust\" is defined in terms of CTransaction::minRelayTxFee,\n        // which has units satoshis-per-kilobyte.\n        // If you'd pay more than 1/3 in fees\n        // to spend something, then we consider it dust.\n        // A typical spendable txout is 34 bytes big, and will\n        // need a CTxIn of at least 148 bytes to spend:\n        // so dust is a spendable txout less than\n        // 546*minRelayTxFee/1000 (in satoshis)\n        if (scriptPubKey.IsUnspendable())\n            return 0;\n\n        size_t nSize = GetSerializeSize(SER_DISK,0)+148u;\n        return 3*minRelayTxFee.GetFee(nSize);\n    }\n\n    bool IsDust(const CFeeRate &minRelayTxFee) const\n    {\n        return (nValue < GetDustThreshold(minRelayTxFee));\n    }\n\n    friend bool operator==(const CTxOut& a, const CTxOut& b)\n    {\n        return (a.nValue       == b.nValue &&\n                a.scriptPubKey == b.scriptPubKey);\n    }\n\n    friend bool operator!=(const CTxOut& a, const CTxOut& b)\n    {\n        return !(a == b);\n    }\n\n    std::string ToString() const;\n};\n#endif\nstruct CMutableTransaction;\n\n/** The basic transaction that is broadcasted on the network and contained in\n * blocks.  A transaction can contain multiple inputs and outputs.\n */\nclass CTransaction\n{\n  private:\n    /** Memory only. */\n    const uint256 hash;\n    void UpdateHash() const;\n\n  public:\n    static const int32_t CURRENT_VERSION = 1;\n\n    // The local variables are made const to prevent unintended modification\n    // without updating the cached hash value. However, CTransaction is not\n    // actually immutable; deserialization and assignment are implemented,\n    // and bypass the constness. This is safe, as they update the entire\n    // structure, including the hash.\n    const int32_t nVersion;\n    const std::vector<CTxIn> vin;\n    const std::vector<CTxOut> vout;\n    const uint32_t nLockTime;\n\n    /** Construct a CTransaction that qualifies as IsNull() */\n    CTransaction();\n\n    /** Convert a CMutableTransaction into a CTransaction. */\n    CTransaction(const CMutableTransaction &tx);\n\n    CTransaction &operator=(const CTransaction &tx);\n\n    ADD_SERIALIZE_METHODS;\n\n    template <typename Stream, typename Operation>\n    inline void SerializationOp(Stream &s, Operation ser_action, int nType, int nVersion)\n    {\n        READWRITE(*const_cast<int32_t *>(&this->nVersion));\n        nVersion = this->nVersion;\n        READWRITE(*const_cast<std::vector<CTxIn> *>(&vin));\n        READWRITE(*const_cast<std::vector<CTxOut> *>(&vout));\n        READWRITE(*const_cast<uint32_t *>(&nLockTime));\n        if (ser_action.ForRead())\n            UpdateHash();\n    }\n\n    bool IsNull() const\n    {\n        return vin.empty() && vout.empty();\n    }\n\n    const uint256 &GetHash() const\n    {\n        return hash;\n    }\n\n    // Return sum of txouts.\n    CAmount GetValueOut() const;\n    // GetValueIn() is a method on CCoinsViewCache, because\n    // inputs must be known to compute value in.\n\n    // Compute priority, given priority of inputs and (optionally) tx size\n    double ComputePriority(double dPriorityInputs, unsigned int nTxSize = 0) const;\n\n    // Compute modified tx size for priority calculation (optionally given tx size)\n    unsigned int CalculateModifiedSize(unsigned int nTxSize = 0) const;\n\n    bool IsCoinBase() const\n    {\n        return (vin.size() == 1 && vin[0].prevout.IsNull());\n    }\n\n    friend bool operator==(const CTransaction &a, const CTransaction &b)\n    {\n        return a.hash == b.hash;\n    }\n\n    friend bool operator!=(const CTransaction &a, const CTransaction &b)\n    {\n        return a.hash != b.hash;\n    }\n\n    std::string ToString() const;\n};\n\n/** A mutable version of CTransaction. */\nstruct CMutableTransaction\n{\n    int32_t nVersion;\n    std::vector<CTxIn> vin;\n    std::vector<CTxOut> vout;\n    uint32_t nLockTime;\n\n    CMutableTransaction();\n    CMutableTransaction(const CTransaction &tx);\n\n    ADD_SERIALIZE_METHODS;\n\n    template <typename Stream, typename Operation>\n    inline void SerializationOp(Stream &s, Operation ser_action, int nType, int nVersion)\n    {\n        READWRITE(this->nVersion);\n        nVersion = this->nVersion;\n        READWRITE(vin);\n        READWRITE(vout);\n        READWRITE(nLockTime);\n    }\n\n    /** Compute the hash of this CMutableTransaction. This is computed on the\n     * fly, as opposed to GetHash() in CTransaction, which uses a cached result.\n     */\n    uint256 GetHash() const;\n};\n\n#endif // BITCOIN_PRIMITIVES_TRANSACTION_H\n"
  },
  {
    "path": "src/UChainService/consensus/clone/pubkey.cpp",
    "content": "// Copyright (c) 2009-2015 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#include \"pubkey.h\"\n\n#include <secp256k1.h>\n#include <secp256k1_recovery.h>\n\nnamespace\n{\n/* Global secp256k1_context object used for verification. */\nsecp256k1_context *secp256k1_context_verify = NULL;\n} // namespace\n\n/** This function is taken from the libsecp256k1 distribution and implements\n *  DER parsing for ECDSA signatures, while supporting an arbitrary subset of\n *  format violations.\n *\n *  Supported violations include negative integers, excessive padding, garbage\n *  at the end, and overly long length descriptors. This is safe to use in\n *  Bitcoin because since the activation of BIP66, signatures are verified to be\n *  strict DER before being passed to this module, and we know it supports all\n *  violations present in the blockchain before that point.\n */\nstatic int ecdsa_signature_parse_der_lax(const secp256k1_context *ctx, secp256k1_ecdsa_signature *sig, const unsigned char *input, size_t inputlen)\n{\n    size_t rpos, rlen, spos, slen;\n    size_t pos = 0;\n    size_t lenbyte;\n    unsigned char tmpsig[64] = {0};\n    int overflow = 0;\n\n    /* Hack to initialize sig with a correctly-parsed but invalid signature. */\n    secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);\n\n    /* Sequence tag byte */\n    if (pos == inputlen || input[pos] != 0x30)\n    {\n        return 0;\n    }\n    pos++;\n\n    /* Sequence length bytes */\n    if (pos == inputlen)\n    {\n        return 0;\n    }\n    lenbyte = input[pos++];\n    if (lenbyte & 0x80)\n    {\n        lenbyte -= 0x80;\n        if (pos + lenbyte > inputlen)\n        {\n            return 0;\n        }\n        pos += lenbyte;\n    }\n\n    /* Integer tag byte for R */\n    if (pos == inputlen || input[pos] != 0x02)\n    {\n        return 0;\n    }\n    pos++;\n\n    /* Integer length for R */\n    if (pos == inputlen)\n    {\n        return 0;\n    }\n    lenbyte = input[pos++];\n    if (lenbyte & 0x80)\n    {\n        lenbyte -= 0x80;\n        if (pos + lenbyte > inputlen)\n        {\n            return 0;\n        }\n        while (lenbyte > 0 && input[pos] == 0)\n        {\n            pos++;\n            lenbyte--;\n        }\n        if (lenbyte >= sizeof(size_t))\n        {\n            return 0;\n        }\n        rlen = 0;\n        while (lenbyte > 0)\n        {\n            rlen = (rlen << 8) + input[pos];\n            pos++;\n            lenbyte--;\n        }\n    }\n    else\n    {\n        rlen = lenbyte;\n    }\n    if (rlen > inputlen - pos)\n    {\n        return 0;\n    }\n    rpos = pos;\n    pos += rlen;\n\n    /* Integer tag byte for S */\n    if (pos == inputlen || input[pos] != 0x02)\n    {\n        return 0;\n    }\n    pos++;\n\n    /* Integer length for S */\n    if (pos == inputlen)\n    {\n        return 0;\n    }\n    lenbyte = input[pos++];\n    if (lenbyte & 0x80)\n    {\n        lenbyte -= 0x80;\n        if (pos + lenbyte > inputlen)\n        {\n            return 0;\n        }\n        while (lenbyte > 0 && input[pos] == 0)\n        {\n            pos++;\n            lenbyte--;\n        }\n        if (lenbyte >= sizeof(size_t))\n        {\n            return 0;\n        }\n        slen = 0;\n        while (lenbyte > 0)\n        {\n            slen = (slen << 8) + input[pos];\n            pos++;\n            lenbyte--;\n        }\n    }\n    else\n    {\n        slen = lenbyte;\n    }\n    if (slen > inputlen - pos)\n    {\n        return 0;\n    }\n    spos = pos;\n    pos += slen;\n\n    /* Ignore leading zeroes in R */\n    while (rlen > 0 && input[rpos] == 0)\n    {\n        rlen--;\n        rpos++;\n    }\n    /* Copy R value */\n    if (rlen > 32)\n    {\n        overflow = 1;\n    }\n    else\n    {\n        memcpy(tmpsig + 32 - rlen, input + rpos, rlen);\n    }\n\n    /* Ignore leading zeroes in S */\n    while (slen > 0 && input[spos] == 0)\n    {\n        slen--;\n        spos++;\n    }\n    /* Copy S value */\n    if (slen > 32)\n    {\n        overflow = 1;\n    }\n    else\n    {\n        memcpy(tmpsig + 64 - slen, input + spos, slen);\n    }\n\n    if (!overflow)\n    {\n        overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);\n    }\n    if (overflow)\n    {\n        /* Overwrite the result again with a correctly-parsed but invalid\n           signature if parsing failed. */\n        memset(tmpsig, 0, 64);\n        secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);\n    }\n    return 1;\n}\n\nbool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char> &vchSig) const\n{\n    if (!IsValid())\n        return false;\n    secp256k1_pubkey pubkey;\n    secp256k1_ecdsa_signature sig;\n    if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, &(*this)[0], size()))\n    {\n        return false;\n    }\n    if (vchSig.size() == 0)\n    {\n        return false;\n    }\n    if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, &vchSig[0], vchSig.size()))\n    {\n        return false;\n    }\n    /* libsecp256k1's ECDSA verification requires lower-S signatures, which have\n     * not historically been enforced in Bitcoin, so normalize them first. */\n    secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, &sig, &sig);\n    return secp256k1_ecdsa_verify(secp256k1_context_verify, &sig, hash.begin(), &pubkey);\n}\n\nbool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned char> &vchSig)\n{\n    if (vchSig.size() != 65)\n        return false;\n    int recid = (vchSig[0] - 27) & 3;\n    bool fComp = ((vchSig[0] - 27) & 4) != 0;\n    secp256k1_pubkey pubkey;\n    secp256k1_ecdsa_recoverable_signature sig;\n    if (!secp256k1_ecdsa_recoverable_signature_parse_compact(secp256k1_context_verify, &sig, &vchSig[1], recid))\n    {\n        return false;\n    }\n    if (!secp256k1_ecdsa_recover(secp256k1_context_verify, &pubkey, &sig, hash.begin()))\n    {\n        return false;\n    }\n    unsigned char pub[65];\n    size_t publen = 65;\n    secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, fComp ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);\n    Set(pub, pub + publen);\n    return true;\n}\n\nbool CPubKey::IsFullyValid() const\n{\n    if (!IsValid())\n        return false;\n    secp256k1_pubkey pubkey;\n    return secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, &(*this)[0], size());\n}\n\nbool CPubKey::Decompress()\n{\n    if (!IsValid())\n        return false;\n    secp256k1_pubkey pubkey;\n    if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, &(*this)[0], size()))\n    {\n        return false;\n    }\n    unsigned char pub[65];\n    size_t publen = 65;\n    secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, SECP256K1_EC_UNCOMPRESSED);\n    Set(pub, pub + publen);\n    return true;\n}\n\nbool CPubKey::Derive(CPubKey &pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode &cc) const\n{\n    assert(IsValid());\n    assert((nChild >> 31) == 0);\n    assert(begin() + 33 == end());\n    unsigned char out[64];\n    BIP32Hash(cc, nChild, *begin(), begin() + 1, out);\n    memcpy(ccChild.begin(), out + 32, 32);\n    secp256k1_pubkey pubkey;\n    if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, &(*this)[0], size()))\n    {\n        return false;\n    }\n    if (!secp256k1_ec_pubkey_tweak_add(secp256k1_context_verify, &pubkey, out))\n    {\n        return false;\n    }\n    unsigned char pub[33];\n    size_t publen = 33;\n    secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, SECP256K1_EC_COMPRESSED);\n    pubkeyChild.Set(pub, pub + publen);\n    return true;\n}\n\nvoid CExtPubKey::Encode(unsigned char code[74]) const\n{\n    code[0] = nDepth;\n    memcpy(code + 1, vchFingerprint, 4);\n    code[5] = (nChild >> 24) & 0xFF;\n    code[6] = (nChild >> 16) & 0xFF;\n    code[7] = (nChild >> 8) & 0xFF;\n    code[8] = (nChild >> 0) & 0xFF;\n    memcpy(code + 9, chaincode.begin(), 32);\n    assert(pubkey.size() == 33);\n    memcpy(code + 41, pubkey.begin(), 33);\n}\n\nvoid CExtPubKey::Decode(const unsigned char code[74])\n{\n    nDepth = code[0];\n    memcpy(vchFingerprint, code + 1, 4);\n    nChild = (code[5] << 24) | (code[6] << 16) | (code[7] << 8) | code[8];\n    memcpy(chaincode.begin(), code + 9, 32);\n    pubkey.Set(code + 41, code + 74);\n}\n\nbool CExtPubKey::Derive(CExtPubKey &out, unsigned int nChild) const\n{\n    out.nDepth = nDepth + 1;\n    CKeyID id = pubkey.GetID();\n    memcpy(&out.vchFingerprint[0], &id, 4);\n    out.nChild = nChild;\n    return pubkey.Derive(out.pubkey, out.chaincode, nChild, chaincode);\n}\n\n/* static */ bool CPubKey::CheckLowS(const std::vector<unsigned char> &vchSig)\n{\n    secp256k1_ecdsa_signature sig;\n    if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, &vchSig[0], vchSig.size()))\n    {\n        return false;\n    }\n    return (!secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, NULL, &sig));\n}\n\n/* static */ int ECCVerifyHandle::refcount = 0;\n\nECCVerifyHandle::ECCVerifyHandle()\n{\n    if (refcount == 0)\n    {\n        assert(secp256k1_context_verify == NULL);\n        secp256k1_context_verify = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);\n        assert(secp256k1_context_verify != NULL);\n    }\n    refcount++;\n}\n\nECCVerifyHandle::~ECCVerifyHandle()\n{\n    refcount--;\n    if (refcount == 0)\n    {\n        assert(secp256k1_context_verify != NULL);\n        secp256k1_context_destroy(secp256k1_context_verify);\n        secp256k1_context_verify = NULL;\n    }\n}\n"
  },
  {
    "path": "src/UChainService/consensus/clone/pubkey.h",
    "content": "// Copyright (c) 2009-2010 Satoshi Nakamoto\n// Copyright (c) 2009-2015 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#ifndef BITCOIN_PUBKEY_H\n#define BITCOIN_PUBKEY_H\n\n#include \"hash.h\"\n#include \"serialize.h\"\n#include \"uint256.h\"\n\n#include <stdexcept>\n#include <vector>\n\n/**\n * secp256k1:\n * const unsigned int PRIVATE_KEY_SIZE = 279;\n * const unsigned int PUBLIC_KEY_SIZE  = 65;\n * const unsigned int SIGNATURE_SIZE   = 72;\n *\n * see www.keylength.com\n * script supports up to 75 for single byte push\n */\n\n/** A reference to a CKey: the Hash160 of its serialized public key */\nclass CKeyID : public uint160\n{\n  public:\n    CKeyID() : uint160() {}\n    CKeyID(const uint160 &in) : uint160(in) {}\n};\n\ntypedef uint256 ChainCode;\n\n/** An encapsulated public key. */\nclass CPubKey\n{\n  private:\n    /**\n     * Just store the serialized data.\n     * Its length can very cheaply be computed from the first byte.\n     */\n    unsigned char vch[65];\n\n    //! Compute the length of a pubkey with a given first byte.\n    unsigned int static GetLen(unsigned char chHeader)\n    {\n        if (chHeader == 2 || chHeader == 3)\n            return 33;\n        if (chHeader == 4 || chHeader == 6 || chHeader == 7)\n            return 65;\n        return 0;\n    }\n\n    //! Set this key data to be invalid\n    void Invalidate()\n    {\n        vch[0] = 0xFF;\n    }\n\n  public:\n    //! Construct an invalid public key.\n    CPubKey()\n    {\n        Invalidate();\n    }\n\n    //! Initialize a public key using begin/end iterators to byte data.\n    template <typename T>\n    void Set(const T pbegin, const T pend)\n    {\n        int len = pend == pbegin ? 0 : GetLen(pbegin[0]);\n        if (len && len == (pend - pbegin))\n            memcpy(vch, (unsigned char *)&pbegin[0], len);\n        else\n            Invalidate();\n    }\n\n    //! Construct a public key using begin/end iterators to byte data.\n    template <typename T>\n    CPubKey(const T pbegin, const T pend)\n    {\n        Set(pbegin, pend);\n    }\n\n    //! Construct a public key from a byte vector.\n    CPubKey(const std::vector<unsigned char> &vch)\n    {\n        Set(vch.begin(), vch.end());\n    }\n\n    //! Simple read-only vector-like interface to the pubkey data.\n    unsigned int size() const { return GetLen(vch[0]); }\n    const unsigned char *begin() const { return vch; }\n    const unsigned char *end() const { return vch + size(); }\n    const unsigned char &operator[](unsigned int pos) const { return vch[pos]; }\n\n    //! Comparator implementation.\n    friend bool operator==(const CPubKey &a, const CPubKey &b)\n    {\n        return a.vch[0] == b.vch[0] &&\n               memcmp(a.vch, b.vch, a.size()) == 0;\n    }\n    friend bool operator!=(const CPubKey &a, const CPubKey &b)\n    {\n        return !(a == b);\n    }\n    friend bool operator<(const CPubKey &a, const CPubKey &b)\n    {\n        return a.vch[0] < b.vch[0] ||\n               (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) < 0);\n    }\n\n    //! Implement serialization, as if this was a byte vector.\n    unsigned int GetSerializeSize(int nType, int nVersion) const\n    {\n        return size() + 1;\n    }\n    template <typename Stream>\n    void Serialize(Stream &s, int nType, int nVersion) const\n    {\n        unsigned int len = size();\n        ::WriteCompactSize(s, len);\n        s.write((char *)vch, len);\n    }\n    template <typename Stream>\n    void Unserialize(Stream &s, int nType, int nVersion)\n    {\n        unsigned int len = ::ReadCompactSize(s);\n        if (len <= 65)\n        {\n            s.read((char *)vch, len);\n        }\n        else\n        {\n            // invalid pubkey, skip available data\n            char dummy;\n            while (len--)\n                s.read(&dummy, 1);\n            Invalidate();\n        }\n    }\n\n    //! Get the KeyID of this public key (hash of its serialization)\n    CKeyID GetID() const\n    {\n        return CKeyID(Hash160(vch, vch + size()));\n    }\n\n    //! Get the 256-bit hash of this public key.\n    uint256 GetHash() const\n    {\n        return Hash(vch, vch + size());\n    }\n\n    /*\n     * Check syntactic correctness.\n     *\n     * Note that this is consensus critical as CheckSig() calls it!\n     */\n    bool IsValid() const\n    {\n        return size() > 0;\n    }\n\n    //! fully validate whether this is a valid public key (more expensive than IsValid())\n    bool IsFullyValid() const;\n\n    //! Check whether this is a compressed public key.\n    bool IsCompressed() const\n    {\n        return size() == 33;\n    }\n\n    /**\n     * Verify a DER signature (~72 bytes).\n     * If this public key is not fully valid, the return value will be false.\n     */\n    bool Verify(const uint256 &hash, const std::vector<unsigned char> &vchSig) const;\n\n    /**\n     * Check whether a signature is normalized (lower-S).\n     */\n    static bool CheckLowS(const std::vector<unsigned char> &vchSig);\n\n    //! Recover a public key from a compact signature.\n    bool RecoverCompact(const uint256 &hash, const std::vector<unsigned char> &vchSig);\n\n    //! Turn this public key into an uncompressed public key.\n    bool Decompress();\n\n    //! Derive BIP32 child pubkey.\n    bool Derive(CPubKey &pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode &cc) const;\n};\n\nstruct CExtPubKey\n{\n    unsigned char nDepth;\n    unsigned char vchFingerprint[4];\n    unsigned int nChild;\n    ChainCode chaincode;\n    CPubKey pubkey;\n\n    friend bool operator==(const CExtPubKey &a, const CExtPubKey &b)\n    {\n        return a.nDepth == b.nDepth && memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], 4) == 0 && a.nChild == b.nChild &&\n               a.chaincode == b.chaincode && a.pubkey == b.pubkey;\n    }\n\n    void Encode(unsigned char code[74]) const;\n    void Decode(const unsigned char code[74]);\n    bool Derive(CExtPubKey &out, unsigned int nChild) const;\n};\n\n/** Users of this module must hold an ECCVerifyHandle. The constructor and\n *  destructor of these are not allowed to run in parallel, though. */\nclass ECCVerifyHandle\n{\n    static int refcount;\n\n  public:\n    ECCVerifyHandle();\n    ~ECCVerifyHandle();\n};\n\n#endif // BITCOIN_PUBKEY_H\n"
  },
  {
    "path": "src/UChainService/consensus/clone/script/interpreter.cpp",
    "content": "// Copyright (c) 2009-2010 Satoshi Nakamoto\n// Copyright (c) 2009-2015 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#include \"interpreter.h\"\n\n#include \"primitives/transaction.h\"\n#include \"crypto/ripemd160.h\"\n#include \"crypto/sha1.h\"\n#include \"crypto/sha256.h\"\n#include \"pubkey.h\"\n#include \"script/script.h\"\n#include \"uint256.h\"\n#include <UChainService/txs/token/attenuation_model.hpp>\n\nusing namespace std;\n\ntypedef vector<unsigned char> valtype;\n\nnamespace\n{\n\ninline bool set_success(ScriptError *ret)\n{\n    if (ret)\n        *ret = SCRIPT_ERR_OK;\n    return true;\n}\n\ninline bool set_error(ScriptError *ret, const ScriptError serror)\n{\n    if (ret)\n        *ret = serror;\n    return false;\n}\n\n} // namespace\n\nbool CastToBool(const valtype &vch)\n{\n    for (unsigned int i = 0; i < vch.size(); i++)\n    {\n        if (vch[i] != 0)\n        {\n            // Can be negative zero\n            if (i == vch.size() - 1 && vch[i] == 0x80)\n                return false;\n            return true;\n        }\n    }\n    return false;\n}\n\n/**\n * Script is a stack machine (like Forth) that evaluates a predicate\n * returning a bool indicating valid or not.  There are no loops.\n */\n#define stacktop(i) (stack.at(stack.size() + (i)))\n#define altstacktop(i) (altstack.at(altstack.size() + (i)))\nstatic inline void popstack(vector<valtype> &stack)\n{\n    if (stack.empty())\n        throw runtime_error(\"popstack(): stack empty\");\n    stack.pop_back();\n}\n\nbool static IsCompressedOrUncompressedPubKey(const valtype &vchPubKey)\n{\n    if (vchPubKey.size() < 33)\n    {\n        //  Non-canonical public key: too short\n        return false;\n    }\n    if (vchPubKey[0] == 0x04)\n    {\n        if (vchPubKey.size() != 65)\n        {\n            //  Non-canonical public key: invalid length for uncompressed key\n            return false;\n        }\n    }\n    else if (vchPubKey[0] == 0x02 || vchPubKey[0] == 0x03)\n    {\n        if (vchPubKey.size() != 33)\n        {\n            //  Non-canonical public key: invalid length for compressed key\n            return false;\n        }\n    }\n    else\n    {\n        //  Non-canonical public key: neither compressed nor uncompressed\n        return false;\n    }\n    return true;\n}\n\n/**\n * A canonical signature exists of: <30> <total len> <02> <len R> <R> <02> <len S> <S> <hashtype>\n * Where R and S are not negative (their first byte has its highest bit not set), and not\n * excessively padded (do not start with a 0 byte, unless an otherwise negative number follows,\n * in which case a single 0 byte is necessary and even required).\n *\n * See https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623\n *\n * This function is consensus-critical since BIP66.\n */\nbool static IsValidSignatureEncoding(const std::vector<unsigned char> &sig)\n{\n    // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] [sighash]\n    // * total-length: 1-byte length descriptor of everything that follows,\n    //   excluding the sighash byte.\n    // * R-length: 1-byte length descriptor of the R value that follows.\n    // * R: arbitrary-length big-endian encoded R value. It must use the shortest\n    //   possible encoding for a positive integers (which means no null bytes at\n    //   the start, except a single one when the next byte has its highest bit set).\n    // * S-length: 1-byte length descriptor of the S value that follows.\n    // * S: arbitrary-length big-endian encoded S value. The same rules apply.\n    // * sighash: 1-byte value indicating what data is hashed (not part of the DER\n    //   signature)\n\n    // Minimum and maximum size constraints.\n    if (sig.size() < 9)\n        return false;\n    if (sig.size() > 73)\n        return false;\n\n    // A signature is of type 0x30 (compound).\n    if (sig[0] != 0x30)\n        return false;\n\n    // Make sure the length covers the entire signature.\n    if (sig[1] != sig.size() - 3)\n        return false;\n\n    // Extract the length of the R element.\n    unsigned int lenR = sig[3];\n\n    // Make sure the length of the S element is still inside the signature.\n    if (5 + lenR >= sig.size())\n        return false;\n\n    // Extract the length of the S element.\n    unsigned int lenS = sig[5 + lenR];\n\n    // Verify that the length of the signature matches the sum of the length\n    // of the elements.\n    if ((size_t)(lenR + lenS + 7) != sig.size())\n        return false;\n\n    // Check whether the R element is an integer.\n    if (sig[2] != 0x02)\n        return false;\n\n    // Zero-length integers are not allowed for R.\n    if (lenR == 0)\n        return false;\n\n    // Negative numbers are not allowed for R.\n    if (sig[4] & 0x80)\n        return false;\n\n    // Null bytes at the start of R are not allowed, unless R would\n    // otherwise be interpreted as a negative number.\n    if (lenR > 1 && (sig[4] == 0x00) && !(sig[5] & 0x80))\n        return false;\n\n    // Check whether the S element is an integer.\n    if (sig[lenR + 4] != 0x02)\n        return false;\n\n    // Zero-length integers are not allowed for S.\n    if (lenS == 0)\n        return false;\n\n    // Negative numbers are not allowed for S.\n    if (sig[lenR + 6] & 0x80)\n        return false;\n\n    // Null bytes at the start of S are not allowed, unless S would otherwise be\n    // interpreted as a negative number.\n    if (lenS > 1 && (sig[lenR + 6] == 0x00) && !(sig[lenR + 7] & 0x80))\n        return false;\n\n    return true;\n}\n\nbool static IsLowDERSignature(const valtype &vchSig, ScriptError *serror)\n{\n    if (!IsValidSignatureEncoding(vchSig))\n    {\n        return set_error(serror, SCRIPT_ERR_SIG_DER);\n    }\n    std::vector<unsigned char> vchSigCopy(vchSig.begin(), vchSig.begin() + vchSig.size() - 1);\n    if (!CPubKey::CheckLowS(vchSigCopy))\n    {\n        return set_error(serror, SCRIPT_ERR_SIG_HIGH_S);\n    }\n    return true;\n}\n\nbool static IsDefinedHashtypeSignature(const valtype &vchSig)\n{\n    if (vchSig.size() == 0)\n    {\n        return false;\n    }\n    unsigned char nHashType = vchSig[vchSig.size() - 1] & (~(SIGHASH_ANYONECANPAY));\n    if (nHashType < SIGHASH_ALL || nHashType > SIGHASH_SINGLE)\n        return false;\n\n    return true;\n}\n\nbool CheckSignatureEncoding(const vector<unsigned char> &vchSig, unsigned int flags, ScriptError *serror)\n{\n    // Empty signature. Not strictly DER encoded, but allowed to provide a\n    // compact way to provide an invalid signature for use with CHECK(MULTI)SIG\n    if (vchSig.size() == 0)\n    {\n        return true;\n    }\n    if ((flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC)) != 0 && !IsValidSignatureEncoding(vchSig))\n    {\n        return set_error(serror, SCRIPT_ERR_SIG_DER);\n    }\n    else if ((flags & SCRIPT_VERIFY_LOW_S) != 0 && !IsLowDERSignature(vchSig, serror))\n    {\n        // serror is set\n        return false;\n    }\n    else if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsDefinedHashtypeSignature(vchSig))\n    {\n        return set_error(serror, SCRIPT_ERR_SIG_HASHTYPE);\n    }\n    return true;\n}\n\nbool static CheckPubKeyEncoding(const valtype &vchSig, unsigned int flags, ScriptError *serror)\n{\n    if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsCompressedOrUncompressedPubKey(vchSig))\n    {\n        return set_error(serror, SCRIPT_ERR_PUBKEYTYPE);\n    }\n    return true;\n}\n\nbool static CheckMinimalPush(const valtype &data, opcodetype opcode)\n{\n    if (data.size() == 0)\n    {\n        // Could have used OP_0.\n        return opcode == OP_0;\n    }\n    else if (data.size() == 1 && data[0] >= 1 && data[0] <= 16)\n    {\n        // Could have used OP_1 .. OP_16.\n        return opcode == OP_1 + (data[0] - 1);\n    }\n    else if (data.size() == 1 && data[0] == 0x81)\n    {\n        // Could have used OP_1NEGATE.\n        return opcode == OP_1NEGATE;\n    }\n    else if (data.size() <= 75)\n    {\n        // Could have used a direct push (opcode indicating number of bytes pushed + those bytes).\n        return opcode == data.size();\n    }\n    else if (data.size() <= 255)\n    {\n        // Could have used OP_PUSHDATA.\n        return opcode == OP_PUSHDATA1;\n    }\n    else if (data.size() <= 65535)\n    {\n        // Could have used OP_PUSHDATA2.\n        return opcode == OP_PUSHDATA2;\n    }\n    return true;\n}\n\nbool EvalScript(vector<vector<unsigned char>> &stack, const CScript &script, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)\n{\n    static const CScriptNum bnZero(0);\n    static const CScriptNum bnOne(1);\n    static const CScriptNum bnFalse(0);\n    static const CScriptNum bnTrue(1);\n    static const valtype vchFalse(0);\n    static const valtype vchZero(0);\n    static const valtype vchTrue(1, 1);\n\n    CScript::const_iterator pc = script.begin();\n    CScript::const_iterator pend = script.end();\n    CScript::const_iterator pbegincodehash = script.begin();\n    opcodetype opcode;\n    valtype vchPushValue;\n    vector<bool> vfExec;\n    vector<valtype> altstack;\n    set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR);\n    if (script.size() > 10000)\n        return set_error(serror, SCRIPT_ERR_SCRIPT_SIZE);\n    int nOpCount = 0;\n    bool fRequireMinimal = (flags & SCRIPT_VERIFY_MINIMALDATA) != 0;\n\n    try\n    {\n        while (pc < pend)\n        {\n            bool fExec = !count(vfExec.begin(), vfExec.end(), false);\n\n            //\n            // Read instruction\n            //\n            if (!script.GetOp(pc, opcode, vchPushValue))\n                return set_error(serror, SCRIPT_ERR_BAD_OPCODE);\n            if (vchPushValue.size() > MAX_SCRIPT_ELEMENT_SIZE)\n                return set_error(serror, SCRIPT_ERR_PUSH_SIZE);\n\n            // Note how OP_RESERVED does not count towards the opcode limit.\n            if (opcode > OP_16 && ++nOpCount > MAX_OPS_PER_SCRIPT)\n                return set_error(serror, SCRIPT_ERR_OP_COUNT);\n\n            if (opcode == OP_CAT ||\n                opcode == OP_SUBSTR ||\n                opcode == OP_LEFT ||\n                opcode == OP_RIGHT ||\n                opcode == OP_INVERT ||\n                opcode == OP_AND ||\n                opcode == OP_OR ||\n                opcode == OP_XOR ||\n                opcode == OP_2MUL ||\n                opcode == OP_2DIV ||\n                opcode == OP_MUL ||\n                opcode == OP_DIV ||\n                opcode == OP_MOD ||\n                opcode == OP_LSHIFT ||\n                opcode == OP_RSHIFT)\n                return set_error(serror, SCRIPT_ERR_DISABLED_OPCODE); // Disabled opcodes.\n\n            if (fExec && 0 <= opcode && opcode <= OP_PUSHDATA4)\n            {\n                if (fRequireMinimal && !CheckMinimalPush(vchPushValue, opcode))\n                {\n                    return set_error(serror, SCRIPT_ERR_MINIMALDATA);\n                }\n                stack.push_back(vchPushValue);\n            }\n            else if (fExec || (OP_IF <= opcode && opcode <= OP_ENDIF))\n                switch (opcode)\n                {\n                //\n                // Push value\n                //\n                case OP_1NEGATE:\n                case OP_1:\n                case OP_2:\n                case OP_3:\n                case OP_4:\n                case OP_5:\n                case OP_6:\n                case OP_7:\n                case OP_8:\n                case OP_9:\n                case OP_10:\n                case OP_11:\n                case OP_12:\n                case OP_13:\n                case OP_14:\n                case OP_15:\n                case OP_16:\n                {\n                    // ( -- value)\n                    CScriptNum bn((int)opcode - (int)(OP_1 - 1));\n                    stack.push_back(bn.getvch());\n                    // The result of these opcodes should always be the minimal way to push the data\n                    // they push, so no need for a CheckMinimalPush here.\n                }\n                break;\n\n                //\n                // Control\n                //\n                case OP_NOP:\n                    break;\n\n                case OP_CHECKLOCKTIMEVERIFY:\n                {\n                    if (!(flags & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY))\n                    {\n                        // not enabled; treat as a NOP2\n                        if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)\n                        {\n                            return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);\n                        }\n                        break;\n                    }\n\n                    if (stack.size() < 1)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n\n                    // Note that elsewhere numeric opcodes are limited to\n                    // operands in the range -2**31+1 to 2**31-1, however it is\n                    // legal for opcodes to produce results exceeding that\n                    // range. This limitation is implemented by CScriptNum's\n                    // default 4-byte limit.\n                    //\n                    // If we kept to that limit we'd have a year 2038 problem,\n                    // even though the nLockTime field in transactions\n                    // themselves is uint32 which only becomes meaningless\n                    // after the year 2106.\n                    //\n                    // Thus as a special case we tell CScriptNum to accept up\n                    // to 5-byte bignums, which are good until 2**39-1, well\n                    // beyond the 2**32-1 limit of the nLockTime field itself.\n                    const CScriptNum nLockTime(stacktop(-1), fRequireMinimal, 5);\n\n                    // In the rare event that the argument may be < 0 due to\n                    // some arithmetic being done first, you can always use\n                    // 0 MAX CHECKLOCKTIMEVERIFY.\n                    if (nLockTime < 0)\n                        return set_error(serror, SCRIPT_ERR_NEGATIVE_LOCKTIME);\n\n                    // Actually compare the specified lock time with the transaction.\n                    if (!checker.CheckLockTime(nLockTime))\n                        return set_error(serror, SCRIPT_ERR_UNSATISFIED_LOCKTIME);\n\n                    break;\n                }\n\n                case OP_CHECKATTENUATIONVERIFY:\n                {\n                    if (!(flags & SCRIPT_VERIFY_CHECKATTENUATIONVERIFY))\n                    {\n                        // not enabled; treat as a NOP3\n                        if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)\n                        {\n                            return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);\n                        }\n                        break;\n                    }\n\n                    if (stack.size() < 2)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n\n                    valtype &vcModelParam = stacktop(-2);\n                    //valtype& vcInputPoint = stacktop(-1);\n                    if (!attenuation_model::check_model_param_format(vcModelParam))\n                        return set_error(serror, SCRIPT_ERR_INVALID_MODEL_PARAM);\n\n                    popstack(stack);\n                    popstack(stack);\n                }\n                break;\n\n                case OP_NOP1:\n                case OP_NOP4:\n                case OP_NOP5:\n                case OP_NOP6:\n                case OP_NOP7:\n                case OP_NOP8:\n                case OP_NOP9:\n                case OP_NOP10:\n                {\n                    if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS)\n                        return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS);\n                }\n                break;\n\n                case OP_IF:\n                case OP_NOTIF:\n                {\n                    // <expression> if [statements] [else [statements]] endif\n                    bool fValue = false;\n                    if (fExec)\n                    {\n                        if (stack.size() < 1)\n                            return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL);\n                        valtype &vch = stacktop(-1);\n                        fValue = CastToBool(vch);\n                        if (opcode == OP_NOTIF)\n                            fValue = !fValue;\n                        popstack(stack);\n                    }\n                    vfExec.push_back(fValue);\n                }\n                break;\n\n                case OP_ELSE:\n                {\n                    if (vfExec.empty())\n                        return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL);\n                    vfExec.back() = !vfExec.back();\n                }\n                break;\n\n                case OP_ENDIF:\n                {\n                    if (vfExec.empty())\n                        return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL);\n                    vfExec.pop_back();\n                }\n                break;\n\n                case OP_VERIFY:\n                {\n                    // (true -- ) or\n                    // (false -- false) and return\n                    if (stack.size() < 1)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n                    bool fValue = CastToBool(stacktop(-1));\n                    if (fValue)\n                        popstack(stack);\n                    else\n                        return set_error(serror, SCRIPT_ERR_VERIFY);\n                }\n                break;\n\n                case OP_RETURN:\n                {\n                    return set_error(serror, SCRIPT_ERR_OP_RETURN);\n                }\n                break;\n\n                //\n                // Stack ops\n                //\n                case OP_TOALTSTACK:\n                {\n                    if (stack.size() < 1)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n                    altstack.push_back(stacktop(-1));\n                    popstack(stack);\n                }\n                break;\n\n                case OP_FROMALTSTACK:\n                {\n                    if (altstack.size() < 1)\n                        return set_error(serror, SCRIPT_ERR_INVALID_ALTSTACK_OPERATION);\n                    stack.push_back(altstacktop(-1));\n                    popstack(altstack);\n                }\n                break;\n\n                case OP_2DROP:\n                {\n                    // (x1 x2 -- )\n                    if (stack.size() < 2)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n                    popstack(stack);\n                    popstack(stack);\n                }\n                break;\n\n                case OP_2DUP:\n                {\n                    // (x1 x2 -- x1 x2 x1 x2)\n                    if (stack.size() < 2)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n                    valtype vch1 = stacktop(-2);\n                    valtype vch2 = stacktop(-1);\n                    stack.push_back(vch1);\n                    stack.push_back(vch2);\n                }\n                break;\n\n                case OP_3DUP:\n                {\n                    // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3)\n                    if (stack.size() < 3)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n                    valtype vch1 = stacktop(-3);\n                    valtype vch2 = stacktop(-2);\n                    valtype vch3 = stacktop(-1);\n                    stack.push_back(vch1);\n                    stack.push_back(vch2);\n                    stack.push_back(vch3);\n                }\n                break;\n\n                case OP_2OVER:\n                {\n                    // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2)\n                    if (stack.size() < 4)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n                    valtype vch1 = stacktop(-4);\n                    valtype vch2 = stacktop(-3);\n                    stack.push_back(vch1);\n                    stack.push_back(vch2);\n                }\n                break;\n\n                case OP_2ROT:\n                {\n                    // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2)\n                    if (stack.size() < 6)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n                    valtype vch1 = stacktop(-6);\n                    valtype vch2 = stacktop(-5);\n                    stack.erase(stack.end() - 6, stack.end() - 4);\n                    stack.push_back(vch1);\n                    stack.push_back(vch2);\n                }\n                break;\n\n                case OP_2SWAP:\n                {\n                    // (x1 x2 x3 x4 -- x3 x4 x1 x2)\n                    if (stack.size() < 4)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n                    swap(stacktop(-4), stacktop(-2));\n                    swap(stacktop(-3), stacktop(-1));\n                }\n                break;\n\n                case OP_IFDUP:\n                {\n                    // (x - 0 | x x)\n                    if (stack.size() < 1)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n                    valtype vch = stacktop(-1);\n                    if (CastToBool(vch))\n                        stack.push_back(vch);\n                }\n                break;\n\n                case OP_DEPTH:\n                {\n                    // -- stacksize\n                    CScriptNum bn(stack.size());\n                    stack.push_back(bn.getvch());\n                }\n                break;\n\n                case OP_DROP:\n                {\n                    // (x -- )\n                    if (stack.size() < 1)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n                    popstack(stack);\n                }\n                break;\n\n                case OP_DUP:\n                {\n                    // (x -- x x)\n                    if (stack.size() < 1)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n                    valtype vch = stacktop(-1);\n                    stack.push_back(vch);\n                }\n                break;\n\n                case OP_NIP:\n                {\n                    // (x1 x2 -- x2)\n                    if (stack.size() < 2)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n                    stack.erase(stack.end() - 2);\n                }\n                break;\n\n                case OP_OVER:\n                {\n                    // (x1 x2 -- x1 x2 x1)\n                    if (stack.size() < 2)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n                    valtype vch = stacktop(-2);\n                    stack.push_back(vch);\n                }\n                break;\n\n                case OP_PICK:\n                case OP_ROLL:\n                {\n                    // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn)\n                    // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn)\n                    if (stack.size() < 2)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n                    int n = CScriptNum(stacktop(-1), fRequireMinimal).getint();\n                    popstack(stack);\n                    if (n < 0 || n >= (int)stack.size())\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n                    valtype vch = stacktop(-n - 1);\n                    if (opcode == OP_ROLL)\n                        stack.erase(stack.end() - n - 1);\n                    stack.push_back(vch);\n                }\n                break;\n\n                case OP_ROT:\n                {\n                    // (x1 x2 x3 -- x2 x3 x1)\n                    //  x2 x1 x3  after first swap\n                    //  x2 x3 x1  after second swap\n                    if (stack.size() < 3)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n                    swap(stacktop(-3), stacktop(-2));\n                    swap(stacktop(-2), stacktop(-1));\n                }\n                break;\n\n                case OP_SWAP:\n                {\n                    // (x1 x2 -- x2 x1)\n                    if (stack.size() < 2)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n                    swap(stacktop(-2), stacktop(-1));\n                }\n                break;\n\n                case OP_TUCK:\n                {\n                    // (x1 x2 -- x2 x1 x2)\n                    if (stack.size() < 2)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n                    valtype vch = stacktop(-1);\n                    stack.insert(stack.end() - 2, vch);\n                }\n                break;\n\n                case OP_SIZE:\n                {\n                    // (in -- in size)\n                    if (stack.size() < 1)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n                    CScriptNum bn(stacktop(-1).size());\n                    stack.push_back(bn.getvch());\n                }\n                break;\n\n                //\n                // Bitwise logic\n                //\n                case OP_EQUAL:\n                case OP_EQUALVERIFY:\n                    //case OP_NOTEQUAL: // use OP_NUMNOTEQUAL\n                    {\n                        // (x1 x2 - bool)\n                        if (stack.size() < 2)\n                            return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n                        valtype &vch1 = stacktop(-2);\n                        valtype &vch2 = stacktop(-1);\n                        bool fEqual = (vch1 == vch2);\n                        // OP_NOTEQUAL is disabled because it would be too easy to say\n                        // something like n != 1 and have some wiseguy pass in 1 with extra\n                        // zero bytes after it (numerically, 0x01 == 0x0001 == 0x000001)\n                        //if (opcode == OP_NOTEQUAL)\n                        //    fEqual = !fEqual;\n                        popstack(stack);\n                        popstack(stack);\n                        stack.push_back(fEqual ? vchTrue : vchFalse);\n                        if (opcode == OP_EQUALVERIFY)\n                        {\n                            if (fEqual)\n                                popstack(stack);\n                            else\n                                return set_error(serror, SCRIPT_ERR_EQUALVERIFY);\n                        }\n                    }\n                    break;\n\n                //\n                // Numeric\n                //\n                case OP_1ADD:\n                case OP_1SUB:\n                case OP_NEGATE:\n                case OP_ABS:\n                case OP_NOT:\n                case OP_0NOTEQUAL:\n                {\n                    // (in -- out)\n                    if (stack.size() < 1)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n                    CScriptNum bn(stacktop(-1), fRequireMinimal);\n                    switch (opcode)\n                    {\n                    case OP_1ADD:\n                        bn += bnOne;\n                        break;\n                    case OP_1SUB:\n                        bn -= bnOne;\n                        break;\n                    case OP_NEGATE:\n                        bn = -bn;\n                        break;\n                    case OP_ABS:\n                        if (bn < bnZero)\n                            bn = -bn;\n                        break;\n                    case OP_NOT:\n                        bn = (bn == bnZero);\n                        break;\n                    case OP_0NOTEQUAL:\n                        bn = (bn != bnZero);\n                        break;\n                    default:\n                        assert(!\"invalid opcode\");\n                        break;\n                    }\n                    popstack(stack);\n                    stack.push_back(bn.getvch());\n                }\n                break;\n\n                case OP_ADD:\n                case OP_SUB:\n                case OP_BOOLAND:\n                case OP_BOOLOR:\n                case OP_NUMEQUAL:\n                case OP_NUMEQUALVERIFY:\n                case OP_NUMNOTEQUAL:\n                case OP_LESSTHAN:\n                case OP_GREATERTHAN:\n                case OP_LESSTHANOREQUAL:\n                case OP_GREATERTHANOREQUAL:\n                case OP_MIN:\n                case OP_MAX:\n                {\n                    // (x1 x2 -- out)\n                    if (stack.size() < 2)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n                    CScriptNum bn1(stacktop(-2), fRequireMinimal);\n                    CScriptNum bn2(stacktop(-1), fRequireMinimal);\n                    CScriptNum bn(0);\n                    switch (opcode)\n                    {\n                    case OP_ADD:\n                        bn = bn1 + bn2;\n                        break;\n\n                    case OP_SUB:\n                        bn = bn1 - bn2;\n                        break;\n\n                    case OP_BOOLAND:\n                        bn = (bn1 != bnZero && bn2 != bnZero);\n                        break;\n                    case OP_BOOLOR:\n                        bn = (bn1 != bnZero || bn2 != bnZero);\n                        break;\n                    case OP_NUMEQUAL:\n                        bn = (bn1 == bn2);\n                        break;\n                    case OP_NUMEQUALVERIFY:\n                        bn = (bn1 == bn2);\n                        break;\n                    case OP_NUMNOTEQUAL:\n                        bn = (bn1 != bn2);\n                        break;\n                    case OP_LESSTHAN:\n                        bn = (bn1 < bn2);\n                        break;\n                    case OP_GREATERTHAN:\n                        bn = (bn1 > bn2);\n                        break;\n                    case OP_LESSTHANOREQUAL:\n                        bn = (bn1 <= bn2);\n                        break;\n                    case OP_GREATERTHANOREQUAL:\n                        bn = (bn1 >= bn2);\n                        break;\n                    case OP_MIN:\n                        bn = (bn1 < bn2 ? bn1 : bn2);\n                        break;\n                    case OP_MAX:\n                        bn = (bn1 > bn2 ? bn1 : bn2);\n                        break;\n                    default:\n                        assert(!\"invalid opcode\");\n                        break;\n                    }\n                    popstack(stack);\n                    popstack(stack);\n                    stack.push_back(bn.getvch());\n\n                    if (opcode == OP_NUMEQUALVERIFY)\n                    {\n                        if (CastToBool(stacktop(-1)))\n                            popstack(stack);\n                        else\n                            return set_error(serror, SCRIPT_ERR_NUMEQUALVERIFY);\n                    }\n                }\n                break;\n\n                case OP_WITHIN:\n                {\n                    // (x min max -- out)\n                    if (stack.size() < 3)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n                    CScriptNum bn1(stacktop(-3), fRequireMinimal);\n                    CScriptNum bn2(stacktop(-2), fRequireMinimal);\n                    CScriptNum bn3(stacktop(-1), fRequireMinimal);\n                    bool fValue = (bn2 <= bn1 && bn1 < bn3);\n                    popstack(stack);\n                    popstack(stack);\n                    popstack(stack);\n                    stack.push_back(fValue ? vchTrue : vchFalse);\n                }\n                break;\n\n                //\n                // Crypto\n                //\n                case OP_RIPEMD160:\n                case OP_SHA1:\n                case OP_SHA256:\n                case OP_HASH160:\n                case OP_HASH256:\n                {\n                    // (in -- hash)\n                    if (stack.size() < 1)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n                    valtype &vch = stacktop(-1);\n                    valtype vchHash((opcode == OP_RIPEMD160 || opcode == OP_SHA1 || opcode == OP_HASH160) ? 20 : 32);\n                    if (opcode == OP_RIPEMD160)\n                        CRIPEMD160().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash));\n                    else if (opcode == OP_SHA1)\n                        CSHA1().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash));\n                    else if (opcode == OP_SHA256)\n                        CSHA256().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash));\n                    else if (opcode == OP_HASH160)\n                        CHash160().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash));\n                    else if (opcode == OP_HASH256)\n                        CHash256().Write(begin_ptr(vch), vch.size()).Finalize(begin_ptr(vchHash));\n                    popstack(stack);\n                    stack.push_back(vchHash);\n                }\n                break;\n\n                case OP_CODESEPARATOR:\n                {\n                    // Hash starts after the code separator\n                    pbegincodehash = pc;\n                }\n                break;\n\n                case OP_CHECKSIG:\n                case OP_CHECKSIGVERIFY:\n                {\n                    // (sig pubkey -- bool)\n                    if (stack.size() < 2)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n\n                    valtype &vchSig = stacktop(-2);\n                    valtype &vchPubKey = stacktop(-1);\n\n                    // Subset of script starting at the most recent codeseparator\n                    CScript scriptCode(pbegincodehash, pend);\n\n                    // Drop the signature, since there's no way for a signature to sign itself\n                    scriptCode.FindAndDelete(CScript(vchSig));\n\n                    if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror))\n                    {\n                        //serror is set\n                        return false;\n                    }\n                    bool fSuccess = checker.CheckSig(vchSig, vchPubKey, scriptCode);\n\n                    popstack(stack);\n                    popstack(stack);\n                    stack.push_back(fSuccess ? vchTrue : vchFalse);\n                    if (opcode == OP_CHECKSIGVERIFY)\n                    {\n                        if (fSuccess)\n                            popstack(stack);\n                        else\n                            return set_error(serror, SCRIPT_ERR_CHECKSIGVERIFY);\n                    }\n                }\n                break;\n\n                case OP_CHECKMULTISIG:\n                case OP_CHECKMULTISIGVERIFY:\n                {\n                    // ([sig ...] num_of_signatures [pubkey ...] num_of_pubkeys -- bool)\n\n                    int i = 1;\n                    if ((int)stack.size() < i)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n\n                    int nKeysCount = CScriptNum(stacktop(-i), fRequireMinimal).getint();\n                    if (nKeysCount < 0 || nKeysCount > MAX_PUBKEYS_PER_MULTISIG)\n                        return set_error(serror, SCRIPT_ERR_PUBKEY_COUNT);\n                    nOpCount += nKeysCount;\n                    if (nOpCount > MAX_OPS_PER_SCRIPT)\n                        return set_error(serror, SCRIPT_ERR_OP_COUNT);\n                    int ikey = ++i;\n                    i += nKeysCount;\n                    if ((int)stack.size() < i)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n\n                    int nSigsCount = CScriptNum(stacktop(-i), fRequireMinimal).getint();\n                    if (nSigsCount < 0 || nSigsCount > nKeysCount)\n                        return set_error(serror, SCRIPT_ERR_SIG_COUNT);\n                    int isig = ++i;\n                    i += nSigsCount;\n                    if ((int)stack.size() < i)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n\n                    // Subset of script starting at the most recent codeseparator\n                    CScript scriptCode(pbegincodehash, pend);\n\n                    // Drop the signatures, since there's no way for a signature to sign itself\n                    for (int k = 0; k < nSigsCount; k++)\n                    {\n                        valtype &vchSig = stacktop(-isig - k);\n                        scriptCode.FindAndDelete(CScript(vchSig));\n                    }\n\n                    bool fSuccess = true;\n                    while (fSuccess && nSigsCount > 0)\n                    {\n                        valtype &vchSig = stacktop(-isig);\n                        valtype &vchPubKey = stacktop(-ikey);\n\n                        // Note how this makes the exact order of pubkey/signature evaluation\n                        // distinguishable by CHECKMULTISIG NOT if the STRICTENC flag is set.\n                        // See the script_(in)valid tests for details.\n                        if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror))\n                        {\n                            // serror is set\n                            return false;\n                        }\n\n                        // Check signature\n                        bool fOk = checker.CheckSig(vchSig, vchPubKey, scriptCode);\n\n                        if (fOk)\n                        {\n                            isig++;\n                            nSigsCount--;\n                        }\n                        ikey++;\n                        nKeysCount--;\n\n                        // If there are more signatures left than keys left,\n                        // then too many signatures have failed. Exit early,\n                        // without checking any further signatures.\n                        if (nSigsCount > nKeysCount)\n                            fSuccess = false;\n                    }\n\n                    // Clean up stack of actual arguments\n                    while (i-- > 1)\n                        popstack(stack);\n\n                    // A bug causes CHECKMULTISIG to consume one extra argument\n                    // whose contents were not checked in any way.\n                    //\n                    // Unfortunately this is a potential source of mutability,\n                    // so optionally verify it is exactly equal to zero prior\n                    // to removing it from the stack.\n                    if (stack.size() < 1)\n                        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);\n                    if ((flags & SCRIPT_VERIFY_NULLDUMMY) && stacktop(-1).size())\n                        return set_error(serror, SCRIPT_ERR_SIG_NULLDUMMY);\n                    popstack(stack);\n\n                    stack.push_back(fSuccess ? vchTrue : vchFalse);\n\n                    if (opcode == OP_CHECKMULTISIGVERIFY)\n                    {\n                        if (fSuccess)\n                            popstack(stack);\n                        else\n                            return set_error(serror, SCRIPT_ERR_CHECKMULTISIGVERIFY);\n                    }\n                }\n                break;\n\n                default:\n                    return set_error(serror, SCRIPT_ERR_BAD_OPCODE);\n                }\n\n            // Size limits\n            if (stack.size() + altstack.size() > 1000)\n                return set_error(serror, SCRIPT_ERR_STACK_SIZE);\n        }\n    }\n    catch (...)\n    {\n        return set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR);\n    }\n\n    if (!vfExec.empty())\n        return set_error(serror, SCRIPT_ERR_UNBALANCED_CONDITIONAL);\n\n    return set_success(serror);\n}\n\nnamespace\n{\n\n/**\n * Wrapper that serializes like CTransaction, but with the modifications\n *  required for the signature hash done in-place\n */\nclass CTransactionSignatureSerializer\n{\n  private:\n    const CTransaction &txTo;  //! reference to the spending transaction (the one being serialized)\n    const CScript &scriptCode; //! output script being consumed\n    const unsigned int nIn;    //! input index of txTo being signed\n    const bool fAnyoneCanPay;  //! whether the hashtype has the SIGHASH_ANYONECANPAY flag set\n    const bool fHashSingle;    //! whether the hashtype is SIGHASH_SINGLE\n    const bool fHashNone;      //! whether the hashtype is SIGHASH_NONE\n\n  public:\n    CTransactionSignatureSerializer(const CTransaction &txToIn, const CScript &scriptCodeIn, unsigned int nInIn, int nHashTypeIn) : txTo(txToIn), scriptCode(scriptCodeIn), nIn(nInIn),\n                                                                                                                                    fAnyoneCanPay(!!(nHashTypeIn & SIGHASH_ANYONECANPAY)),\n                                                                                                                                    fHashSingle((nHashTypeIn & 0x1f) == SIGHASH_SINGLE),\n                                                                                                                                    fHashNone((nHashTypeIn & 0x1f) == SIGHASH_NONE) {}\n\n    /** Serialize the passed scriptCode, skipping OP_CODESEPARATORs */\n    template <typename S>\n    void SerializeScriptCode(S &s, int nType, int nVersion) const\n    {\n        CScript::const_iterator it = scriptCode.begin();\n        CScript::const_iterator itBegin = it;\n        opcodetype opcode;\n        unsigned int nCodeSeparators = 0;\n        while (scriptCode.GetOp(it, opcode))\n        {\n            if (opcode == OP_CODESEPARATOR)\n                nCodeSeparators++;\n        }\n        ::WriteCompactSize(s, scriptCode.size() - nCodeSeparators);\n        it = itBegin;\n        while (scriptCode.GetOp(it, opcode))\n        {\n            if (opcode == OP_CODESEPARATOR)\n            {\n                s.write((char *)&itBegin[0], it - itBegin - 1);\n                itBegin = it;\n            }\n        }\n        if (itBegin != scriptCode.end())\n            s.write((char *)&itBegin[0], it - itBegin);\n    }\n\n    /** Serialize an input of txTo */\n    template <typename S>\n    void SerializeInput(S &s, unsigned int nInput, int nType, int nVersion) const\n    {\n        // In case of SIGHASH_ANYONECANPAY, only the input being signed is serialized\n        if (fAnyoneCanPay)\n            nInput = nIn;\n        // Serialize the prevout\n        ::Serialize(s, txTo.vin[nInput].prevout, nType, nVersion);\n        // Serialize the script\n        if (nInput != nIn)\n            // Blank out other inputs' signatures\n            ::Serialize(s, CScriptBase(), nType, nVersion);\n        else\n            SerializeScriptCode(s, nType, nVersion);\n        // Serialize the nSequence\n        if (nInput != nIn && (fHashSingle || fHashNone))\n            // let the others update at will\n            ::Serialize(s, (int)0, nType, nVersion);\n        else\n            ::Serialize(s, txTo.vin[nInput].nSequence, nType, nVersion);\n    }\n\n    /** Serialize an output of txTo */\n    template <typename S>\n    void SerializeOutput(S &s, unsigned int nOutput, int nType, int nVersion) const\n    {\n        if (fHashSingle && nOutput != nIn)\n            // Do not lock-in the txout payee at other indices as txin\n            ::Serialize(s, CTxOut(), nType, nVersion);\n        else\n            ::Serialize(s, txTo.vout[nOutput], nType, nVersion);\n    }\n\n    /** Serialize txTo */\n    template <typename S>\n    void Serialize(S &s, int nType, int nVersion) const\n    {\n        // Serialize nVersion\n        ::Serialize(s, txTo.nVersion, nType, nVersion);\n        // Serialize vin\n        unsigned int nInputs = fAnyoneCanPay ? 1 : txTo.vin.size();\n        ::WriteCompactSize(s, nInputs);\n        for (unsigned int nInput = 0; nInput < nInputs; nInput++)\n            SerializeInput(s, nInput, nType, nVersion);\n        // Serialize vout\n        unsigned int nOutputs = fHashNone ? 0 : (fHashSingle ? nIn + 1 : txTo.vout.size());\n        ::WriteCompactSize(s, nOutputs);\n        for (unsigned int nOutput = 0; nOutput < nOutputs; nOutput++)\n            SerializeOutput(s, nOutput, nType, nVersion);\n        // Serialize nLockTime\n        ::Serialize(s, txTo.nLockTime, nType, nVersion);\n    }\n};\n\n} // namespace\n\nuint256 SignatureHash(const CScript &scriptCode, const CTransaction &txTo, unsigned int nIn, int nHashType)\n{\n    static const uint256 one(uint256S(\"0000000000000000000000000000000000000000000000000000000000000001\"));\n    if (nIn >= txTo.vin.size())\n    {\n        //  nIn out of range\n        return one;\n    }\n\n    // Check for invalid use of SIGHASH_SINGLE\n    if ((nHashType & 0x1f) == SIGHASH_SINGLE)\n    {\n        if (nIn >= txTo.vout.size())\n        {\n            //  nOut out of range\n            return one;\n        }\n    }\n\n    // Wrapper to serialize only the necessary parts of the transaction being signed\n    CTransactionSignatureSerializer txTmp(txTo, scriptCode, nIn, nHashType);\n\n    // Serialize and hash\n    CHashWriter ss(SER_GETHASH, 0);\n    ss << txTmp << nHashType;\n    return ss.GetHash();\n}\n\nbool TransactionSignatureChecker::VerifySignature(const std::vector<unsigned char> &vchSig, const CPubKey &pubkey, const uint256 &sighash) const\n{\n    return pubkey.Verify(sighash, vchSig);\n}\n\nbool TransactionSignatureChecker::CheckSig(const vector<unsigned char> &vchSigIn, const vector<unsigned char> &vchPubKey, const CScript &scriptCode) const\n{\n    CPubKey pubkey(vchPubKey);\n    if (!pubkey.IsValid())\n        return false;\n\n    // Hash type is one byte tacked on to the end of the signature\n    vector<unsigned char> vchSig(vchSigIn);\n    if (vchSig.empty())\n        return false;\n    int nHashType = vchSig.back();\n    vchSig.pop_back();\n\n    uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType);\n\n    if (!VerifySignature(vchSig, pubkey, sighash))\n        return false;\n\n    return true;\n}\n\nbool TransactionSignatureChecker::CheckLockTime(const CScriptNum &nLockTime) const\n{\n    // There are two kinds of nLockTime: lock-by-blockheight\n    // and lock-by-blocktime, distinguished by whether\n    // nLockTime < LOCKTIME_THRESHOLD.\n    //\n    // We want to compare apples to apples, so fail the script\n    // unless the type of nLockTime being tested is the same as\n    // the nLockTime in the transaction.\n    if (!(\n            (txTo->nLockTime < LOCKTIME_THRESHOLD && nLockTime < LOCKTIME_THRESHOLD) ||\n            (txTo->nLockTime >= LOCKTIME_THRESHOLD && nLockTime >= LOCKTIME_THRESHOLD)))\n        return false;\n\n    // Now that we know we're comparing apples-to-apples, the\n    // comparison is a simple numeric one.\n    if (nLockTime > (int64_t)txTo->nLockTime)\n        return false;\n\n    // Finally the nLockTime feature can be disabled and thus\n    // CHECKLOCKTIMEVERIFY bypassed if every txin has been\n    // finalized by setting nSequence to maxint. The\n    // transaction would be allowed into the blockchain, making\n    // the opcode ineffective.\n    //\n    // Testing if this vin is not final is sufficient to\n    // prevent this condition. Alternatively we could test all\n    // inputs, but testing just this input minimizes the data\n    // required to prove correct CHECKLOCKTIMEVERIFY execution.\n    if (txTo->vin[nIn].IsFinal())\n        return false;\n\n    return true;\n}\n\nbool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)\n{\n    set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR);\n\n    if ((flags & SCRIPT_VERIFY_SIGPUSHONLY) != 0 && !scriptSig.IsPushOnly())\n    {\n        return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY);\n    }\n\n    vector<vector<unsigned char>> stack, stackCopy;\n    if (!EvalScript(stack, scriptSig, flags, checker, serror))\n        // serror is set\n        return false;\n    if (flags & SCRIPT_VERIFY_P2SH)\n        stackCopy = stack;\n    if (!EvalScript(stack, scriptPubKey, flags, checker, serror))\n        // serror is set\n        return false;\n    if (stack.empty())\n        return set_error(serror, SCRIPT_ERR_EVAL_FALSE);\n    /*if (CastToBool(stack.back()) == false)\n        return set_error(serror, SCRIPT_ERR_EVAL_FALSE);*/\n\n    // Additional validation for spend-to-script-hash transactions:\n    if ((flags & SCRIPT_VERIFY_P2SH) && scriptPubKey.IsPayToScriptHash())\n    {\n        // scriptSig must be literals-only or validation fails\n        if (!scriptSig.IsPushOnly())\n            return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY);\n\n        // Restore stack.\n        swap(stack, stackCopy);\n\n        // stack cannot be empty here, because if it was the\n        // P2SH  HASH <> EQUAL  scriptPubKey would be evaluated with\n        // an empty stack and the EvalScript above would return false.\n        assert(!stack.empty());\n\n        const valtype &pubKeySerialized = stack.back();\n        CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end());\n        popstack(stack);\n\n        if (!EvalScript(stack, pubKey2, flags, checker, serror))\n            // serror is set\n            return false;\n        if (stack.empty())\n            return set_error(serror, SCRIPT_ERR_EVAL_FALSE);\n        if (!CastToBool(stack.back()))\n            return set_error(serror, SCRIPT_ERR_EVAL_FALSE);\n    }\n\n    // The CLEANSTACK check is only performed after potential P2SH evaluation,\n    // as the non-P2SH evaluation of a P2SH script will obviously not result in\n    // a clean stack (the P2SH inputs remain).\n    if ((flags & SCRIPT_VERIFY_CLEANSTACK) != 0)\n    {\n        // Disallow CLEANSTACK without P2SH, as otherwise a switch CLEANSTACK->P2SH+CLEANSTACK\n        // would be possible, which is not a softfork (and P2SH should be one).\n        assert((flags & SCRIPT_VERIFY_P2SH) != 0);\n        if (stack.size() != 1)\n        {\n            return set_error(serror, SCRIPT_ERR_CLEANSTACK);\n        }\n    }\n\n    return set_success(serror);\n}\n"
  },
  {
    "path": "src/UChainService/consensus/clone/script/interpreter.h",
    "content": "// Copyright (c) 2009-2010 Satoshi Nakamoto\n// Copyright (c) 2009-2015 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#ifndef BITCOIN_SCRIPT_INTERPRETER_H\n#define BITCOIN_SCRIPT_INTERPRETER_H\n\n#include \"script_error.h\"\n#include \"primitives/transaction.h\"\n\n#include <vector>\n#include <stdint.h>\n#include <string>\n\nclass CPubKey;\nclass CScript;\nclass CTransaction;\nclass uint256;\n\n/** Signature hash types/flags */\nenum\n{\n    SIGHASH_ALL = 1,\n    SIGHASH_NONE = 2,\n    SIGHASH_SINGLE = 3,\n    SIGHASH_ANYONECANPAY = 0x80,\n};\n\n/** Script verification flags */\nenum\n{\n    SCRIPT_VERIFY_NONE = 0,\n\n    // Evaluate P2SH subscripts (softfork safe, BIP16).\n    SCRIPT_VERIFY_P2SH = (1U << 0),\n\n    // Passing a non-strict-DER signature or one with undefined hashtype to a checksig operation causes script failure.\n    // Evaluating a pubkey that is not (0x04 + 64 bytes) or (0x02 or 0x03 + 32 bytes) by checksig causes script failure.\n    // (softfork safe, but not used or intended as a consensus rule).\n    SCRIPT_VERIFY_STRICTENC = (1U << 1),\n\n    // Passing a non-strict-DER signature to a checksig operation causes script failure (softfork safe, BIP62 rule 1)\n    SCRIPT_VERIFY_DERSIG = (1U << 2),\n\n    // Passing a non-strict-DER signature or one with S > order/2 to a checksig operation causes script failure\n    // (softfork safe, BIP62 rule 5).\n    SCRIPT_VERIFY_LOW_S = (1U << 3),\n\n    // verify dummy stack item consumed by CHECKMULTISIG is of zero-length (softfork safe, BIP62 rule 7).\n    SCRIPT_VERIFY_NULLDUMMY = (1U << 4),\n\n    // Using a non-push operator in the scriptSig causes script failure (softfork safe, BIP62 rule 2).\n    SCRIPT_VERIFY_SIGPUSHONLY = (1U << 5),\n\n    // Require minimal encodings for all push operations (OP_0... OP_16, OP_1NEGATE where possible, direct\n    // pushes up to 75 bytes, OP_PUSHDATA up to 255 bytes, OP_PUSHDATA2 for anything larger). Evaluating\n    // any other push causes the script to fail (BIP62 rule 3).\n    // In addition, whenever a stack element is interpreted as a number, it must be of minimal length (BIP62 rule 4).\n    // (softfork safe)\n    SCRIPT_VERIFY_MINIMALDATA = (1U << 6),\n\n    // Discourage use of NOPs reserved for upgrades (NOP1-10)\n    //\n    // Provided so that nodes can avoid accepting or mining transactions\n    // containing executed NOP's whose meaning may change after a soft-fork,\n    // thus rendering the script invalid; with this flag set executing\n    // discouraged NOPs fails the script. This verification flag will never be\n    // a mandatory flag applied to scripts in a block. NOPs that are not\n    // executed, e.g.  within an unexecuted IF ENDIF block, are *not* rejected.\n    SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1U << 7),\n\n    // Require that only a single stack element remains after evaluation. This changes the success criterion from\n    // \"At least one stack element must remain, and when interpreted as a boolean, it must be true\" to\n    // \"Exactly one stack element must remain, and when interpreted as a boolean, it must be true\".\n    // (softfork safe, BIP62 rule 6)\n    // Note: CLEANSTACK should never be used without P2SH.\n    SCRIPT_VERIFY_CLEANSTACK = (1U << 8),\n\n    // Verify CHECKLOCKTIMEVERIFY\n    //\n    // See BIP65 for details.\n    SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9),\n\n    // Verify CHECKATTENUATIONVERIFY\n    SCRIPT_VERIFY_CHECKATTENUATIONVERIFY = (1U << 10),\n};\n\nbool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig, unsigned int flags, ScriptError *serror);\n\nuint256 SignatureHash(const CScript &scriptCode, const CTransaction &txTo, unsigned int nIn, int nHashType);\n\nclass BaseSignatureChecker\n{\n  public:\n    virtual bool CheckSig(const std::vector<unsigned char> &scriptSig, const std::vector<unsigned char> &vchPubKey, const CScript &scriptCode) const\n    {\n        return false;\n    }\n\n    virtual bool CheckLockTime(const CScriptNum &nLockTime) const\n    {\n        return false;\n    }\n\n    virtual ~BaseSignatureChecker() {}\n};\n\nclass TransactionSignatureChecker : public BaseSignatureChecker\n{\n  private:\n    const CTransaction *txTo;\n    unsigned int nIn;\n\n  protected:\n    virtual bool VerifySignature(const std::vector<unsigned char> &vchSig, const CPubKey &vchPubKey, const uint256 &sighash) const;\n\n  public:\n    TransactionSignatureChecker(const CTransaction *txToIn, unsigned int nInIn) : txTo(txToIn), nIn(nInIn) {}\n    bool CheckSig(const std::vector<unsigned char> &scriptSig, const std::vector<unsigned char> &vchPubKey, const CScript &scriptCode) const;\n    bool CheckLockTime(const CScriptNum &nLockTime) const;\n};\n\nclass MutableTransactionSignatureChecker : public TransactionSignatureChecker\n{\n  private:\n    const CTransaction txTo;\n\n  public:\n    MutableTransactionSignatureChecker(const CMutableTransaction *txToIn, unsigned int nInIn) : TransactionSignatureChecker(&txTo, nInIn), txTo(*txToIn) {}\n};\n\nbool EvalScript(std::vector<std::vector<unsigned char>> &stack, const CScript &script, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *error = NULL);\nbool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *error = NULL);\n\n#endif // BITCOIN_SCRIPT_INTERPRETER_H\n"
  },
  {
    "path": "src/UChainService/consensus/clone/script/script.cpp",
    "content": "// Copyright (c) 2009-2010 Satoshi Nakamoto\n// Copyright (c) 2009-2015 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#include \"script.h\"\n\n#include \"tinyformat.h\"\n#include \"utilstrencodings.h\"\n\nusing namespace std;\n\nconst char *GetOpName(opcodetype opcode)\n{\n    switch (opcode)\n    {\n    // push value\n    case OP_0:\n        return \"0\";\n    case OP_PUSHDATA1:\n        return \"OP_PUSHDATA1\";\n    case OP_PUSHDATA2:\n        return \"OP_PUSHDATA2\";\n    case OP_PUSHDATA4:\n        return \"OP_PUSHDATA4\";\n    case OP_1NEGATE:\n        return \"-1\";\n    case OP_RESERVED:\n        return \"OP_RESERVED\";\n    case OP_1:\n        return \"1\";\n    case OP_2:\n        return \"2\";\n    case OP_3:\n        return \"3\";\n    case OP_4:\n        return \"4\";\n    case OP_5:\n        return \"5\";\n    case OP_6:\n        return \"6\";\n    case OP_7:\n        return \"7\";\n    case OP_8:\n        return \"8\";\n    case OP_9:\n        return \"9\";\n    case OP_10:\n        return \"10\";\n    case OP_11:\n        return \"11\";\n    case OP_12:\n        return \"12\";\n    case OP_13:\n        return \"13\";\n    case OP_14:\n        return \"14\";\n    case OP_15:\n        return \"15\";\n    case OP_16:\n        return \"16\";\n\n    // control\n    case OP_NOP:\n        return \"OP_NOP\";\n    case OP_VER:\n        return \"OP_VER\";\n    case OP_IF:\n        return \"OP_IF\";\n    case OP_NOTIF:\n        return \"OP_NOTIF\";\n    case OP_VERIF:\n        return \"OP_VERIF\";\n    case OP_VERNOTIF:\n        return \"OP_VERNOTIF\";\n    case OP_ELSE:\n        return \"OP_ELSE\";\n    case OP_ENDIF:\n        return \"OP_ENDIF\";\n    case OP_VERIFY:\n        return \"OP_VERIFY\";\n    case OP_RETURN:\n        return \"OP_RETURN\";\n\n    // stack ops\n    case OP_TOALTSTACK:\n        return \"OP_TOALTSTACK\";\n    case OP_FROMALTSTACK:\n        return \"OP_FROMALTSTACK\";\n    case OP_2DROP:\n        return \"OP_2DROP\";\n    case OP_2DUP:\n        return \"OP_2DUP\";\n    case OP_3DUP:\n        return \"OP_3DUP\";\n    case OP_2OVER:\n        return \"OP_2OVER\";\n    case OP_2ROT:\n        return \"OP_2ROT\";\n    case OP_2SWAP:\n        return \"OP_2SWAP\";\n    case OP_IFDUP:\n        return \"OP_IFDUP\";\n    case OP_DEPTH:\n        return \"OP_DEPTH\";\n    case OP_DROP:\n        return \"OP_DROP\";\n    case OP_DUP:\n        return \"OP_DUP\";\n    case OP_NIP:\n        return \"OP_NIP\";\n    case OP_OVER:\n        return \"OP_OVER\";\n    case OP_PICK:\n        return \"OP_PICK\";\n    case OP_ROLL:\n        return \"OP_ROLL\";\n    case OP_ROT:\n        return \"OP_ROT\";\n    case OP_SWAP:\n        return \"OP_SWAP\";\n    case OP_TUCK:\n        return \"OP_TUCK\";\n\n    // splice ops\n    case OP_CAT:\n        return \"OP_CAT\";\n    case OP_SUBSTR:\n        return \"OP_SUBSTR\";\n    case OP_LEFT:\n        return \"OP_LEFT\";\n    case OP_RIGHT:\n        return \"OP_RIGHT\";\n    case OP_SIZE:\n        return \"OP_SIZE\";\n\n    // bit logic\n    case OP_INVERT:\n        return \"OP_INVERT\";\n    case OP_AND:\n        return \"OP_AND\";\n    case OP_OR:\n        return \"OP_OR\";\n    case OP_XOR:\n        return \"OP_XOR\";\n    case OP_EQUAL:\n        return \"OP_EQUAL\";\n    case OP_EQUALVERIFY:\n        return \"OP_EQUALVERIFY\";\n    case OP_RESERVED1:\n        return \"OP_RESERVED1\";\n    case OP_RESERVED2:\n        return \"OP_RESERVED2\";\n\n    // numeric\n    case OP_1ADD:\n        return \"OP_1ADD\";\n    case OP_1SUB:\n        return \"OP_1SUB\";\n    case OP_2MUL:\n        return \"OP_2MUL\";\n    case OP_2DIV:\n        return \"OP_2DIV\";\n    case OP_NEGATE:\n        return \"OP_NEGATE\";\n    case OP_ABS:\n        return \"OP_ABS\";\n    case OP_NOT:\n        return \"OP_NOT\";\n    case OP_0NOTEQUAL:\n        return \"OP_0NOTEQUAL\";\n    case OP_ADD:\n        return \"OP_ADD\";\n    case OP_SUB:\n        return \"OP_SUB\";\n    case OP_MUL:\n        return \"OP_MUL\";\n    case OP_DIV:\n        return \"OP_DIV\";\n    case OP_MOD:\n        return \"OP_MOD\";\n    case OP_LSHIFT:\n        return \"OP_LSHIFT\";\n    case OP_RSHIFT:\n        return \"OP_RSHIFT\";\n    case OP_BOOLAND:\n        return \"OP_BOOLAND\";\n    case OP_BOOLOR:\n        return \"OP_BOOLOR\";\n    case OP_NUMEQUAL:\n        return \"OP_NUMEQUAL\";\n    case OP_NUMEQUALVERIFY:\n        return \"OP_NUMEQUALVERIFY\";\n    case OP_NUMNOTEQUAL:\n        return \"OP_NUMNOTEQUAL\";\n    case OP_LESSTHAN:\n        return \"OP_LESSTHAN\";\n    case OP_GREATERTHAN:\n        return \"OP_GREATERTHAN\";\n    case OP_LESSTHANOREQUAL:\n        return \"OP_LESSTHANOREQUAL\";\n    case OP_GREATERTHANOREQUAL:\n        return \"OP_GREATERTHANOREQUAL\";\n    case OP_MIN:\n        return \"OP_MIN\";\n    case OP_MAX:\n        return \"OP_MAX\";\n    case OP_WITHIN:\n        return \"OP_WITHIN\";\n\n    // crypto\n    case OP_RIPEMD160:\n        return \"OP_RIPEMD160\";\n    case OP_SHA1:\n        return \"OP_SHA1\";\n    case OP_SHA256:\n        return \"OP_SHA256\";\n    case OP_HASH160:\n        return \"OP_HASH160\";\n    case OP_HASH256:\n        return \"OP_HASH256\";\n    case OP_CODESEPARATOR:\n        return \"OP_CODESEPARATOR\";\n    case OP_CHECKSIG:\n        return \"OP_CHECKSIG\";\n    case OP_CHECKSIGVERIFY:\n        return \"OP_CHECKSIGVERIFY\";\n    case OP_CHECKMULTISIG:\n        return \"OP_CHECKMULTISIG\";\n    case OP_CHECKMULTISIGVERIFY:\n        return \"OP_CHECKMULTISIGVERIFY\";\n\n    // expanson\n    case OP_NOP1:\n        return \"OP_NOP1\";\n    case OP_CHECKLOCKTIMEVERIFY:\n        return \"OP_CHECKLOCKTIMEVERIFY\";\n    case OP_CHECKATTENUATIONVERIFY:\n        return \"OP_CHECKATTENUATIONVERIFY\";\n    case OP_NOP4:\n        return \"OP_NOP4\";\n    case OP_NOP5:\n        return \"OP_NOP5\";\n    case OP_NOP6:\n        return \"OP_NOP6\";\n    case OP_NOP7:\n        return \"OP_NOP7\";\n    case OP_NOP8:\n        return \"OP_NOP8\";\n    case OP_NOP9:\n        return \"OP_NOP9\";\n    case OP_NOP10:\n        return \"OP_NOP10\";\n\n    case OP_INVALIDOPCODE:\n        return \"OP_INVALIDOPCODE\";\n\n        // Note:\n        //  The template matching params OP_SMALLINTEGER/etc are defined in opcodetype enum\n        //  as kind of implementation hack, they are *NOT* real opcodes.  If found in real\n        //  Script, just let the default: case deal with them.\n\n    default:\n        return \"OP_UNKNOWN\";\n    }\n}\n\nunsigned int CScript::GetSigOpCount(bool fAccurate) const\n{\n    unsigned int n = 0;\n    const_iterator pc = begin();\n    opcodetype lastOpcode = OP_INVALIDOPCODE;\n    while (pc < end())\n    {\n        opcodetype opcode;\n        if (!GetOp(pc, opcode))\n            break;\n        if (opcode == OP_CHECKSIG || opcode == OP_CHECKSIGVERIFY)\n            n++;\n        else if (opcode == OP_CHECKMULTISIG || opcode == OP_CHECKMULTISIGVERIFY)\n        {\n            if (fAccurate && lastOpcode >= OP_1 && lastOpcode <= OP_16)\n                n += DecodeOP_N(lastOpcode);\n            else\n                n += MAX_PUBKEYS_PER_MULTISIG;\n        }\n        lastOpcode = opcode;\n    }\n    return n;\n}\n\nunsigned int CScript::GetSigOpCount(const CScript &scriptSig) const\n{\n    if (!IsPayToScriptHash())\n        return GetSigOpCount(true);\n\n    // This is a pay-to-script-hash scriptPubKey;\n    // get the last item that the scriptSig\n    // pushes onto the stack:\n    const_iterator pc = scriptSig.begin();\n    vector<unsigned char> data;\n    while (pc < scriptSig.end())\n    {\n        opcodetype opcode;\n        if (!scriptSig.GetOp(pc, opcode, data))\n            return 0;\n        if (opcode > OP_16)\n            return 0;\n    }\n\n    /// ... and return its opcount:\n    CScript subscript(data.begin(), data.end());\n    return subscript.GetSigOpCount(true);\n}\n\nbool CScript::IsPayToScriptHash() const\n{\n    // Extra-fast test for pay-to-script-hash CScripts:\n    return (this->size() == 23 &&\n            (*this)[0] == OP_HASH160 &&\n            (*this)[1] == 0x14 &&\n            (*this)[22] == OP_EQUAL);\n}\n\nbool CScript::IsPushOnly(const_iterator pc) const\n{\n    while (pc < end())\n    {\n        opcodetype opcode;\n        if (!GetOp(pc, opcode))\n            return false;\n        // Note that IsPushOnly() *does* consider OP_RESERVED to be a\n        // push-type opcode, however execution of OP_RESERVED fails, so\n        // it's not relevant to P2SH/BIP62 as the scriptSig would fail prior to\n        // the P2SH special validation code being executed.\n        if (opcode > OP_16)\n            return false;\n    }\n    return true;\n}\n\nbool CScript::IsPushOnly() const\n{\n    return this->IsPushOnly(begin());\n}\n"
  },
  {
    "path": "src/UChainService/consensus/clone/script/script.h",
    "content": "// Copyright (c) 2009-2010 Satoshi Nakamoto\n// Copyright (c) 2009-2015 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#ifndef BITCOIN_SCRIPT_SCRIPT_H\n#define BITCOIN_SCRIPT_SCRIPT_H\n\n#include \"crypto/common.h\"\n#include \"prevector.h\"\n\n#include <assert.h>\n#include <climits>\n#include <limits>\n#include <stdexcept>\n#include <stdint.h>\n#include <string.h>\n#include <string>\n#include <vector>\n\n// Maximum number of bytes pushable to the stack\nstatic const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520;\n\n// Maximum number of non-push operations per script\nstatic const int MAX_OPS_PER_SCRIPT = 201;\n\n// Maximum number of public keys per multisig\nstatic const int MAX_PUBKEYS_PER_MULTISIG = 20;\n\n// Threshold for nLockTime: below this value it is interpreted as block number,\n// otherwise as UNIX timestamp.\nstatic const unsigned int LOCKTIME_THRESHOLD = 500000000; // Tue Nov  5 00:53:20 1985 UTC\n\ntemplate <typename T>\nstd::vector<unsigned char> ToByteVector(const T &in)\n{\n    return std::vector<unsigned char>(in.begin(), in.end());\n}\n\n/** Script opcodes */\nenum opcodetype\n{\n    // push value\n    OP_0 = 0x00,\n    OP_FALSE = OP_0,\n    OP_PUSHDATA1 = 0x4c,\n    OP_PUSHDATA2 = 0x4d,\n    OP_PUSHDATA4 = 0x4e,\n    OP_1NEGATE = 0x4f,\n    OP_RESERVED = 0x50,\n    OP_1 = 0x51,\n    OP_TRUE = OP_1,\n    OP_2 = 0x52,\n    OP_3 = 0x53,\n    OP_4 = 0x54,\n    OP_5 = 0x55,\n    OP_6 = 0x56,\n    OP_7 = 0x57,\n    OP_8 = 0x58,\n    OP_9 = 0x59,\n    OP_10 = 0x5a,\n    OP_11 = 0x5b,\n    OP_12 = 0x5c,\n    OP_13 = 0x5d,\n    OP_14 = 0x5e,\n    OP_15 = 0x5f,\n    OP_16 = 0x60,\n\n    // control\n    OP_NOP = 0x61,\n    OP_VER = 0x62,\n    OP_IF = 0x63,\n    OP_NOTIF = 0x64,\n    OP_VERIF = 0x65,\n    OP_VERNOTIF = 0x66,\n    OP_ELSE = 0x67,\n    OP_ENDIF = 0x68,\n    OP_VERIFY = 0x69,\n    OP_RETURN = 0x6a,\n\n    // stack ops\n    OP_TOALTSTACK = 0x6b,\n    OP_FROMALTSTACK = 0x6c,\n    OP_2DROP = 0x6d,\n    OP_2DUP = 0x6e,\n    OP_3DUP = 0x6f,\n    OP_2OVER = 0x70,\n    OP_2ROT = 0x71,\n    OP_2SWAP = 0x72,\n    OP_IFDUP = 0x73,\n    OP_DEPTH = 0x74,\n    OP_DROP = 0x75,\n    OP_DUP = 0x76,\n    OP_NIP = 0x77,\n    OP_OVER = 0x78,\n    OP_PICK = 0x79,\n    OP_ROLL = 0x7a,\n    OP_ROT = 0x7b,\n    OP_SWAP = 0x7c,\n    OP_TUCK = 0x7d,\n\n    // splice ops\n    OP_CAT = 0x7e,\n    OP_SUBSTR = 0x7f,\n    OP_LEFT = 0x80,\n    OP_RIGHT = 0x81,\n    OP_SIZE = 0x82,\n\n    // bit logic\n    OP_INVERT = 0x83,\n    OP_AND = 0x84,\n    OP_OR = 0x85,\n    OP_XOR = 0x86,\n    OP_EQUAL = 0x87,\n    OP_EQUALVERIFY = 0x88,\n    OP_RESERVED1 = 0x89,\n    OP_RESERVED2 = 0x8a,\n\n    // numeric\n    OP_1ADD = 0x8b,\n    OP_1SUB = 0x8c,\n    OP_2MUL = 0x8d,\n    OP_2DIV = 0x8e,\n    OP_NEGATE = 0x8f,\n    OP_ABS = 0x90,\n    OP_NOT = 0x91,\n    OP_0NOTEQUAL = 0x92,\n\n    OP_ADD = 0x93,\n    OP_SUB = 0x94,\n    OP_MUL = 0x95,\n    OP_DIV = 0x96,\n    OP_MOD = 0x97,\n    OP_LSHIFT = 0x98,\n    OP_RSHIFT = 0x99,\n\n    OP_BOOLAND = 0x9a,\n    OP_BOOLOR = 0x9b,\n    OP_NUMEQUAL = 0x9c,\n    OP_NUMEQUALVERIFY = 0x9d,\n    OP_NUMNOTEQUAL = 0x9e,\n    OP_LESSTHAN = 0x9f,\n    OP_GREATERTHAN = 0xa0,\n    OP_LESSTHANOREQUAL = 0xa1,\n    OP_GREATERTHANOREQUAL = 0xa2,\n    OP_MIN = 0xa3,\n    OP_MAX = 0xa4,\n\n    OP_WITHIN = 0xa5,\n\n    // crypto\n    OP_RIPEMD160 = 0xa6,\n    OP_SHA1 = 0xa7,\n    OP_SHA256 = 0xa8,\n    OP_HASH160 = 0xa9,\n    OP_HASH256 = 0xaa,\n    OP_CODESEPARATOR = 0xab,\n    OP_CHECKSIG = 0xac,\n    OP_CHECKSIGVERIFY = 0xad,\n    OP_CHECKMULTISIG = 0xae,\n    OP_CHECKMULTISIGVERIFY = 0xaf,\n\n    // expansion\n    OP_NOP1 = 0xb0,\n    OP_CHECKLOCKTIMEVERIFY = 0xb1,\n    OP_NOP2 = OP_CHECKLOCKTIMEVERIFY,\n    OP_NOP3 = 0xb2,\n    OP_CHECKATTENUATIONVERIFY = OP_NOP3,\n    OP_NOP4 = 0xb3,\n    OP_NOP5 = 0xb4,\n    OP_NOP6 = 0xb5,\n    OP_NOP7 = 0xb6,\n    OP_NOP8 = 0xb7,\n    OP_NOP9 = 0xb8,\n    OP_NOP10 = 0xb9,\n\n    // template matching params\n    OP_SMALLINTEGER = 0xfa,\n    OP_PUBKEYS = 0xfb,\n    OP_PUBKEYHASH = 0xfd,\n    OP_PUBKEY = 0xfe,\n\n    OP_INVALIDOPCODE = 0xff,\n};\n\nconst char *GetOpName(opcodetype opcode);\n\nclass scriptnum_error : public std::runtime_error\n{\n  public:\n    explicit scriptnum_error(const std::string &str) : std::runtime_error(str) {}\n};\n\nclass CScriptNum\n{\n    /**\n * Numeric opcodes (OP_1ADD, etc) are restricted to operating on 4-byte integers.\n * The semantics are subtle, though: operands must be in the range [-2^31 +1...2^31 -1],\n * but results may overflow (and are valid as long as they are not used in a subsequent\n * numeric operation). CScriptNum enforces those semantics by storing results as\n * an int64 and allowing out-of-range values to be returned as a vector of bytes but\n * throwing an exception if arithmetic is done or the result is interpreted as an integer.\n */\n  public:\n    explicit CScriptNum(const int64_t &n)\n    {\n        m_value = n;\n    }\n\n    static const size_t nDefaultMaxNumSize = 4;\n\n    explicit CScriptNum(const std::vector<unsigned char> &vch, bool fRequireMinimal,\n                        const size_t nMaxNumSize = nDefaultMaxNumSize)\n    {\n        if (vch.size() > nMaxNumSize)\n        {\n            throw scriptnum_error(\"script number overflow\");\n        }\n        if (fRequireMinimal && vch.size() > 0)\n        {\n            // Check that the number is encoded with the minimum possible\n            // number of bytes.\n            //\n            // If the most-significant-byte - excluding the sign bit - is zero\n            // then we're not minimal. Note how this test also rejects the\n            // negative-zero encoding, 0x80.\n            if ((vch.back() & 0x7f) == 0)\n            {\n                // One exception: if there's more than one byte and the most\n                // significant bit of the second-most-significant-byte is set\n                // it would conflict with the sign bit. An example of this case\n                // is +-255, which encode to 0xff00 and 0xff80 respectively.\n                // (big-endian).\n                if (vch.size() <= 1 || (vch[vch.size() - 2] & 0x80) == 0)\n                {\n                    throw scriptnum_error(\"non-minimally encoded script number\");\n                }\n            }\n        }\n        m_value = set_vch(vch);\n    }\n\n    inline bool operator==(const int64_t &rhs) const { return m_value == rhs; }\n    inline bool operator!=(const int64_t &rhs) const { return m_value != rhs; }\n    inline bool operator<=(const int64_t &rhs) const { return m_value <= rhs; }\n    inline bool operator<(const int64_t &rhs) const { return m_value < rhs; }\n    inline bool operator>=(const int64_t &rhs) const { return m_value >= rhs; }\n    inline bool operator>(const int64_t &rhs) const { return m_value > rhs; }\n\n    inline bool operator==(const CScriptNum &rhs) const { return operator==(rhs.m_value); }\n    inline bool operator!=(const CScriptNum &rhs) const { return operator!=(rhs.m_value); }\n    inline bool operator<=(const CScriptNum &rhs) const { return operator<=(rhs.m_value); }\n    inline bool operator<(const CScriptNum &rhs) const { return operator<(rhs.m_value); }\n    inline bool operator>=(const CScriptNum &rhs) const { return operator>=(rhs.m_value); }\n    inline bool operator>(const CScriptNum &rhs) const { return operator>(rhs.m_value); }\n\n    inline CScriptNum operator+(const int64_t &rhs) const { return CScriptNum(m_value + rhs); }\n    inline CScriptNum operator-(const int64_t &rhs) const { return CScriptNum(m_value - rhs); }\n    inline CScriptNum operator+(const CScriptNum &rhs) const { return operator+(rhs.m_value); }\n    inline CScriptNum operator-(const CScriptNum &rhs) const { return operator-(rhs.m_value); }\n\n    inline CScriptNum &operator+=(const CScriptNum &rhs) { return operator+=(rhs.m_value); }\n    inline CScriptNum &operator-=(const CScriptNum &rhs) { return operator-=(rhs.m_value); }\n\n    inline CScriptNum operator-() const\n    {\n        assert(m_value != std::numeric_limits<int64_t>::min());\n        return CScriptNum(-m_value);\n    }\n\n    inline CScriptNum &operator=(const int64_t &rhs)\n    {\n        m_value = rhs;\n        return *this;\n    }\n\n    inline CScriptNum &operator+=(const int64_t &rhs)\n    {\n        assert(rhs == 0 || (rhs > 0 && m_value <= std::numeric_limits<int64_t>::max() - rhs) ||\n               (rhs < 0 && m_value >= std::numeric_limits<int64_t>::min() - rhs));\n        m_value += rhs;\n        return *this;\n    }\n\n    inline CScriptNum &operator-=(const int64_t &rhs)\n    {\n        assert(rhs == 0 || (rhs > 0 && m_value >= std::numeric_limits<int64_t>::min() + rhs) ||\n               (rhs < 0 && m_value <= std::numeric_limits<int64_t>::max() + rhs));\n        m_value -= rhs;\n        return *this;\n    }\n\n    int getint() const\n    {\n        if (m_value > std::numeric_limits<int>::max())\n            return std::numeric_limits<int>::max();\n        else if (m_value < std::numeric_limits<int>::min())\n            return std::numeric_limits<int>::min();\n        return m_value;\n    }\n\n    std::vector<unsigned char> getvch() const\n    {\n        return serialize(m_value);\n    }\n\n    static std::vector<unsigned char> serialize(const int64_t &value)\n    {\n        if (value == 0)\n            return std::vector<unsigned char>();\n\n        std::vector<unsigned char> result;\n        const bool neg = value < 0;\n        uint64_t absvalue = neg ? -value : value;\n\n        while (absvalue)\n        {\n            result.push_back(absvalue & 0xff);\n            absvalue >>= 8;\n        }\n\n        //    - If the most significant byte is >= 0x80 and the value is positive, push a\n        //    new zero-byte to make the significant byte < 0x80 again.\n\n        //    - If the most significant byte is >= 0x80 and the value is negative, push a\n        //    new 0x80 byte that will be popped off when converting to an integral.\n\n        //    - If the most significant byte is < 0x80 and the value is negative, add\n        //    0x80 to it, since it will be subtracted and interpreted as a negative when\n        //    converting to an integral.\n\n        if (result.back() & 0x80)\n            result.push_back(neg ? 0x80 : 0);\n        else if (neg)\n            result.back() |= 0x80;\n\n        return result;\n    }\n\n  private:\n    static int64_t set_vch(const std::vector<unsigned char> &vch)\n    {\n        if (vch.empty())\n            return 0;\n\n        int64_t result = 0;\n        for (size_t i = 0; i != vch.size(); ++i)\n            result |= static_cast<int64_t>(vch[i]) << 8 * i;\n\n        // If the input vector's most significant byte is 0x80, remove it from\n        // the result's msb and return a negative.\n        if (vch.back() & 0x80)\n            return -((int64_t)(result & ~(0x80ULL << (8 * (vch.size() - 1)))));\n\n        return result;\n    }\n\n    int64_t m_value;\n};\n\ntypedef prevector<28, unsigned char> CScriptBase;\n\n/** Serialized script, used inside transaction inputs and outputs */\nclass CScript : public CScriptBase\n{\n  protected:\n    CScript &push_int64(int64_t n)\n    {\n        if (n == -1 || (n >= 1 && n <= 16))\n        {\n            push_back(n + (OP_1 - 1));\n        }\n        else if (n == 0)\n        {\n            push_back(OP_0);\n        }\n        else\n        {\n            *this << CScriptNum::serialize(n);\n        }\n        return *this;\n    }\n\n  public:\n    CScript() {}\n    CScript(const CScript &b) : CScriptBase(b.begin(), b.end()) {}\n    CScript(const_iterator pbegin, const_iterator pend) : CScriptBase(pbegin, pend) {}\n    CScript(std::vector<unsigned char>::const_iterator pbegin, std::vector<unsigned char>::const_iterator pend) : CScriptBase(pbegin, pend) {}\n    CScript(const unsigned char *pbegin, const unsigned char *pend) : CScriptBase(pbegin, pend) {}\n\n    CScript &operator+=(const CScript &b)\n    {\n        insert(end(), b.begin(), b.end());\n        return *this;\n    }\n\n    friend CScript operator+(const CScript &a, const CScript &b)\n    {\n        CScript ret = a;\n        ret += b;\n        return ret;\n    }\n\n    CScript(int64_t b) { operator<<(b); }\n\n    explicit CScript(opcodetype b) { operator<<(b); }\n    explicit CScript(const CScriptNum &b) { operator<<(b); }\n    explicit CScript(const std::vector<unsigned char> &b) { operator<<(b); }\n\n    CScript &operator<<(int64_t b) { return push_int64(b); }\n\n    CScript &operator<<(opcodetype opcode)\n    {\n        if (opcode < 0 || opcode > 0xff)\n            throw std::runtime_error(\"CScript::operator<<(): invalid opcode\");\n        insert(end(), (unsigned char)opcode);\n        return *this;\n    }\n\n    CScript &operator<<(const CScriptNum &b)\n    {\n        *this << b.getvch();\n        return *this;\n    }\n\n    CScript &operator<<(const std::vector<unsigned char> &b)\n    {\n        if (b.size() < OP_PUSHDATA1)\n        {\n            insert(end(), (unsigned char)b.size());\n        }\n        else if (b.size() <= 0xff)\n        {\n            insert(end(), OP_PUSHDATA1);\n            insert(end(), (unsigned char)b.size());\n        }\n        else if (b.size() <= 0xffff)\n        {\n            insert(end(), OP_PUSHDATA2);\n            uint8_t data[2];\n            WriteLE16(data, b.size());\n            insert(end(), data, data + sizeof(data));\n        }\n        else\n        {\n            insert(end(), OP_PUSHDATA4);\n            uint8_t data[4];\n            WriteLE32(data, b.size());\n            insert(end(), data, data + sizeof(data));\n        }\n        insert(end(), b.begin(), b.end());\n        return *this;\n    }\n\n    CScript &operator<<(const CScript &b)\n    {\n        // I'm not sure if this should push the script or concatenate scripts.\n        // If there's ever a use for pushing a script onto a script, delete this member fn\n        assert(!\"Warning: Pushing a CScript onto a CScript with << is probably not intended, use + to concatenate!\");\n        return *this;\n    }\n\n    bool GetOp(iterator &pc, opcodetype &opcodeRet, std::vector<unsigned char> &vchRet)\n    {\n        // Wrapper so it can be called with either iterator or const_iterator\n        const_iterator pc2 = pc;\n        bool fRet = GetOp2(pc2, opcodeRet, &vchRet);\n        pc = begin() + (pc2 - begin());\n        return fRet;\n    }\n\n    bool GetOp(iterator &pc, opcodetype &opcodeRet)\n    {\n        const_iterator pc2 = pc;\n        bool fRet = GetOp2(pc2, opcodeRet, NULL);\n        pc = begin() + (pc2 - begin());\n        return fRet;\n    }\n\n    bool GetOp(const_iterator &pc, opcodetype &opcodeRet, std::vector<unsigned char> &vchRet) const\n    {\n        return GetOp2(pc, opcodeRet, &vchRet);\n    }\n\n    bool GetOp(const_iterator &pc, opcodetype &opcodeRet) const\n    {\n        return GetOp2(pc, opcodeRet, NULL);\n    }\n\n    bool GetOp2(const_iterator &pc, opcodetype &opcodeRet, std::vector<unsigned char> *pvchRet) const\n    {\n        opcodeRet = OP_INVALIDOPCODE;\n        if (pvchRet)\n            pvchRet->clear();\n        if (pc >= end())\n            return false;\n\n        // Read instruction\n        if (end() - pc < 1)\n            return false;\n        unsigned int opcode = *pc++;\n\n        // Immediate operand\n        if (opcode <= OP_PUSHDATA4)\n        {\n            unsigned int nSize = 0;\n            if (opcode < OP_PUSHDATA1)\n            {\n                nSize = opcode;\n            }\n            else if (opcode == OP_PUSHDATA1)\n            {\n                if (end() - pc < 1)\n                    return false;\n                nSize = *pc++;\n            }\n            else if (opcode == OP_PUSHDATA2)\n            {\n                if (end() - pc < 2)\n                    return false;\n                nSize = ReadLE16(&pc[0]);\n                pc += 2;\n            }\n            else if (opcode == OP_PUSHDATA4)\n            {\n                if (end() - pc < 4)\n                    return false;\n                nSize = ReadLE32(&pc[0]);\n                pc += 4;\n            }\n            if (end() - pc < 0 || (unsigned int)(end() - pc) < nSize)\n                return false;\n            if (pvchRet)\n                pvchRet->assign(pc, pc + nSize);\n            pc += nSize;\n        }\n\n        opcodeRet = (opcodetype)opcode;\n        return true;\n    }\n\n    /** Encode/decode small integers: */\n    static int DecodeOP_N(opcodetype opcode)\n    {\n        if (opcode == OP_0)\n            return 0;\n        assert(opcode >= OP_1 && opcode <= OP_16);\n        return (int)opcode - (int)(OP_1 - 1);\n    }\n    static opcodetype EncodeOP_N(int n)\n    {\n        assert(n >= 0 && n <= 16);\n        if (n == 0)\n            return OP_0;\n        return (opcodetype)(OP_1 + n - 1);\n    }\n\n    int FindAndDelete(const CScript &b)\n    {\n        int nFound = 0;\n        if (b.empty())\n            return nFound;\n        iterator pc = begin();\n        opcodetype opcode;\n        do\n        {\n            while (end() - pc >= (long)b.size() && memcmp(&pc[0], &b[0], b.size()) == 0)\n            {\n                pc = erase(pc, pc + b.size());\n                ++nFound;\n            }\n        } while (GetOp(pc, opcode));\n        return nFound;\n    }\n    int Find(opcodetype op) const\n    {\n        int nFound = 0;\n        opcodetype opcode;\n        for (const_iterator pc = begin(); pc != end() && GetOp(pc, opcode);)\n            if (opcode == op)\n                ++nFound;\n        return nFound;\n    }\n\n    /**\n     * Pre-version-0.6, Bitcoin always counted CHECKMULTISIGs\n     * as 20 sigops. With pay-to-script-hash, that changed:\n     * CHECKMULTISIGs serialized in scriptSigs are\n     * counted more accurately, assuming they are of the form\n     *  ... OP_N CHECKMULTISIG ...\n     */\n    unsigned int GetSigOpCount(bool fAccurate) const;\n\n    /**\n     * Accurately count sigOps, including sigOps in\n     * pay-to-script-hash transactions:\n     */\n    unsigned int GetSigOpCount(const CScript &scriptSig) const;\n\n    bool IsPayToScriptHash() const;\n\n    /** Called by IsStandardTx and P2SH/BIP62 VerifyScript (which makes it consensus-critical). */\n    bool IsPushOnly(const_iterator pc) const;\n    bool IsPushOnly() const;\n\n    /**\n     * Returns whether the script is guaranteed to fail at execution,\n     * regardless of the initial stack. This allows outputs to be pruned\n     * instantly when entering the UTXO set.\n     */\n    bool IsUnspendable() const\n    {\n        return (size() > 0 && *begin() == OP_RETURN);\n    }\n\n    void clear()\n    {\n        // The default std::vector::clear() does not release memory.\n        CScriptBase().swap(*this);\n    }\n};\n\nclass CReserveScript\n{\n  public:\n    CScript reserveScript;\n    virtual void KeepScript() {}\n    CReserveScript() {}\n    virtual ~CReserveScript() {}\n};\n\n#endif // BITCOIN_SCRIPT_SCRIPT_H\n"
  },
  {
    "path": "src/UChainService/consensus/clone/script/script_error.h",
    "content": "// Copyright (c) 2009-2010 Satoshi Nakamoto\n// Copyright (c) 2009-2014 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#ifndef BITCOIN_SCRIPT_SCRIPT_ERROR_H\n#define BITCOIN_SCRIPT_SCRIPT_ERROR_H\n\ntypedef enum ScriptError_t\n{\n    SCRIPT_ERR_OK = 0,\n    SCRIPT_ERR_UNKNOWN_ERROR,\n    SCRIPT_ERR_EVAL_FALSE,\n    SCRIPT_ERR_OP_RETURN,\n\n    /* Max sizes */\n    SCRIPT_ERR_SCRIPT_SIZE,\n    SCRIPT_ERR_PUSH_SIZE,\n    SCRIPT_ERR_OP_COUNT,\n    SCRIPT_ERR_STACK_SIZE,\n    SCRIPT_ERR_SIG_COUNT,\n    SCRIPT_ERR_PUBKEY_COUNT,\n\n    /* Failed verify operations */\n    SCRIPT_ERR_VERIFY,\n    SCRIPT_ERR_EQUALVERIFY,\n    SCRIPT_ERR_CHECKMULTISIGVERIFY,\n    SCRIPT_ERR_CHECKSIGVERIFY,\n    SCRIPT_ERR_NUMEQUALVERIFY,\n\n    /* Logical/Format/Canonical errors */\n    SCRIPT_ERR_BAD_OPCODE,\n    SCRIPT_ERR_DISABLED_OPCODE,\n    SCRIPT_ERR_INVALID_STACK_OPERATION,\n    SCRIPT_ERR_INVALID_ALTSTACK_OPERATION,\n    SCRIPT_ERR_UNBALANCED_CONDITIONAL,\n\n    /* OP_CHECKLOCKTIMEVERIFY */\n    SCRIPT_ERR_NEGATIVE_LOCKTIME,\n    SCRIPT_ERR_UNSATISFIED_LOCKTIME,\n\n    /* BIP62 */\n    SCRIPT_ERR_SIG_HASHTYPE,\n    SCRIPT_ERR_SIG_DER,\n    SCRIPT_ERR_MINIMALDATA,\n    SCRIPT_ERR_SIG_PUSHONLY,\n    SCRIPT_ERR_SIG_HIGH_S,\n    SCRIPT_ERR_SIG_NULLDUMMY,\n    SCRIPT_ERR_PUBKEYTYPE,\n    SCRIPT_ERR_CLEANSTACK,\n\n    /* softfork safeness */\n    SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS,\n\n    /* OP_CHECKATTENUATIONVERIFY */\n    SCRIPT_ERR_INVALID_MODEL_PARAM,\n\n    SCRIPT_ERR_ERROR_COUNT\n} ScriptError;\n\n#define SCRIPT_ERR_LAST SCRIPT_ERR_ERROR_COUNT\n\nconst char *ScriptErrorString(const ScriptError error);\n\n#endif // BITCOIN_SCRIPT_SCRIPT_ERROR_H\n"
  },
  {
    "path": "src/UChainService/consensus/clone/serialize.h",
    "content": "// Copyright (c) 2009-2010 Satoshi Nakamoto\n// Copyright (c) 2009-2015 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#ifndef BITCOIN_SERIALIZE_H\n#define BITCOIN_SERIALIZE_H\n\n#include \"compat/endian.h\"\n\n#include <algorithm>\n#include <assert.h>\n#include <ios>\n#include <limits>\n#include <map>\n#include <set>\n#include <stdint.h>\n#include <string>\n#include <string.h>\n#include <utility>\n#include <vector>\n\n#include \"prevector.h\"\n\nstatic const unsigned int MAX_SIZE = 0x02000000;\n\n/**\n * Used to bypass the rule against non-const reference to temporary\n * where it makes sense with wrappers such as CFlatData or CTxDB\n */\ntemplate <typename T>\ninline T &REF(const T &val)\n{\n    return const_cast<T &>(val);\n}\n\n/**\n * Used to acquire a non-const pointer \"this\" to generate bodies\n * of const serialization operations from a template\n */\ntemplate <typename T>\ninline T *NCONST_PTR(const T *val)\n{\n    return const_cast<T *>(val);\n}\n\n/**\n * Get begin pointer of vector (non-const version).\n * @note These functions avoid the undefined case of indexing into an empty\n * vector, as well as that of indexing after the end of the vector.\n */\ntemplate <typename V>\ninline typename V::value_type *begin_ptr(V &v)\n{\n    return v.empty() ? NULL : &v[0];\n}\n/** Get begin pointer of vector (const version) */\ntemplate <typename V>\ninline const typename V::value_type *begin_ptr(const V &v)\n{\n    return v.empty() ? NULL : &v[0];\n}\n/** Get end pointer of vector (non-const version) */\ntemplate <typename V>\ninline typename V::value_type *end_ptr(V &v)\n{\n    return v.empty() ? NULL : (&v[0] + v.size());\n}\n/** Get end pointer of vector (const version) */\ntemplate <typename V>\ninline const typename V::value_type *end_ptr(const V &v)\n{\n    return v.empty() ? NULL : (&v[0] + v.size());\n}\n\n/*\n * Lowest-level serialization and conversion.\n * @note Sizes of these types are verified in the tests\n */\ntemplate <typename Stream>\ninline void ser_writedata8(Stream &s, uint8_t obj)\n{\n    s.write((char *)&obj, 1);\n}\ntemplate <typename Stream>\ninline void ser_writedata16(Stream &s, uint16_t obj)\n{\n    obj = htole16(obj);\n    s.write((char *)&obj, 2);\n}\ntemplate <typename Stream>\ninline void ser_writedata32(Stream &s, uint32_t obj)\n{\n    obj = htole32(obj);\n    s.write((char *)&obj, 4);\n}\ntemplate <typename Stream>\ninline void ser_writedata64(Stream &s, uint64_t obj)\n{\n    obj = htole64(obj);\n    s.write((char *)&obj, 8);\n}\ntemplate <typename Stream>\ninline uint8_t ser_readdata8(Stream &s)\n{\n    uint8_t obj;\n    s.read((char *)&obj, 1);\n    return obj;\n}\ntemplate <typename Stream>\ninline uint16_t ser_readdata16(Stream &s)\n{\n    uint16_t obj;\n    s.read((char *)&obj, 2);\n    return le16toh(obj);\n}\ntemplate <typename Stream>\ninline uint32_t ser_readdata32(Stream &s)\n{\n    uint32_t obj;\n    s.read((char *)&obj, 4);\n    return le32toh(obj);\n}\ntemplate <typename Stream>\ninline uint64_t ser_readdata64(Stream &s)\n{\n    uint64_t obj;\n    s.read((char *)&obj, 8);\n    return le64toh(obj);\n}\ninline uint64_t ser_double_to_uint64(double x)\n{\n    union {\n        double x;\n        uint64_t y;\n    } tmp;\n    tmp.x = x;\n    return tmp.y;\n}\ninline uint32_t ser_float_to_uint32(float x)\n{\n    union {\n        float x;\n        uint32_t y;\n    } tmp;\n    tmp.x = x;\n    return tmp.y;\n}\ninline double ser_uint64_to_double(uint64_t y)\n{\n    union {\n        double x;\n        uint64_t y;\n    } tmp;\n    tmp.y = y;\n    return tmp.x;\n}\ninline float ser_uint32_to_float(uint32_t y)\n{\n    union {\n        float x;\n        uint32_t y;\n    } tmp;\n    tmp.y = y;\n    return tmp.x;\n}\n\n/////////////////////////////////////////////////////////////////\n//\n// Templates for serializing to anything that looks like a stream,\n// i.e. anything that supports .read(char*, size_t) and .write(char*, size_t)\n//\n\nenum\n{\n    // primary actions\n    SER_NETWORK = (1 << 0),\n    SER_DISK = (1 << 1),\n    SER_GETHASH = (1 << 2),\n};\n\n#define READWRITE(obj) (::SerReadWrite(s, (obj), nType, nVersion, ser_action))\n\n/**\n * Implement three methods for serializable objects. These are actually wrappers over\n * \"SerializationOp\" template, which implements the body of each class' serialization\n * code. Adding \"ADD_SERIALIZE_METHODS\" in the body of the class causes these wrappers to be\n * added as members.\n */\n#define ADD_SERIALIZE_METHODS                                                         \\\n    size_t GetSerializeSize(int nType, int nVersion) const                            \\\n    {                                                                                 \\\n        CSizeComputer s(nType, nVersion);                                             \\\n        NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize(), nType, nVersion); \\\n        return s.size();                                                              \\\n    }                                                                                 \\\n    template <typename Stream>                                                        \\\n    void Serialize(Stream &s, int nType, int nVersion) const                          \\\n    {                                                                                 \\\n        NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize(), nType, nVersion); \\\n    }                                                                                 \\\n    template <typename Stream>                                                        \\\n    void Unserialize(Stream &s, int nType, int nVersion)                              \\\n    {                                                                                 \\\n        SerializationOp(s, CSerActionUnserialize(), nType, nVersion);                 \\\n    }\n\n/*\n * Basic Types\n */\ninline unsigned int GetSerializeSize(char a, int, int = 0) { return 1; }\ninline unsigned int GetSerializeSize(int8_t a, int, int = 0) { return 1; }\ninline unsigned int GetSerializeSize(uint8_t a, int, int = 0) { return 1; }\ninline unsigned int GetSerializeSize(int16_t a, int, int = 0) { return 2; }\ninline unsigned int GetSerializeSize(uint16_t a, int, int = 0) { return 2; }\ninline unsigned int GetSerializeSize(int32_t a, int, int = 0) { return 4; }\ninline unsigned int GetSerializeSize(uint32_t a, int, int = 0) { return 4; }\ninline unsigned int GetSerializeSize(int64_t a, int, int = 0) { return 8; }\ninline unsigned int GetSerializeSize(uint64_t a, int, int = 0) { return 8; }\ninline unsigned int GetSerializeSize(float a, int, int = 0) { return 4; }\ninline unsigned int GetSerializeSize(double a, int, int = 0) { return 8; }\n\ntemplate <typename Stream>\ninline void Serialize(Stream &s, char a, int, int = 0) { ser_writedata8(s, a); } // TODO Get rid of bare char\ntemplate <typename Stream>\ninline void Serialize(Stream &s, int8_t a, int, int = 0) { ser_writedata8(s, a); }\ntemplate <typename Stream>\ninline void Serialize(Stream &s, uint8_t a, int, int = 0) { ser_writedata8(s, a); }\ntemplate <typename Stream>\ninline void Serialize(Stream &s, int16_t a, int, int = 0) { ser_writedata16(s, a); }\ntemplate <typename Stream>\ninline void Serialize(Stream &s, uint16_t a, int, int = 0) { ser_writedata16(s, a); }\ntemplate <typename Stream>\ninline void Serialize(Stream &s, int32_t a, int, int = 0) { ser_writedata32(s, a); }\ntemplate <typename Stream>\ninline void Serialize(Stream &s, uint32_t a, int, int = 0) { ser_writedata32(s, a); }\ntemplate <typename Stream>\ninline void Serialize(Stream &s, int64_t a, int, int = 0) { ser_writedata64(s, a); }\ntemplate <typename Stream>\ninline void Serialize(Stream &s, uint64_t a, int, int = 0) { ser_writedata64(s, a); }\ntemplate <typename Stream>\ninline void Serialize(Stream &s, float a, int, int = 0) { ser_writedata32(s, ser_float_to_uint32(a)); }\ntemplate <typename Stream>\ninline void Serialize(Stream &s, double a, int, int = 0) { ser_writedata64(s, ser_double_to_uint64(a)); }\n\ntemplate <typename Stream>\ninline void Unserialize(Stream &s, char &a, int, int = 0) { a = ser_readdata8(s); } // TODO Get rid of bare char\ntemplate <typename Stream>\ninline void Unserialize(Stream &s, int8_t &a, int, int = 0) { a = ser_readdata8(s); }\ntemplate <typename Stream>\ninline void Unserialize(Stream &s, uint8_t &a, int, int = 0) { a = ser_readdata8(s); }\ntemplate <typename Stream>\ninline void Unserialize(Stream &s, int16_t &a, int, int = 0) { a = ser_readdata16(s); }\ntemplate <typename Stream>\ninline void Unserialize(Stream &s, uint16_t &a, int, int = 0) { a = ser_readdata16(s); }\ntemplate <typename Stream>\ninline void Unserialize(Stream &s, int32_t &a, int, int = 0) { a = ser_readdata32(s); }\ntemplate <typename Stream>\ninline void Unserialize(Stream &s, uint32_t &a, int, int = 0) { a = ser_readdata32(s); }\ntemplate <typename Stream>\ninline void Unserialize(Stream &s, int64_t &a, int, int = 0) { a = ser_readdata64(s); }\ntemplate <typename Stream>\ninline void Unserialize(Stream &s, uint64_t &a, int, int = 0) { a = ser_readdata64(s); }\ntemplate <typename Stream>\ninline void Unserialize(Stream &s, float &a, int, int = 0) { a = ser_uint32_to_float(ser_readdata32(s)); }\ntemplate <typename Stream>\ninline void Unserialize(Stream &s, double &a, int, int = 0) { a = ser_uint64_to_double(ser_readdata64(s)); }\n\ninline unsigned int GetSerializeSize(bool a, int, int = 0) { return sizeof(char); }\ntemplate <typename Stream>\ninline void Serialize(Stream &s, bool a, int, int = 0)\n{\n    char f = a;\n    ser_writedata8(s, f);\n}\ntemplate <typename Stream>\ninline void Unserialize(Stream &s, bool &a, int, int = 0)\n{\n    char f = ser_readdata8(s);\n    a = f;\n}\n\n/**\n * Compact Size\n * size <  253        -- 1 byte\n * size <= USHRT_MAX  -- 3 bytes  (253 + 2 bytes)\n * size <= UINT_MAX   -- 5 bytes  (254 + 4 bytes)\n * size >  UINT_MAX   -- 9 bytes  (255 + 8 bytes)\n */\ninline unsigned int GetSizeOfCompactSize(uint64_t nSize)\n{\n    if (nSize < 253)\n        return sizeof(unsigned char);\n    else if (nSize <= std::numeric_limits<unsigned short>::max())\n        return sizeof(unsigned char) + sizeof(unsigned short);\n    else if (nSize <= std::numeric_limits<unsigned int>::max())\n        return sizeof(unsigned char) + sizeof(unsigned int);\n    else\n        return sizeof(unsigned char) + sizeof(uint64_t);\n}\n\ntemplate <typename Stream>\nvoid WriteCompactSize(Stream &os, uint64_t nSize)\n{\n    if (nSize < 253)\n    {\n        ser_writedata8(os, nSize);\n    }\n    else if (nSize <= std::numeric_limits<unsigned short>::max())\n    {\n        ser_writedata8(os, 253);\n        ser_writedata16(os, nSize);\n    }\n    else if (nSize <= std::numeric_limits<unsigned int>::max())\n    {\n        ser_writedata8(os, 254);\n        ser_writedata32(os, nSize);\n    }\n    else\n    {\n        ser_writedata8(os, 255);\n        ser_writedata64(os, nSize);\n    }\n    return;\n}\n\ntemplate <typename Stream>\nuint64_t ReadCompactSize(Stream &is)\n{\n    uint8_t chSize = ser_readdata8(is);\n    uint64_t nSizeRet = 0;\n    if (chSize < 253)\n    {\n        nSizeRet = chSize;\n    }\n    else if (chSize == 253)\n    {\n        nSizeRet = ser_readdata16(is);\n        if (nSizeRet < 253)\n            throw std::ios_base::failure(\"non-canonical ReadCompactSize()\");\n    }\n    else if (chSize == 254)\n    {\n        nSizeRet = ser_readdata32(is);\n        if (nSizeRet < 0x10000u)\n            throw std::ios_base::failure(\"non-canonical ReadCompactSize()\");\n    }\n    else\n    {\n        nSizeRet = ser_readdata64(is);\n        if (nSizeRet < 0x100000000ULL)\n            throw std::ios_base::failure(\"non-canonical ReadCompactSize()\");\n    }\n    if (nSizeRet > (uint64_t)MAX_SIZE)\n        throw std::ios_base::failure(\"ReadCompactSize(): size too large\");\n    return nSizeRet;\n}\n\n/**\n * Variable-length integers: bytes are a MSB base-128 encoding of the number.\n * The high bit in each byte signifies whether another digit follows. To make\n * sure the encoding is one-to-one, one is subtracted from all but the last digit.\n * Thus, the byte sequence a[] with length len, where all but the last byte\n * has bit 128 set, encodes the number:\n *\n *  (a[len-1] & 0x7F) + sum(i=1..len-1, 128^i*((a[len-i-1] & 0x7F)+1))\n *\n * Properties:\n * * Very small (0-127: 1 byte, 128-16511: 2 bytes, 16512-2113663: 3 bytes)\n * * Every integer has exactly one encoding\n * * Encoding does not depend on size of original integer type\n * * No redundancy: every (infinite) byte sequence corresponds to a list\n *   of encoded integers.\n *\n * 0:         [0x00]  256:        [0x81 0x00]\n * 1:         [0x01]  16383:      [0xFE 0x7F]\n * 127:       [0x7F]  16384:      [0xFF 0x00]\n * 128:  [0x80 0x00]  16511: [0x80 0xFF 0x7F]\n * 255:  [0x80 0x7F]  65535: [0x82 0xFD 0x7F]\n * 2^32:           [0x8E 0xFE 0xFE 0xFF 0x00]\n */\n\ntemplate <typename I>\ninline unsigned int GetSizeOfVarInt(I n)\n{\n    int nRet = 0;\n    while (true)\n    {\n        nRet++;\n        if (n <= 0x7F)\n            break;\n        n = (n >> 7) - 1;\n    }\n    return nRet;\n}\n\ntemplate <typename Stream, typename I>\nvoid WriteVarInt(Stream &os, I n)\n{\n    unsigned char tmp[(sizeof(n) * 8 + 6) / 7];\n    int len = 0;\n    while (true)\n    {\n        tmp[len] = (n & 0x7F) | (len ? 0x80 : 0x00);\n        if (n <= 0x7F)\n            break;\n        n = (n >> 7) - 1;\n        len++;\n    }\n    do\n    {\n        ser_writedata8(os, tmp[len]);\n    } while (len--);\n}\n\ntemplate <typename Stream, typename I>\nI ReadVarInt(Stream &is)\n{\n    I n = 0;\n    while (true)\n    {\n        unsigned char chData = ser_readdata8(is);\n        n = (n << 7) | (chData & 0x7F);\n        if (chData & 0x80)\n            n++;\n        else\n            return n;\n    }\n}\n\n#define FLATDATA(obj) REF(CFlatData((char *)&(obj), (char *)&(obj) + sizeof(obj)))\n#define VARINT(obj) REF(WrapVarInt(REF(obj)))\n#define LIMITED_STRING(obj, n) REF(LimitedString<n>(REF(obj)))\n\n/**\n * Wrapper for serializing arrays and POD.\n */\nclass CFlatData\n{\n  protected:\n    char *pbegin;\n    char *pend;\n\n  public:\n    CFlatData(void *pbeginIn, void *pendIn) : pbegin((char *)pbeginIn), pend((char *)pendIn) {}\n    template <class T, class TAl>\n    explicit CFlatData(std::vector<T, TAl> &v)\n    {\n        pbegin = (char *)begin_ptr(v);\n        pend = (char *)end_ptr(v);\n    }\n    template <unsigned int N, typename T, typename S, typename D>\n    explicit CFlatData(prevector<N, T, S, D> &v)\n    {\n        pbegin = (char *)begin_ptr(v);\n        pend = (char *)end_ptr(v);\n    }\n    char *begin() { return pbegin; }\n    const char *begin() const { return pbegin; }\n    char *end() { return pend; }\n    const char *end() const { return pend; }\n\n    unsigned int GetSerializeSize(int, int = 0) const\n    {\n        return pend - pbegin;\n    }\n\n    template <typename Stream>\n    void Serialize(Stream &s, int, int = 0) const\n    {\n        s.write(pbegin, pend - pbegin);\n    }\n\n    template <typename Stream>\n    void Unserialize(Stream &s, int, int = 0)\n    {\n        s.read(pbegin, pend - pbegin);\n    }\n};\n\ntemplate <typename I>\nclass CVarInt\n{\n  protected:\n    I &n;\n\n  public:\n    CVarInt(I &nIn) : n(nIn) {}\n\n    unsigned int GetSerializeSize(int, int) const\n    {\n        return GetSizeOfVarInt<I>(n);\n    }\n\n    template <typename Stream>\n    void Serialize(Stream &s, int, int) const\n    {\n        WriteVarInt<Stream, I>(s, n);\n    }\n\n    template <typename Stream>\n    void Unserialize(Stream &s, int, int)\n    {\n        n = ReadVarInt<Stream, I>(s);\n    }\n};\n\ntemplate <size_t Limit>\nclass LimitedString\n{\n  protected:\n    std::string &string;\n\n  public:\n    LimitedString(std::string &string) : string(string) {}\n\n    template <typename Stream>\n    void Unserialize(Stream &s, int, int = 0)\n    {\n        size_t size = ReadCompactSize(s);\n        if (size > Limit)\n        {\n            throw std::ios_base::failure(\"String length limit exceeded\");\n        }\n        string.resize(size);\n        if (size != 0)\n            s.read((char *)&string[0], size);\n    }\n\n    template <typename Stream>\n    void Serialize(Stream &s, int, int = 0) const\n    {\n        WriteCompactSize(s, string.size());\n        if (!string.empty())\n            s.write((char *)&string[0], string.size());\n    }\n\n    unsigned int GetSerializeSize(int, int = 0) const\n    {\n        return GetSizeOfCompactSize(string.size()) + string.size();\n    }\n};\n\ntemplate <typename I>\nCVarInt<I> WrapVarInt(I &n) { return CVarInt<I>(n); }\n\n/**\n * Forward declarations\n */\n\n/**\n *  string\n */\ntemplate <typename C>\nunsigned int GetSerializeSize(const std::basic_string<C> &str, int, int = 0);\ntemplate <typename Stream, typename C>\nvoid Serialize(Stream &os, const std::basic_string<C> &str, int, int = 0);\ntemplate <typename Stream, typename C>\nvoid Unserialize(Stream &is, std::basic_string<C> &str, int, int = 0);\n\n/**\n * prevector\n * prevectors of unsigned char are a special case and are intended to be serialized as a single opaque blob.\n */\ntemplate <unsigned int N, typename T>\nunsigned int GetSerializeSize_impl(const prevector<N, T> &v, int nType, int nVersion, const unsigned char &);\ntemplate <unsigned int N, typename T, typename V>\nunsigned int GetSerializeSize_impl(const prevector<N, T> &v, int nType, int nVersion, const V &);\ntemplate <unsigned int N, typename T>\ninline unsigned int GetSerializeSize(const prevector<N, T> &v, int nType, int nVersion);\ntemplate <typename Stream, unsigned int N, typename T>\nvoid Serialize_impl(Stream &os, const prevector<N, T> &v, int nType, int nVersion, const unsigned char &);\ntemplate <typename Stream, unsigned int N, typename T, typename V>\nvoid Serialize_impl(Stream &os, const prevector<N, T> &v, int nType, int nVersion, const V &);\ntemplate <typename Stream, unsigned int N, typename T>\ninline void Serialize(Stream &os, const prevector<N, T> &v, int nType, int nVersion);\ntemplate <typename Stream, unsigned int N, typename T>\nvoid Unserialize_impl(Stream &is, prevector<N, T> &v, int nType, int nVersion, const unsigned char &);\ntemplate <typename Stream, unsigned int N, typename T, typename V>\nvoid Unserialize_impl(Stream &is, prevector<N, T> &v, int nType, int nVersion, const V &);\ntemplate <typename Stream, unsigned int N, typename T>\ninline void Unserialize(Stream &is, prevector<N, T> &v, int nType, int nVersion);\n\n/**\n * vector\n * vectors of unsigned char are a special case and are intended to be serialized as a single opaque blob.\n */\ntemplate <typename T, typename A>\nunsigned int GetSerializeSize_impl(const std::vector<T, A> &v, int nType, int nVersion, const unsigned char &);\ntemplate <typename T, typename A, typename V>\nunsigned int GetSerializeSize_impl(const std::vector<T, A> &v, int nType, int nVersion, const V &);\ntemplate <typename T, typename A>\ninline unsigned int GetSerializeSize(const std::vector<T, A> &v, int nType, int nVersion);\ntemplate <typename Stream, typename T, typename A>\nvoid Serialize_impl(Stream &os, const std::vector<T, A> &v, int nType, int nVersion, const unsigned char &);\ntemplate <typename Stream, typename T, typename A, typename V>\nvoid Serialize_impl(Stream &os, const std::vector<T, A> &v, int nType, int nVersion, const V &);\ntemplate <typename Stream, typename T, typename A>\ninline void Serialize(Stream &os, const std::vector<T, A> &v, int nType, int nVersion);\ntemplate <typename Stream, typename T, typename A>\nvoid Unserialize_impl(Stream &is, std::vector<T, A> &v, int nType, int nVersion, const unsigned char &);\ntemplate <typename Stream, typename T, typename A, typename V>\nvoid Unserialize_impl(Stream &is, std::vector<T, A> &v, int nType, int nVersion, const V &);\ntemplate <typename Stream, typename T, typename A>\ninline void Unserialize(Stream &is, std::vector<T, A> &v, int nType, int nVersion);\n\n/**\n * pair\n */\ntemplate <typename K, typename T>\nunsigned int GetSerializeSize(const std::pair<K, T> &item, int nType, int nVersion);\ntemplate <typename Stream, typename K, typename T>\nvoid Serialize(Stream &os, const std::pair<K, T> &item, int nType, int nVersion);\ntemplate <typename Stream, typename K, typename T>\nvoid Unserialize(Stream &is, std::pair<K, T> &item, int nType, int nVersion);\n\n/**\n * map\n */\ntemplate <typename K, typename T, typename Pred, typename A>\nunsigned int GetSerializeSize(const std::map<K, T, Pred, A> &m, int nType, int nVersion);\ntemplate <typename Stream, typename K, typename T, typename Pred, typename A>\nvoid Serialize(Stream &os, const std::map<K, T, Pred, A> &m, int nType, int nVersion);\ntemplate <typename Stream, typename K, typename T, typename Pred, typename A>\nvoid Unserialize(Stream &is, std::map<K, T, Pred, A> &m, int nType, int nVersion);\n\n/**\n * set\n */\ntemplate <typename K, typename Pred, typename A>\nunsigned int GetSerializeSize(const std::set<K, Pred, A> &m, int nType, int nVersion);\ntemplate <typename Stream, typename K, typename Pred, typename A>\nvoid Serialize(Stream &os, const std::set<K, Pred, A> &m, int nType, int nVersion);\ntemplate <typename Stream, typename K, typename Pred, typename A>\nvoid Unserialize(Stream &is, std::set<K, Pred, A> &m, int nType, int nVersion);\n\n/**\n * If none of the specialized versions above matched, default to calling member function.\n * \"int nType\" is changed to \"long nType\" to keep from getting an ambiguous overload error.\n * The compiler will only cast int to long if none of the other templates matched.\n * Thanks to Boost serialization for this idea.\n */\ntemplate <typename T>\ninline unsigned int GetSerializeSize(const T &a, long nType, int nVersion)\n{\n    return a.GetSerializeSize((int)nType, nVersion);\n}\n\ntemplate <typename Stream, typename T>\ninline void Serialize(Stream &os, const T &a, long nType, int nVersion)\n{\n    a.Serialize(os, (int)nType, nVersion);\n}\n\ntemplate <typename Stream, typename T>\ninline void Unserialize(Stream &is, T &a, long nType, int nVersion)\n{\n    a.Unserialize(is, (int)nType, nVersion);\n}\n\n/**\n * string\n */\ntemplate <typename C>\nunsigned int GetSerializeSize(const std::basic_string<C> &str, int, int)\n{\n    return GetSizeOfCompactSize(str.size()) + str.size() * sizeof(str[0]);\n}\n\ntemplate <typename Stream, typename C>\nvoid Serialize(Stream &os, const std::basic_string<C> &str, int, int)\n{\n    WriteCompactSize(os, str.size());\n    if (!str.empty())\n        os.write((char *)&str[0], str.size() * sizeof(str[0]));\n}\n\ntemplate <typename Stream, typename C>\nvoid Unserialize(Stream &is, std::basic_string<C> &str, int, int)\n{\n    unsigned int nSize = ReadCompactSize(is);\n    str.resize(nSize);\n    if (nSize != 0)\n        is.read((char *)&str[0], nSize * sizeof(str[0]));\n}\n\n/**\n * prevector\n */\ntemplate <unsigned int N, typename T>\nunsigned int GetSerializeSize_impl(const prevector<N, T> &v, int nType, int nVersion, const unsigned char &)\n{\n    return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T));\n}\n\ntemplate <unsigned int N, typename T, typename V>\nunsigned int GetSerializeSize_impl(const prevector<N, T> &v, int nType, int nVersion, const V &)\n{\n    unsigned int nSize = GetSizeOfCompactSize(v.size());\n    for (typename prevector<N, T>::const_iterator vi = v.begin(); vi != v.end(); ++vi)\n        nSize += GetSerializeSize((*vi), nType, nVersion);\n    return nSize;\n}\n\ntemplate <unsigned int N, typename T>\ninline unsigned int GetSerializeSize(const prevector<N, T> &v, int nType, int nVersion)\n{\n    return GetSerializeSize_impl(v, nType, nVersion, T());\n}\n\ntemplate <typename Stream, unsigned int N, typename T>\nvoid Serialize_impl(Stream &os, const prevector<N, T> &v, int nType, int nVersion, const unsigned char &)\n{\n    WriteCompactSize(os, v.size());\n    if (!v.empty())\n        os.write((char *)&v[0], v.size() * sizeof(T));\n}\n\ntemplate <typename Stream, unsigned int N, typename T, typename V>\nvoid Serialize_impl(Stream &os, const prevector<N, T> &v, int nType, int nVersion, const V &)\n{\n    WriteCompactSize(os, v.size());\n    for (typename prevector<N, T>::const_iterator vi = v.begin(); vi != v.end(); ++vi)\n        ::Serialize(os, (*vi), nType, nVersion);\n}\n\ntemplate <typename Stream, unsigned int N, typename T>\ninline void Serialize(Stream &os, const prevector<N, T> &v, int nType, int nVersion)\n{\n    Serialize_impl(os, v, nType, nVersion, T());\n}\n\ntemplate <typename Stream, unsigned int N, typename T>\nvoid Unserialize_impl(Stream &is, prevector<N, T> &v, int nType, int nVersion, const unsigned char &)\n{\n    // Limit size per read so bogus size value won't cause out of memory\n    v.clear();\n    unsigned int nSize = ReadCompactSize(is);\n    unsigned int i = 0;\n    while (i < nSize)\n    {\n        unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));\n        v.resize(i + blk);\n        is.read((char *)&v[i], blk * sizeof(T));\n        i += blk;\n    }\n}\n\ntemplate <typename Stream, unsigned int N, typename T, typename V>\nvoid Unserialize_impl(Stream &is, prevector<N, T> &v, int nType, int nVersion, const V &)\n{\n    v.clear();\n    unsigned int nSize = ReadCompactSize(is);\n    unsigned int i = 0;\n    unsigned int nMid = 0;\n    while (nMid < nSize)\n    {\n        nMid += 5000000 / sizeof(T);\n        if (nMid > nSize)\n            nMid = nSize;\n        v.resize(nMid);\n        for (; i < nMid; i++)\n            Unserialize(is, v[i], nType, nVersion);\n    }\n}\n\ntemplate <typename Stream, unsigned int N, typename T>\ninline void Unserialize(Stream &is, prevector<N, T> &v, int nType, int nVersion)\n{\n    Unserialize_impl(is, v, nType, nVersion, T());\n}\n\n/**\n * vector\n */\ntemplate <typename T, typename A>\nunsigned int GetSerializeSize_impl(const std::vector<T, A> &v, int nType, int nVersion, const unsigned char &)\n{\n    return (GetSizeOfCompactSize(v.size()) + v.size() * sizeof(T));\n}\n\ntemplate <typename T, typename A, typename V>\nunsigned int GetSerializeSize_impl(const std::vector<T, A> &v, int nType, int nVersion, const V &)\n{\n    unsigned int nSize = GetSizeOfCompactSize(v.size());\n    for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)\n        nSize += GetSerializeSize((*vi), nType, nVersion);\n    return nSize;\n}\n\ntemplate <typename T, typename A>\ninline unsigned int GetSerializeSize(const std::vector<T, A> &v, int nType, int nVersion)\n{\n    return GetSerializeSize_impl(v, nType, nVersion, T());\n}\n\ntemplate <typename Stream, typename T, typename A>\nvoid Serialize_impl(Stream &os, const std::vector<T, A> &v, int nType, int nVersion, const unsigned char &)\n{\n    WriteCompactSize(os, v.size());\n    if (!v.empty())\n        os.write((char *)&v[0], v.size() * sizeof(T));\n}\n\ntemplate <typename Stream, typename T, typename A, typename V>\nvoid Serialize_impl(Stream &os, const std::vector<T, A> &v, int nType, int nVersion, const V &)\n{\n    WriteCompactSize(os, v.size());\n    for (typename std::vector<T, A>::const_iterator vi = v.begin(); vi != v.end(); ++vi)\n        ::Serialize(os, (*vi), nType, nVersion);\n}\n\ntemplate <typename Stream, typename T, typename A>\ninline void Serialize(Stream &os, const std::vector<T, A> &v, int nType, int nVersion)\n{\n    Serialize_impl(os, v, nType, nVersion, T());\n}\n\ntemplate <typename Stream, typename T, typename A>\nvoid Unserialize_impl(Stream &is, std::vector<T, A> &v, int nType, int nVersion, const unsigned char &)\n{\n    // Limit size per read so bogus size value won't cause out of memory\n    v.clear();\n    unsigned int nSize = ReadCompactSize(is);\n    unsigned int i = 0;\n    while (i < nSize)\n    {\n        unsigned int blk = std::min(nSize - i, (unsigned int)(1 + 4999999 / sizeof(T)));\n        v.resize(i + blk);\n        is.read((char *)&v[i], blk * sizeof(T));\n        i += blk;\n    }\n}\n\ntemplate <typename Stream, typename T, typename A, typename V>\nvoid Unserialize_impl(Stream &is, std::vector<T, A> &v, int nType, int nVersion, const V &)\n{\n    v.clear();\n    unsigned int nSize = ReadCompactSize(is);\n    unsigned int i = 0;\n    unsigned int nMid = 0;\n    while (nMid < nSize)\n    {\n        nMid += 5000000 / sizeof(T);\n        if (nMid > nSize)\n            nMid = nSize;\n        v.resize(nMid);\n        for (; i < nMid; i++)\n            Unserialize(is, v[i], nType, nVersion);\n    }\n}\n\ntemplate <typename Stream, typename T, typename A>\ninline void Unserialize(Stream &is, std::vector<T, A> &v, int nType, int nVersion)\n{\n    Unserialize_impl(is, v, nType, nVersion, T());\n}\n\n/**\n * pair\n */\ntemplate <typename K, typename T>\nunsigned int GetSerializeSize(const std::pair<K, T> &item, int nType, int nVersion)\n{\n    return GetSerializeSize(item.first, nType, nVersion) + GetSerializeSize(item.second, nType, nVersion);\n}\n\ntemplate <typename Stream, typename K, typename T>\nvoid Serialize(Stream &os, const std::pair<K, T> &item, int nType, int nVersion)\n{\n    Serialize(os, item.first, nType, nVersion);\n    Serialize(os, item.second, nType, nVersion);\n}\n\ntemplate <typename Stream, typename K, typename T>\nvoid Unserialize(Stream &is, std::pair<K, T> &item, int nType, int nVersion)\n{\n    Unserialize(is, item.first, nType, nVersion);\n    Unserialize(is, item.second, nType, nVersion);\n}\n\n/**\n * map\n */\ntemplate <typename K, typename T, typename Pred, typename A>\nunsigned int GetSerializeSize(const std::map<K, T, Pred, A> &m, int nType, int nVersion)\n{\n    unsigned int nSize = GetSizeOfCompactSize(m.size());\n    for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)\n        nSize += GetSerializeSize((*mi), nType, nVersion);\n    return nSize;\n}\n\ntemplate <typename Stream, typename K, typename T, typename Pred, typename A>\nvoid Serialize(Stream &os, const std::map<K, T, Pred, A> &m, int nType, int nVersion)\n{\n    WriteCompactSize(os, m.size());\n    for (typename std::map<K, T, Pred, A>::const_iterator mi = m.begin(); mi != m.end(); ++mi)\n        Serialize(os, (*mi), nType, nVersion);\n}\n\ntemplate <typename Stream, typename K, typename T, typename Pred, typename A>\nvoid Unserialize(Stream &is, std::map<K, T, Pred, A> &m, int nType, int nVersion)\n{\n    m.clear();\n    unsigned int nSize = ReadCompactSize(is);\n    typename std::map<K, T, Pred, A>::iterator mi = m.begin();\n    for (unsigned int i = 0; i < nSize; i++)\n    {\n        std::pair<K, T> item;\n        Unserialize(is, item, nType, nVersion);\n        mi = m.insert(mi, item);\n    }\n}\n\n/**\n * set\n */\ntemplate <typename K, typename Pred, typename A>\nunsigned int GetSerializeSize(const std::set<K, Pred, A> &m, int nType, int nVersion)\n{\n    unsigned int nSize = GetSizeOfCompactSize(m.size());\n    for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)\n        nSize += GetSerializeSize((*it), nType, nVersion);\n    return nSize;\n}\n\ntemplate <typename Stream, typename K, typename Pred, typename A>\nvoid Serialize(Stream &os, const std::set<K, Pred, A> &m, int nType, int nVersion)\n{\n    WriteCompactSize(os, m.size());\n    for (typename std::set<K, Pred, A>::const_iterator it = m.begin(); it != m.end(); ++it)\n        Serialize(os, (*it), nType, nVersion);\n}\n\ntemplate <typename Stream, typename K, typename Pred, typename A>\nvoid Unserialize(Stream &is, std::set<K, Pred, A> &m, int nType, int nVersion)\n{\n    m.clear();\n    unsigned int nSize = ReadCompactSize(is);\n    typename std::set<K, Pred, A>::iterator it = m.begin();\n    for (unsigned int i = 0; i < nSize; i++)\n    {\n        K key;\n        Unserialize(is, key, nType, nVersion);\n        it = m.insert(it, key);\n    }\n}\n\n/**\n * Support for ADD_SERIALIZE_METHODS and READWRITE macro\n */\nstruct CSerActionSerialize\n{\n    bool ForRead() const { return false; }\n};\nstruct CSerActionUnserialize\n{\n    bool ForRead() const { return true; }\n};\n\ntemplate <typename Stream, typename T>\ninline void SerReadWrite(Stream &s, const T &obj, int nType, int nVersion, CSerActionSerialize ser_action)\n{\n    ::Serialize(s, obj, nType, nVersion);\n}\n\ntemplate <typename Stream, typename T>\ninline void SerReadWrite(Stream &s, T &obj, int nType, int nVersion, CSerActionUnserialize ser_action)\n{\n    ::Unserialize(s, obj, nType, nVersion);\n}\n\nclass CSizeComputer\n{\n  protected:\n    size_t nSize;\n\n  public:\n    int nType;\n    int nVersion;\n\n    CSizeComputer(int nTypeIn, int nVersionIn) : nSize(0), nType(nTypeIn), nVersion(nVersionIn) {}\n\n    CSizeComputer &write(const char *psz, size_t nSize)\n    {\n        this->nSize += nSize;\n        return *this;\n    }\n\n    template <typename T>\n    CSizeComputer &operator<<(const T &obj)\n    {\n        ::Serialize(*this, obj, nType, nVersion);\n        return (*this);\n    }\n\n    size_t size() const\n    {\n        return nSize;\n    }\n};\n\n#endif // BITCOIN_SERIALIZE_H\n"
  },
  {
    "path": "src/UChainService/consensus/clone/tinyformat.h",
    "content": "// tinyformat.h\n// Copyright (C) 2011, Chris Foster [chris42f (at) gmail (d0t) com]\n//\n// Boost Software License - Version 1.0\n//\n// Permission is hereby granted, free of charge, to any person or organization\n// obtaining a copy of the software and accompanying documentation covered by\n// this license (the \"Software\") to use, reproduce, display, distribute,\n// execute, and transmit the Software, and to prepare derivative works of the\n// Software, and to permit third-parties to whom the Software is furnished to\n// do so, all subject to the following:\n//\n// The copyright notices in the Software and this entire statement, including\n// the above license grant, this restriction and the following disclaimer,\n// must be included in all copies of the Software, in whole or in part, and\n// all derivative works of the Software, unless such copies or derivative\n// works are solely in the form of machine-executable object code generated by\n// a source language processor.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT\n// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE\n// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,\n// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n// DEALINGS IN THE SOFTWARE.\n\n//------------------------------------------------------------------------------\n// Tinyformat: A minimal type safe printf replacement\n//\n// tinyformat.h is a type safe printf replacement library in a single C++\n// header file.  Design goals include:\n//\n// * Type safety and extensibility for user defined types.\n// * C99 printf() compatibility, to the extent possible using std::ostream\n// * Simplicity and minimalism.  A single header file to include and distribute\n//   with your projects.\n// * Augment rather than replace the standard stream formatting mechanism\n// * C++98 support, with optional C++11 niceties\n//\n//\n// Main interface example usage\n// ----------------------------\n//\n// To print a date to std::cout:\n//\n//   std::string weekday = \"Wednesday\";\n//   const char* month = \"July\";\n//   size_t day = 27;\n//   long hour = 14;\n//   int min = 44;\n//\n//   tfm::printf(\"%s, %s %d, %.2d:%.2d\\n\", weekday, month, day, hour, min);\n//\n// The strange types here emphasize the type safety of the interface; it is\n// possible to print a std::string using the \"%s\" conversion, and a\n// size_t using the \"%d\" conversion.  A similar result could be achieved\n// using either of the tfm::format() functions.  One prints on a user provided\n// stream:\n//\n//   tfm::format(std::cerr, \"%s, %s %d, %.2d:%.2d\\n\",\n//               weekday, month, day, hour, min);\n//\n// The other returns a std::string:\n//\n//   std::string date = tfm::format(\"%s, %s %d, %.2d:%.2d\\n\",\n//                                  weekday, month, day, hour, min);\n//   std::cout << date;\n//\n// These are the three primary interface functions.\n//\n//\n// User defined format functions\n// -----------------------------\n//\n// Simulating variadic templates in C++98 is pretty painful since it requires\n// writing out the same function for each desired number of arguments.  To make\n// this bearable tinyformat comes with a set of macros which are used\n// internally to generate the API, but which may also be used in user code.\n//\n// The three macros TINYFORMAT_ARGTYPES(n), TINYFORMAT_VARARGS(n) and\n// TINYFORMAT_PASSARGS(n) will generate a list of n argument types,\n// type/name pairs and argument names respectively when called with an integer\n// n between 1 and 16.  We can use these to define a macro which generates the\n// desired user defined function with n arguments.  To generate all 16 user\n// defined function bodies, use the macro TINYFORMAT_FOREACH_ARGNUM.  For an\n// example, see the implementation of printf() at the end of the source file.\n//\n//\n// Additional API information\n// --------------------------\n//\n// Error handling: Define TINYFORMAT_ERROR to customize the error handling for\n// format strings which are unsupported or have the wrong number of format\n// specifiers (calls assert() by default).\n//\n// User defined types: Uses operator<< for user defined types by default.\n// Overload formatValue() for more control.\n\n#ifndef TINYFORMAT_H_INCLUDED\n#define TINYFORMAT_H_INCLUDED\n\nnamespace tinyformat\n{\n}\n//------------------------------------------------------------------------------\n// Config section.  Customize to your liking!\n\n// Namespace alias to encourage brevity\nnamespace tfm = tinyformat;\n\n// Error handling; calls assert() by default.\n#define TINYFORMAT_ERROR(reasonString) throw std::runtime_error(reasonString)\n\n// Define for C++11 variadic templates which make the code shorter & more\n// general.  If you don't define this, C++11 support is autodetected below.\n// #define TINYFORMAT_USE_VARIADIC_TEMPLATES\n\n//------------------------------------------------------------------------------\n// Implementation details.\n#include <cassert>\n#include <iostream>\n#include <sstream>\n#include <stdexcept>\n\n#ifndef TINYFORMAT_ERROR\n#define TINYFORMAT_ERROR(reason) assert(0 && reason)\n#endif\n\n#if !defined(TINYFORMAT_USE_VARIADIC_TEMPLATES) && !defined(TINYFORMAT_NO_VARIADIC_TEMPLATES)\n#ifdef __GXX_EXPERIMENTAL_CXX0X__\n#define TINYFORMAT_USE_VARIADIC_TEMPLATES\n#endif\n#endif\n\n#ifdef __GNUC__\n#define TINYFORMAT_NOINLINE __attribute__((noinline))\n#elif defined(_MSC_VER)\n#define TINYFORMAT_NOINLINE __declspec(noinline)\n#else\n#define TINYFORMAT_NOINLINE\n#endif\n\n#if defined(__GLIBCXX__) && __GLIBCXX__ < 20080201\n//  std::showpos is broken on old libstdc++ as provided with OSX.  See\n//  http://gcc.gnu.org/ml/libstdc++/2007-11/msg00075.html\n#define TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND\n#endif\n\nnamespace tinyformat\n{\n\n//------------------------------------------------------------------------------\nnamespace detail\n{\n\n// Test whether type T1 is convertible to type T2\ntemplate <typename T1, typename T2>\nstruct is_convertible\n{\n  private:\n    // two types of different size\n    struct fail\n    {\n        char dummy[2];\n    };\n    struct succeed\n    {\n        char dummy;\n    };\n    // Try to convert a T1 to a T2 by plugging into tryConvert\n    static fail tryConvert(...);\n    static succeed tryConvert(const T2 &);\n    static const T1 &makeT1();\n\n  public:\n#ifdef _MSC_VER\n    // Disable spurious loss of precision warnings in tryConvert(makeT1())\n#pragma warning(push)\n#pragma warning(disable : 4244)\n#pragma warning(disable : 4267)\n#endif\n    // Standard trick: the (...) version of tryConvert will be chosen from\n    // the overload set only if the version taking a T2 doesn't match.\n    // Then we compare the sizes of the return types to check which\n    // function matched.  Very neat, in a disgusting kind of way :)\n    static const bool value =\n        sizeof(tryConvert(makeT1())) == sizeof(succeed);\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n};\n\n// Detect when a type is not a wchar_t string\ntemplate <typename T>\nstruct is_wchar\n{\n    typedef int tinyformat_wchar_is_not_supported;\n};\ntemplate <>\nstruct is_wchar<wchar_t *>\n{\n};\ntemplate <>\nstruct is_wchar<const wchar_t *>\n{\n};\ntemplate <int n>\nstruct is_wchar<const wchar_t[n]>\n{\n};\ntemplate <int n>\nstruct is_wchar<wchar_t[n]>\n{\n};\n\n// Format the value by casting to type fmtT.  This default implementation\n// should never be called.\ntemplate <typename T, typename fmtT, bool convertible = is_convertible<T, fmtT>::value>\nstruct formatValueAsType\n{\n    static void invoke(std::ostream & /*out*/, const T & /*value*/) { assert(0); }\n};\n// Specialized version for types that can actually be converted to fmtT, as\n// indicated by the \"convertible\" template parameter.\ntemplate <typename T, typename fmtT>\nstruct formatValueAsType<T, fmtT, true>\n{\n    static void invoke(std::ostream &out, const T &value)\n    {\n        out << static_cast<fmtT>(value);\n    }\n};\n\n#ifdef TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND\ntemplate <typename T, bool convertible = is_convertible<T, int>::value>\nstruct formatZeroIntegerWorkaround\n{\n    static bool invoke(std::ostream & /**/, const T & /**/) { return false; }\n};\ntemplate <typename T>\nstruct formatZeroIntegerWorkaround<T, true>\n{\n    static bool invoke(std::ostream &out, const T &value)\n    {\n        if (static_cast<int>(value) == 0 && out.flags() & std::ios::showpos)\n        {\n            out << \"+0\";\n            return true;\n        }\n        return false;\n    }\n};\n#endif // TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND\n\n// Convert an arbitrary type to integer.  The version with convertible=false\n// throws an error.\ntemplate <typename T, bool convertible = is_convertible<T, int>::value>\nstruct convertToInt\n{\n    static int invoke(const T & /*value*/)\n    {\n        TINYFORMAT_ERROR(\"tinyformat: Cannot convert from argument type to \"\n                         \"integer for use as variable width or precision\");\n        return 0;\n    }\n};\n// Specialization for convertToInt when conversion is possible\ntemplate <typename T>\nstruct convertToInt<T, true>\n{\n    static int invoke(const T &value) { return static_cast<int>(value); }\n};\n\n} // namespace detail\n\n//------------------------------------------------------------------------------\n// Variable formatting functions.  May be overridden for user-defined types if\n// desired.\n\n// Format a value into a stream. Called from format() for all types by default.\n//\n// Users may override this for their own types.  When this function is called,\n// the stream flags will have been modified according to the format string.\n// The format specification is provided in the range [fmtBegin, fmtEnd).\n//\n// By default, formatValue() uses the usual stream insertion operator\n// operator<< to format the type T, with special cases for the %c and %p\n// conversions.\ntemplate <typename T>\ninline void formatValue(std::ostream &out, const char * /*fmtBegin*/,\n                        const char *fmtEnd, const T &value)\n{\n#ifndef TINYFORMAT_ALLOW_WCHAR_STRINGS\n    // Since we don't support printing of wchar_t using \"%ls\", make it fail at\n    // compile time in preference to printing as a void* at runtime.\n    typedef typename detail::is_wchar<T>::tinyformat_wchar_is_not_supported DummyType;\n    (void)DummyType(); // avoid unused type warning with gcc-4.8\n#endif\n    // The mess here is to support the %c and %p conversions: if these\n    // conversions are active we try to convert the type to a char or const\n    // void* respectively and format that instead of the value itself.  For the\n    // %p conversion it's important to avoid dereferencing the pointer, which\n    // could otherwise lead to a crash when printing a dangling (const char*).\n    const bool canConvertToChar = detail::is_convertible<T, char>::value;\n    const bool canConvertToVoidPtr = detail::is_convertible<T, const void *>::value;\n    if (canConvertToChar && *(fmtEnd - 1) == 'c')\n        detail::formatValueAsType<T, char>::invoke(out, value);\n    else if (canConvertToVoidPtr && *(fmtEnd - 1) == 'p')\n        detail::formatValueAsType<T, const void *>::invoke(out, value);\n#ifdef TINYFORMAT_OLD_LIBSTDCPLUSPLUS_WORKAROUND\n    else if (detail::formatZeroIntegerWorkaround<T>::invoke(out, value)) /**/\n        ;\n#endif\n    else\n        out << value;\n}\n\n// Overloaded version for char types to support printing as an integer\n#define TINYFORMAT_DEFINE_FORMATVALUE_CHAR(charType)                      \\\n    inline void formatValue(std::ostream &out, const char * /*fmtBegin*/, \\\n                            const char *fmtEnd, charType value)           \\\n    {                                                                     \\\n        switch (*(fmtEnd - 1))                                            \\\n        {                                                                 \\\n        case 'u':                                                         \\\n        case 'd':                                                         \\\n        case 'i':                                                         \\\n        case 'o':                                                         \\\n        case 'X':                                                         \\\n        case 'x':                                                         \\\n            out << static_cast<int>(value);                               \\\n            break;                                                        \\\n        default:                                                          \\\n            out << value;                                                 \\\n            break;                                                        \\\n        }                                                                 \\\n    }\n// per 3.9.1: char, signed char and unsigned char are all distinct types\nTINYFORMAT_DEFINE_FORMATVALUE_CHAR(char)\nTINYFORMAT_DEFINE_FORMATVALUE_CHAR(signed char)\nTINYFORMAT_DEFINE_FORMATVALUE_CHAR(unsigned char)\n#undef TINYFORMAT_DEFINE_FORMATVALUE_CHAR\n\n//------------------------------------------------------------------------------\n// Tools for emulating variadic templates in C++98.  The basic idea here is\n// stolen from the boost preprocessor metaprogramming library and cut down to\n// be just general enough for what we need.\n\n#define TINYFORMAT_ARGTYPES(n) TINYFORMAT_ARGTYPES_##n\n#define TINYFORMAT_VARARGS(n) TINYFORMAT_VARARGS_##n\n#define TINYFORMAT_PASSARGS(n) TINYFORMAT_PASSARGS_##n\n#define TINYFORMAT_PASSARGS_TAIL(n) TINYFORMAT_PASSARGS_TAIL_##n\n\n// To keep it as transparent as possible, the macros below have been generated\n// using python via the excellent cog.py code generation script.  This avoids\n// the need for a bunch of complex (but more general) preprocessor tricks as\n// used in boost.preprocessor.\n//\n// To rerun the code generation in place, use `cog.py -r tinyformat.h`\n// (see http://nedbatchelder.com/code/cog).  Alternatively you can just create\n// extra versions by hand.\n\n/*[[[cog\nmaxParams = 16\n\ndef makeCommaSepLists(lineTemplate, elemTemplate, startInd=1):\n    for j in range(startInd,maxParams+1):\n        list = ', '.join([elemTemplate % {'i':i} for i in range(startInd,j+1)])\n        cog.outl(lineTemplate % {'j':j, 'list':list})\n\nmakeCommaSepLists('#define TINYFORMAT_ARGTYPES_%(j)d %(list)s',\n                  'class T%(i)d')\n\ncog.outl()\nmakeCommaSepLists('#define TINYFORMAT_VARARGS_%(j)d %(list)s',\n                  'const T%(i)d& v%(i)d')\n\ncog.outl()\nmakeCommaSepLists('#define TINYFORMAT_PASSARGS_%(j)d %(list)s', 'v%(i)d')\n\ncog.outl()\ncog.outl('#define TINYFORMAT_PASSARGS_TAIL_1')\nmakeCommaSepLists('#define TINYFORMAT_PASSARGS_TAIL_%(j)d , %(list)s',\n                  'v%(i)d', startInd = 2)\n\ncog.outl()\ncog.outl('#define TINYFORMAT_FOREACH_ARGNUM(m) \\\\\\n    ' +\n         ' '.join(['m(%d)' % (j,) for j in range(1,maxParams+1)]))\n]]]*/\n#define TINYFORMAT_ARGTYPES_1 class T1\n#define TINYFORMAT_ARGTYPES_2 class T1, class T2\n#define TINYFORMAT_ARGTYPES_3 class T1, class T2, class T3\n#define TINYFORMAT_ARGTYPES_4 class T1, class T2, class T3, class T4\n#define TINYFORMAT_ARGTYPES_5 class T1, class T2, class T3, class T4, class T5\n#define TINYFORMAT_ARGTYPES_6 class T1, class T2, class T3, class T4, class T5, class T6\n#define TINYFORMAT_ARGTYPES_7 class T1, class T2, class T3, class T4, class T5, class T6, class T7\n#define TINYFORMAT_ARGTYPES_8 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8\n#define TINYFORMAT_ARGTYPES_9 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9\n#define TINYFORMAT_ARGTYPES_10 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10\n#define TINYFORMAT_ARGTYPES_11 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11\n#define TINYFORMAT_ARGTYPES_12 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12\n#define TINYFORMAT_ARGTYPES_13 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13\n#define TINYFORMAT_ARGTYPES_14 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14\n#define TINYFORMAT_ARGTYPES_15 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15\n#define TINYFORMAT_ARGTYPES_16 class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9, class T10, class T11, class T12, class T13, class T14, class T15, class T16\n\n#define TINYFORMAT_VARARGS_1 const T1 &v1\n#define TINYFORMAT_VARARGS_2 const T1 &v1, const T2 &v2\n#define TINYFORMAT_VARARGS_3 const T1 &v1, const T2 &v2, const T3 &v3\n#define TINYFORMAT_VARARGS_4 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4\n#define TINYFORMAT_VARARGS_5 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5\n#define TINYFORMAT_VARARGS_6 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6\n#define TINYFORMAT_VARARGS_7 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7\n#define TINYFORMAT_VARARGS_8 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8\n#define TINYFORMAT_VARARGS_9 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8, const T9 &v9\n#define TINYFORMAT_VARARGS_10 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8, const T9 &v9, const T10 &v10\n#define TINYFORMAT_VARARGS_11 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8, const T9 &v9, const T10 &v10, const T11 &v11\n#define TINYFORMAT_VARARGS_12 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8, const T9 &v9, const T10 &v10, const T11 &v11, const T12 &v12\n#define TINYFORMAT_VARARGS_13 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8, const T9 &v9, const T10 &v10, const T11 &v11, const T12 &v12, const T13 &v13\n#define TINYFORMAT_VARARGS_14 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8, const T9 &v9, const T10 &v10, const T11 &v11, const T12 &v12, const T13 &v13, const T14 &v14\n#define TINYFORMAT_VARARGS_15 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8, const T9 &v9, const T10 &v10, const T11 &v11, const T12 &v12, const T13 &v13, const T14 &v14, const T15 &v15\n#define TINYFORMAT_VARARGS_16 const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8, const T9 &v9, const T10 &v10, const T11 &v11, const T12 &v12, const T13 &v13, const T14 &v14, const T15 &v15, const T16 &v16\n\n#define TINYFORMAT_PASSARGS_1 v1\n#define TINYFORMAT_PASSARGS_2 v1, v2\n#define TINYFORMAT_PASSARGS_3 v1, v2, v3\n#define TINYFORMAT_PASSARGS_4 v1, v2, v3, v4\n#define TINYFORMAT_PASSARGS_5 v1, v2, v3, v4, v5\n#define TINYFORMAT_PASSARGS_6 v1, v2, v3, v4, v5, v6\n#define TINYFORMAT_PASSARGS_7 v1, v2, v3, v4, v5, v6, v7\n#define TINYFORMAT_PASSARGS_8 v1, v2, v3, v4, v5, v6, v7, v8\n#define TINYFORMAT_PASSARGS_9 v1, v2, v3, v4, v5, v6, v7, v8, v9\n#define TINYFORMAT_PASSARGS_10 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10\n#define TINYFORMAT_PASSARGS_11 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11\n#define TINYFORMAT_PASSARGS_12 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12\n#define TINYFORMAT_PASSARGS_13 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13\n#define TINYFORMAT_PASSARGS_14 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14\n#define TINYFORMAT_PASSARGS_15 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15\n#define TINYFORMAT_PASSARGS_16 v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16\n\n#define TINYFORMAT_PASSARGS_TAIL_1\n#define TINYFORMAT_PASSARGS_TAIL_2 , v2\n#define TINYFORMAT_PASSARGS_TAIL_3 , v2, v3\n#define TINYFORMAT_PASSARGS_TAIL_4 , v2, v3, v4\n#define TINYFORMAT_PASSARGS_TAIL_5 , v2, v3, v4, v5\n#define TINYFORMAT_PASSARGS_TAIL_6 , v2, v3, v4, v5, v6\n#define TINYFORMAT_PASSARGS_TAIL_7 , v2, v3, v4, v5, v6, v7\n#define TINYFORMAT_PASSARGS_TAIL_8 , v2, v3, v4, v5, v6, v7, v8\n#define TINYFORMAT_PASSARGS_TAIL_9 , v2, v3, v4, v5, v6, v7, v8, v9\n#define TINYFORMAT_PASSARGS_TAIL_10 , v2, v3, v4, v5, v6, v7, v8, v9, v10\n#define TINYFORMAT_PASSARGS_TAIL_11 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11\n#define TINYFORMAT_PASSARGS_TAIL_12 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12\n#define TINYFORMAT_PASSARGS_TAIL_13 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13\n#define TINYFORMAT_PASSARGS_TAIL_14 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14\n#define TINYFORMAT_PASSARGS_TAIL_15 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15\n#define TINYFORMAT_PASSARGS_TAIL_16 , v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16\n\n#define TINYFORMAT_FOREACH_ARGNUM(m) \\\n    m(1) m(2) m(3) m(4) m(5) m(6) m(7) m(8) m(9) m(10) m(11) m(12) m(13) m(14) m(15) m(16)\n//[[[end]]]\n\nnamespace detail\n{\n\n// Class holding current position in format string and an output stream into\n// which arguments are formatted.\nclass FormatIterator\n{\n  public:\n    // Flags for features not representable with standard stream state\n    enum ExtraFormatFlags\n    {\n        Flag_None = 0,\n        Flag_TruncateToPrecision = 1 << 0, // truncate length to stream precision()\n        Flag_SpacePadPositive = 1 << 1,    // pad positive values with spaces\n        Flag_VariableWidth = 1 << 2,       // variable field width in arg list\n        Flag_VariablePrecision = 1 << 3    // variable field precision in arg list\n    };\n\n    // out is the output stream, fmt is the full format string\n    FormatIterator(std::ostream &out, const char *fmt)\n        : m_out(out),\n          m_fmt(fmt),\n          m_extraFlags(Flag_None),\n          m_wantWidth(false),\n          m_wantPrecision(false),\n          m_variableWidth(0),\n          m_variablePrecision(0),\n          m_origWidth(out.width()),\n          m_origPrecision(out.precision()),\n          m_origFlags(out.flags()),\n          m_origFill(out.fill())\n    {\n    }\n\n    // Print remaining part of format string.\n    void finish()\n    {\n        // It would be nice if we could do this from the destructor, but we\n        // can't if TINFORMAT_ERROR is used to throw an exception!\n        m_fmt = printFormatStringLiteral(m_out, m_fmt);\n        if (*m_fmt != '\\0')\n            TINYFORMAT_ERROR(\"tinyformat: Too many conversion specifiers in format string\");\n    }\n\n    ~FormatIterator()\n    {\n        // Restore stream state\n        m_out.width(m_origWidth);\n        m_out.precision(m_origPrecision);\n        m_out.flags(m_origFlags);\n        m_out.fill(m_origFill);\n    }\n\n    template <typename T>\n    void accept(const T &value);\n\n  private:\n    // Parse and return an integer from the string c, as atoi()\n    // On return, c is set to one past the end of the integer.\n    static int parseIntAndAdvance(const char *&c)\n    {\n        int i = 0;\n        for (; *c >= '0' && *c <= '9'; ++c)\n            i = 10 * i + (*c - '0');\n        return i;\n    }\n\n    // Format at most truncLen characters of a C string to the given\n    // stream.  Return true if formatting proceeded (generic version always\n    // returns false)\n    template <typename T>\n    static bool formatCStringTruncate(std::ostream & /*out*/, const T & /*value*/,\n                                      std::streamsize /*truncLen*/)\n    {\n        return false;\n    }\n#define TINYFORMAT_DEFINE_FORMAT_C_STRING_TRUNCATE(type)              \\\n    static bool formatCStringTruncate(std::ostream &out, type *value, \\\n                                      std::streamsize truncLen)       \\\n    {                                                                 \\\n        std::streamsize len = 0;                                      \\\n        while (len < truncLen && value[len] != 0)                     \\\n            ++len;                                                    \\\n        out.write(value, len);                                        \\\n        return true;                                                  \\\n    }\n    // Overload for const char* and char*.  Could overload for signed &\n    // unsigned char too, but these are technically unneeded for printf\n    // compatibility.\n    TINYFORMAT_DEFINE_FORMAT_C_STRING_TRUNCATE(const char)\n    TINYFORMAT_DEFINE_FORMAT_C_STRING_TRUNCATE(char)\n#undef TINYFORMAT_DEFINE_FORMAT_C_STRING_TRUNCATE\n\n    // Print literal part of format string and return next format spec\n    // position.\n    //\n    // Skips over any occurrences of '%%', printing a literal '%' to the\n    // output.  The position of the first % character of the next\n    // nontrivial format spec is returned, or the end of string.\n    static const char *printFormatStringLiteral(std::ostream &out,\n                                                const char *fmt)\n    {\n        const char *c = fmt;\n        for (; true; ++c)\n        {\n            switch (*c)\n            {\n            case '\\0':\n                out.write(fmt, static_cast<std::streamsize>(c - fmt));\n                return c;\n            case '%':\n                out.write(fmt, static_cast<std::streamsize>(c - fmt));\n                if (*(c + 1) != '%')\n                    return c;\n                // for \"%%\", tack trailing % onto next literal section.\n                fmt = ++c;\n                break;\n            }\n        }\n    }\n\n    static const char *streamStateFromFormat(std::ostream &out,\n                                             unsigned int &extraFlags,\n                                             const char *fmtStart,\n                                             int variableWidth,\n                                             int variablePrecision);\n\n    // Private copy & assign: Kill gcc warnings with -Weffc++\n    FormatIterator(const FormatIterator &);\n    FormatIterator &operator=(const FormatIterator &);\n\n    // Stream, current format string & state\n    std::ostream &m_out;\n    const char *m_fmt;\n    unsigned int m_extraFlags;\n    // State machine info for handling of variable width & precision\n    bool m_wantWidth;\n    bool m_wantPrecision;\n    int m_variableWidth;\n    int m_variablePrecision;\n    // Saved stream state\n    std::streamsize m_origWidth;\n    std::streamsize m_origPrecision;\n    std::ios::fmtflags m_origFlags;\n    char m_origFill;\n};\n\n// Accept a value for formatting into the internal stream.\ntemplate <typename T>\nTINYFORMAT_NOINLINE // < greatly reduces bloat in optimized builds\n    void\n    FormatIterator::accept(const T &value)\n{\n    // Parse the format string\n    const char *fmtEnd = 0;\n    if (m_extraFlags == Flag_None && !m_wantWidth && !m_wantPrecision)\n    {\n        m_fmt = printFormatStringLiteral(m_out, m_fmt);\n        fmtEnd = streamStateFromFormat(m_out, m_extraFlags, m_fmt, 0, 0);\n        m_wantWidth = (m_extraFlags & Flag_VariableWidth) != 0;\n        m_wantPrecision = (m_extraFlags & Flag_VariablePrecision) != 0;\n    }\n    // Consume value as variable width and precision specifier if necessary\n    if (m_extraFlags & (Flag_VariableWidth | Flag_VariablePrecision))\n    {\n        if (m_wantWidth || m_wantPrecision)\n        {\n            int v = convertToInt<T>::invoke(value);\n            if (m_wantWidth)\n            {\n                m_variableWidth = v;\n                m_wantWidth = false;\n            }\n            else if (m_wantPrecision)\n            {\n                m_variablePrecision = v;\n                m_wantPrecision = false;\n            }\n            return;\n        }\n        // If we get here, we've set both the variable precision and width as\n        // required and we need to rerun the stream state setup to insert these.\n        fmtEnd = streamStateFromFormat(m_out, m_extraFlags, m_fmt,\n                                       m_variableWidth, m_variablePrecision);\n    }\n\n    // Format the value into the stream.\n    if (!(m_extraFlags & (Flag_SpacePadPositive | Flag_TruncateToPrecision)))\n        formatValue(m_out, m_fmt, fmtEnd, value);\n    else\n    {\n        // The following are special cases where there's no direct\n        // correspondence between stream formatting and the printf() behaviour.\n        // Instead, we simulate the behaviour crudely by formatting into a\n        // temporary string stream and munging the resulting string.\n        std::ostringstream tmpStream;\n        tmpStream.copyfmt(m_out);\n        if (m_extraFlags & Flag_SpacePadPositive)\n            tmpStream.setf(std::ios::showpos);\n        // formatCStringTruncate is required for truncating conversions like\n        // \"%.4s\" where at most 4 characters of the c-string should be read.\n        // If we didn't include this special case, we might read off the end.\n        if (!((m_extraFlags & Flag_TruncateToPrecision) &&\n              formatCStringTruncate(tmpStream, value, m_out.precision())))\n        {\n            // Not a truncated c-string; just format normally.\n            formatValue(tmpStream, m_fmt, fmtEnd, value);\n        }\n        std::string result = tmpStream.str(); // allocates... yuck.\n        if (m_extraFlags & Flag_SpacePadPositive)\n        {\n            for (size_t i = 0, iend = result.size(); i < iend; ++i)\n                if (result[i] == '+')\n                    result[i] = ' ';\n        }\n        if ((m_extraFlags & Flag_TruncateToPrecision) &&\n            (int)result.size() > (int)m_out.precision())\n            m_out.write(result.c_str(), m_out.precision());\n        else\n            m_out << result;\n    }\n    m_extraFlags = Flag_None;\n    m_fmt = fmtEnd;\n}\n\n// Parse a format string and set the stream state accordingly.\n//\n// The format mini-language recognized here is meant to be the one from C99,\n// with the form \"%[flags][width][.precision][length]type\".\n//\n// Formatting options which can't be natively represented using the ostream\n// state are returned in the extraFlags parameter which is a bitwise\n// combination of values from the ExtraFormatFlags enum.\ninline const char *FormatIterator::streamStateFromFormat(std::ostream &out,\n                                                         unsigned int &extraFlags,\n                                                         const char *fmtStart,\n                                                         int variableWidth,\n                                                         int variablePrecision)\n{\n    if (*fmtStart != '%')\n    {\n        TINYFORMAT_ERROR(\"tinyformat: Not enough conversion specifiers in format string\");\n        return fmtStart;\n    }\n    // Reset stream state to defaults.\n    out.width(0);\n    out.precision(6);\n    out.fill(' ');\n    // Reset most flags; ignore irrelevant unitbuf & skipws.\n    out.unsetf(std::ios::adjustfield | std::ios::basefield |\n               std::ios::floatfield | std::ios::showbase | std::ios::boolalpha |\n               std::ios::showpoint | std::ios::showpos | std::ios::uppercase);\n    extraFlags = Flag_None;\n    bool precisionSet = false;\n    bool widthSet = false;\n    const char *c = fmtStart + 1;\n    // 1) Parse flags\n    for (;; ++c)\n    {\n        switch (*c)\n        {\n        case '#':\n            out.setf(std::ios::showpoint | std::ios::showbase);\n            continue;\n        case '0':\n            // overridden by left alignment ('-' flag)\n            if (!(out.flags() & std::ios::left))\n            {\n                // Use internal padding so that numeric values are\n                // formatted correctly, eg -00010 rather than 000-10\n                out.fill('0');\n                out.setf(std::ios::internal, std::ios::adjustfield);\n            }\n            continue;\n        case '-':\n            out.fill(' ');\n            out.setf(std::ios::left, std::ios::adjustfield);\n            continue;\n        case ' ':\n            // overridden by show positive sign, '+' flag.\n            if (!(out.flags() & std::ios::showpos))\n                extraFlags |= Flag_SpacePadPositive;\n            continue;\n        case '+':\n            out.setf(std::ios::showpos);\n            extraFlags &= ~Flag_SpacePadPositive;\n            continue;\n        }\n        break;\n    }\n    // 2) Parse width\n    if (*c >= '0' && *c <= '9')\n    {\n        widthSet = true;\n        out.width(parseIntAndAdvance(c));\n    }\n    if (*c == '*')\n    {\n        widthSet = true;\n        if (variableWidth < 0)\n        {\n            // negative widths correspond to '-' flag set\n            out.fill(' ');\n            out.setf(std::ios::left, std::ios::adjustfield);\n            variableWidth = -variableWidth;\n        }\n        out.width(variableWidth);\n        extraFlags |= Flag_VariableWidth;\n        ++c;\n    }\n    // 3) Parse precision\n    if (*c == '.')\n    {\n        ++c;\n        int precision = 0;\n        if (*c == '*')\n        {\n            ++c;\n            extraFlags |= Flag_VariablePrecision;\n            precision = variablePrecision;\n        }\n        else\n        {\n            if (*c >= '0' && *c <= '9')\n                precision = parseIntAndAdvance(c);\n            else if (*c == '-') // negative precisions ignored, treated as zero.\n                parseIntAndAdvance(++c);\n        }\n        out.precision(precision);\n        precisionSet = true;\n    }\n    // 4) Ignore any C99 length modifier\n    while (*c == 'l' || *c == 'h' || *c == 'L' ||\n           *c == 'j' || *c == 'z' || *c == 't')\n        ++c;\n    // 5) We're up to the conversion specifier character.\n    // Set stream flags based on conversion specifier (thanks to the\n    // boost::format class for forging the way here).\n    bool intConversion = false;\n    switch (*c)\n    {\n    case 'u':\n    case 'd':\n    case 'i':\n        out.setf(std::ios::dec, std::ios::basefield);\n        intConversion = true;\n        break;\n    case 'o':\n        out.setf(std::ios::oct, std::ios::basefield);\n        intConversion = true;\n        break;\n    case 'X':\n        out.setf(std::ios::uppercase);\n    case 'x':\n    case 'p':\n        out.setf(std::ios::hex, std::ios::basefield);\n        intConversion = true;\n        break;\n    case 'E':\n        out.setf(std::ios::uppercase);\n    case 'e':\n        out.setf(std::ios::scientific, std::ios::floatfield);\n        out.setf(std::ios::dec, std::ios::basefield);\n        break;\n    case 'F':\n        out.setf(std::ios::uppercase);\n    case 'f':\n        out.setf(std::ios::fixed, std::ios::floatfield);\n        break;\n    case 'G':\n        out.setf(std::ios::uppercase);\n    case 'g':\n        out.setf(std::ios::dec, std::ios::basefield);\n        // As in boost::format, let stream decide float format.\n        out.flags(out.flags() & ~std::ios::floatfield);\n        break;\n    case 'a':\n    case 'A':\n        TINYFORMAT_ERROR(\"tinyformat: the %a and %A conversion specs \"\n                         \"are not supported\");\n        break;\n    case 'c':\n        // Handled as special case inside formatValue()\n        break;\n    case 's':\n        if (precisionSet)\n            extraFlags |= Flag_TruncateToPrecision;\n        // Make %s print booleans as \"true\" and \"false\"\n        out.setf(std::ios::boolalpha);\n        break;\n    case 'n':\n        // Not supported - will cause problems!\n        TINYFORMAT_ERROR(\"tinyformat: %n conversion spec not supported\");\n        break;\n    case '\\0':\n        TINYFORMAT_ERROR(\"tinyformat: Conversion spec incorrectly \"\n                         \"terminated by end of string\");\n        return c;\n    }\n    if (intConversion && precisionSet && !widthSet)\n    {\n        // \"precision\" for integers gives the minimum number of digits (to be\n        // padded with zeros on the left).  This isn't really supported by the\n        // iostreams, but we can approximately simulate it with the width if\n        // the width isn't otherwise used.\n        out.width(out.precision());\n        out.setf(std::ios::internal, std::ios::adjustfield);\n        out.fill('0');\n    }\n    return c + 1;\n}\n\n//------------------------------------------------------------------------------\n// Private format function on top of which the public interface is implemented.\n// We enforce a mimimum of one value to be formatted to prevent bugs looking like\n//\n//   const char* myStr = \"100% broken\";\n//   printf(myStr);   // Parses % as a format specifier\n#ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES\n\ntemplate <typename T1>\nvoid format(FormatIterator &fmtIter, const T1 &value1)\n{\n    fmtIter.accept(value1);\n    fmtIter.finish();\n}\n\n// General version for C++11\ntemplate <typename T1, typename... Args>\nvoid format(FormatIterator &fmtIter, const T1 &value1, const Args &... args)\n{\n    fmtIter.accept(value1);\n    format(fmtIter, args...);\n}\n\n#else\n\ninline void format(FormatIterator &fmtIter)\n{\n    fmtIter.finish();\n}\n\n// General version for C++98\n#define TINYFORMAT_MAKE_FORMAT_DETAIL(n)                                \\\n    template <TINYFORMAT_ARGTYPES(n)>                                   \\\n    void format(detail::FormatIterator &fmtIter, TINYFORMAT_VARARGS(n)) \\\n    {                                                                   \\\n        fmtIter.accept(v1);                                             \\\n        format(fmtIter TINYFORMAT_PASSARGS_TAIL(n));                    \\\n    }\n\nTINYFORMAT_FOREACH_ARGNUM(TINYFORMAT_MAKE_FORMAT_DETAIL)\n#undef TINYFORMAT_MAKE_FORMAT_DETAIL\n\n#endif // End C++98 variadic template emulation for format()\n\n} // namespace detail\n\n//------------------------------------------------------------------------------\n// Implement all the main interface functions here in terms of detail::format()\n\n#ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES\n\n// C++11 - the simple case\ntemplate <typename T1, typename... Args>\nvoid format(std::ostream &out, const char *fmt, const T1 &v1, const Args &... args)\n{\n    detail::FormatIterator fmtIter(out, fmt);\n    format(fmtIter, v1, args...);\n}\n\ntemplate <typename T1, typename... Args>\nstd::string format(const char *fmt, const T1 &v1, const Args &... args)\n{\n    std::ostringstream oss;\n    format(oss, fmt, v1, args...);\n    return oss.str();\n}\n\ntemplate <typename T1, typename... Args>\nstd::string format(const std::string &fmt, const T1 &v1, const Args &... args)\n{\n    std::ostringstream oss;\n    format(oss, fmt.c_str(), v1, args...);\n    return oss.str();\n}\n\ntemplate <typename T1, typename... Args>\nvoid printf(const char *fmt, const T1 &v1, const Args &... args)\n{\n    format(std::cout, fmt, v1, args...);\n}\n\n#else\n\n// C++98 - define the interface functions using the wrapping macros\n#define TINYFORMAT_MAKE_FORMAT_FUNCS(n)                                    \\\n                                                                           \\\n    template <TINYFORMAT_ARGTYPES(n)>                                      \\\n    void format(std::ostream &out, const char *fmt, TINYFORMAT_VARARGS(n)) \\\n    {                                                                      \\\n        tinyformat::detail::FormatIterator fmtIter(out, fmt);              \\\n        tinyformat::detail::format(fmtIter, TINYFORMAT_PASSARGS(n));       \\\n    }                                                                      \\\n                                                                           \\\n    template <TINYFORMAT_ARGTYPES(n)>                                      \\\n    std::string format(const char *fmt, TINYFORMAT_VARARGS(n))             \\\n    {                                                                      \\\n        std::ostringstream oss;                                            \\\n        tinyformat::format(oss, fmt, TINYFORMAT_PASSARGS(n));              \\\n        return oss.str();                                                  \\\n    }                                                                      \\\n                                                                           \\\n    template <TINYFORMAT_ARGTYPES(n)>                                      \\\n    std::string format(const std::string &fmt, TINYFORMAT_VARARGS(n))      \\\n    {                                                                      \\\n        std::ostringstream oss;                                            \\\n        tinyformat::format(oss, fmt.c_str(), TINYFORMAT_PASSARGS(n));      \\\n        return oss.str();                                                  \\\n    }                                                                      \\\n                                                                           \\\n    template <TINYFORMAT_ARGTYPES(n)>                                      \\\n    void printf(const char *fmt, TINYFORMAT_VARARGS(n))                    \\\n    {                                                                      \\\n        tinyformat::format(std::cout, fmt, TINYFORMAT_PASSARGS(n));        \\\n    }\n\nTINYFORMAT_FOREACH_ARGNUM(TINYFORMAT_MAKE_FORMAT_FUNCS)\n#undef TINYFORMAT_MAKE_FORMAT_FUNCS\n#endif\n\n//------------------------------------------------------------------------------\n// Define deprecated wrapping macro for backward compatibility in tinyformat\n// 1.x.  Will be removed in version 2!\n#define TINYFORMAT_WRAP_FORMAT_EXTRA_ARGS\n#define TINYFORMAT_WRAP_FORMAT_N(n, returnType, funcName, funcDeclSuffix,  \\\n                                 bodyPrefix, streamName, bodySuffix)       \\\n    template <TINYFORMAT_ARGTYPES(n)>                                      \\\n    returnType funcName(TINYFORMAT_WRAP_FORMAT_EXTRA_ARGS const char *fmt, \\\n                        TINYFORMAT_VARARGS(n)) funcDeclSuffix              \\\n    {                                                                      \\\n        bodyPrefix                                                         \\\n            tinyformat::format(streamName, fmt, TINYFORMAT_PASSARGS(n));   \\\n        bodySuffix                                                         \\\n    }\n\n#define TINYFORMAT_WRAP_FORMAT(returnType, funcName, funcDeclSuffix,                                       \\\n                               bodyPrefix, streamName, bodySuffix)                                         \\\n    inline returnType funcName(TINYFORMAT_WRAP_FORMAT_EXTRA_ARGS const char *fmt) funcDeclSuffix           \\\n    {                                                                                                      \\\n        bodyPrefix                                                                                         \\\n            tinyformat::detail::FormatIterator(streamName, fmt)                                            \\\n                .finish();                                                                                 \\\n        bodySuffix                                                                                         \\\n    }                                                                                                      \\\n    TINYFORMAT_WRAP_FORMAT_N(1, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix)  \\\n    TINYFORMAT_WRAP_FORMAT_N(2, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix)  \\\n    TINYFORMAT_WRAP_FORMAT_N(3, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix)  \\\n    TINYFORMAT_WRAP_FORMAT_N(4, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix)  \\\n    TINYFORMAT_WRAP_FORMAT_N(5, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix)  \\\n    TINYFORMAT_WRAP_FORMAT_N(6, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix)  \\\n    TINYFORMAT_WRAP_FORMAT_N(7, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix)  \\\n    TINYFORMAT_WRAP_FORMAT_N(8, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix)  \\\n    TINYFORMAT_WRAP_FORMAT_N(9, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix)  \\\n    TINYFORMAT_WRAP_FORMAT_N(10, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \\\n    TINYFORMAT_WRAP_FORMAT_N(11, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \\\n    TINYFORMAT_WRAP_FORMAT_N(12, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \\\n    TINYFORMAT_WRAP_FORMAT_N(13, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \\\n    TINYFORMAT_WRAP_FORMAT_N(14, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \\\n    TINYFORMAT_WRAP_FORMAT_N(15, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix) \\\n    TINYFORMAT_WRAP_FORMAT_N(16, returnType, funcName, funcDeclSuffix, bodyPrefix, streamName, bodySuffix)\n\n} // namespace tinyformat\n\n#define strprintf tfm::format\n\n#endif // TINYFORMAT_H_INCLUDED\n"
  },
  {
    "path": "src/UChainService/consensus/clone/uint256.cpp",
    "content": "// Copyright (c) 2009-2010 Satoshi Nakamoto\n// Copyright (c) 2009-2015 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#include \"uint256.h\"\n\n#include \"utilstrencodings.h\"\n\n#include <stdio.h>\n#include <string.h>\n\ntemplate <unsigned int BITS>\nbase_blob<BITS>::base_blob(const std::vector<unsigned char> &vch)\n{\n    assert(vch.size() == sizeof(data));\n    memcpy(data, &vch[0], sizeof(data));\n}\n\ntemplate <unsigned int BITS>\nstd::string base_blob<BITS>::GetHex() const\n{\n    char psz[sizeof(data) * 2 + 1];\n    for (unsigned int i = 0; i < sizeof(data); i++)\n        sprintf(psz + i * 2, \"%02x\", data[sizeof(data) - i - 1]);\n    return std::string(psz, psz + sizeof(data) * 2);\n}\n\ntemplate <unsigned int BITS>\nvoid base_blob<BITS>::SetHex(const char *psz)\n{\n    memset(data, 0, sizeof(data));\n\n    // skip leading spaces\n    while (isspace(*psz))\n        psz++;\n\n    // skip 0x\n    if (psz[0] == '0' && tolower(psz[1]) == 'x')\n        psz += 2;\n\n    // hex string to uint\n    const char *pbegin = psz;\n    while (::HexDigit(*psz) != -1)\n        psz++;\n    psz--;\n    unsigned char *p1 = (unsigned char *)data;\n    unsigned char *pend = p1 + WIDTH;\n    while (psz >= pbegin && p1 < pend)\n    {\n        *p1 = ::HexDigit(*psz--);\n        if (psz >= pbegin)\n        {\n            *p1 |= ((unsigned char)::HexDigit(*psz--) << 4);\n            p1++;\n        }\n    }\n}\n\ntemplate <unsigned int BITS>\nvoid base_blob<BITS>::SetHex(const std::string &str)\n{\n    SetHex(str.c_str());\n}\n\ntemplate <unsigned int BITS>\nstd::string base_blob<BITS>::ToString() const\n{\n    return (GetHex());\n}\n\n// Explicit instantiations for base_blob<160>\ntemplate base_blob<160>::base_blob(const std::vector<unsigned char> &);\ntemplate std::string base_blob<160>::GetHex() const;\ntemplate std::string base_blob<160>::ToString() const;\ntemplate void base_blob<160>::SetHex(const char *);\ntemplate void base_blob<160>::SetHex(const std::string &);\n\n// Explicit instantiations for base_blob<256>\ntemplate base_blob<256>::base_blob(const std::vector<unsigned char> &);\ntemplate std::string base_blob<256>::GetHex() const;\ntemplate std::string base_blob<256>::ToString() const;\ntemplate void base_blob<256>::SetHex(const char *);\ntemplate void base_blob<256>::SetHex(const std::string &);\n\nstatic void inline HashMix(uint32_t &a, uint32_t &b, uint32_t &c)\n{\n    // Taken from lookup3, by Bob Jenkins.\n    a -= c;\n    a ^= ((c << 4) | (c >> 28));\n    c += b;\n    b -= a;\n    b ^= ((a << 6) | (a >> 26));\n    a += c;\n    c -= b;\n    c ^= ((b << 8) | (b >> 24));\n    b += a;\n    a -= c;\n    a ^= ((c << 16) | (c >> 16));\n    c += b;\n    b -= a;\n    b ^= ((a << 19) | (a >> 13));\n    a += c;\n    c -= b;\n    c ^= ((b << 4) | (b >> 28));\n    b += a;\n}\n\nstatic void inline HashFinal(uint32_t &a, uint32_t &b, uint32_t &c)\n{\n    // Taken from lookup3, by Bob Jenkins.\n    c ^= b;\n    c -= ((b << 14) | (b >> 18));\n    a ^= c;\n    a -= ((c << 11) | (c >> 21));\n    b ^= a;\n    b -= ((a << 25) | (a >> 7));\n    c ^= b;\n    c -= ((b << 16) | (b >> 16));\n    a ^= c;\n    a -= ((c << 4) | (c >> 28));\n    b ^= a;\n    b -= ((a << 14) | (a >> 18));\n    c ^= b;\n    c -= ((b << 24) | (b >> 8));\n}\n\nuint64_t uint256::GetHash(const uint256 &salt) const\n{\n    uint32_t a, b, c;\n    const uint32_t *pn = (const uint32_t *)data;\n    const uint32_t *salt_pn = (const uint32_t *)salt.data;\n    a = b = c = 0xdeadbeef + WIDTH;\n\n    a += pn[0] ^ salt_pn[0];\n    b += pn[1] ^ salt_pn[1];\n    c += pn[2] ^ salt_pn[2];\n    HashMix(a, b, c);\n    a += pn[3] ^ salt_pn[3];\n    b += pn[4] ^ salt_pn[4];\n    c += pn[5] ^ salt_pn[5];\n    HashMix(a, b, c);\n    a += pn[6] ^ salt_pn[6];\n    b += pn[7] ^ salt_pn[7];\n    HashFinal(a, b, c);\n\n    return ((((uint64_t)b) << 32) | c);\n}\n"
  },
  {
    "path": "src/UChainService/consensus/clone/uint256.h",
    "content": "// Copyright (c) 2009-2010 Satoshi Nakamoto\n// Copyright (c) 2009-2015 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#ifndef BITCOIN_UINT256_H\n#define BITCOIN_UINT256_H\n\n#include <assert.h>\n#include <cstring>\n#include <stdexcept>\n#include <stdint.h>\n#include <string>\n#include <vector>\n#include \"crypto/common.h\"\n\n/** Template base class for fixed-sized opaque blobs. */\ntemplate <unsigned int BITS>\nclass base_blob\n{\n  protected:\n    enum\n    {\n        WIDTH = BITS / 8\n    };\n    uint8_t data[WIDTH];\n\n  public:\n    base_blob()\n    {\n        memset(data, 0, sizeof(data));\n    }\n\n    explicit base_blob(const std::vector<unsigned char> &vch);\n\n    bool IsNull() const\n    {\n        for (int i = 0; i < WIDTH; i++)\n            if (data[i] != 0)\n                return false;\n        return true;\n    }\n\n    void SetNull()\n    {\n        memset(data, 0, sizeof(data));\n    }\n\n    friend inline bool operator==(const base_blob &a, const base_blob &b) { return memcmp(a.data, b.data, sizeof(a.data)) == 0; }\n    friend inline bool operator!=(const base_blob &a, const base_blob &b) { return memcmp(a.data, b.data, sizeof(a.data)) != 0; }\n    friend inline bool operator<(const base_blob &a, const base_blob &b) { return memcmp(a.data, b.data, sizeof(a.data)) < 0; }\n\n    std::string GetHex() const;\n    void SetHex(const char *psz);\n    void SetHex(const std::string &str);\n    std::string ToString() const;\n\n    unsigned char *begin()\n    {\n        return &data[0];\n    }\n\n    unsigned char *end()\n    {\n        return &data[WIDTH];\n    }\n\n    const unsigned char *begin() const\n    {\n        return &data[0];\n    }\n\n    const unsigned char *end() const\n    {\n        return &data[WIDTH];\n    }\n\n    unsigned int size() const\n    {\n        return sizeof(data);\n    }\n\n    unsigned int GetSerializeSize(int nType, int nVersion) const\n    {\n        return sizeof(data);\n    }\n\n    template <typename Stream>\n    void Serialize(Stream &s, int nType, int nVersion) const\n    {\n        s.write((char *)data, sizeof(data));\n    }\n\n    template <typename Stream>\n    void Unserialize(Stream &s, int nType, int nVersion)\n    {\n        s.read((char *)data, sizeof(data));\n    }\n};\n\n/** 160-bit opaque blob.\n * @note This type is called uint160 for historical reasons only. It is an opaque\n * blob of 160 bits and has no integer operations.\n */\nclass uint160 : public base_blob<160>\n{\n  public:\n    uint160() {}\n    uint160(const base_blob<160> &b) : base_blob<160>(b) {}\n    explicit uint160(const std::vector<unsigned char> &vch) : base_blob<160>(vch) {}\n};\n\n/** 256-bit opaque blob.\n * @note This type is called uint256 for historical reasons only. It is an\n * opaque blob of 256 bits and has no integer operations. Use arith_uint256 if\n * those are required.\n */\nclass uint256 : public base_blob<256>\n{\n  public:\n    uint256() {}\n    uint256(const base_blob<256> &b) : base_blob<256>(b) {}\n    explicit uint256(const std::vector<unsigned char> &vch) : base_blob<256>(vch) {}\n\n    /** A cheap hash function that just returns 64 bits from the result, it can be\n     * used when the contents are considered uniformly random. It is not appropriate\n     * when the value can easily be influenced from outside as e.g. a network adversary could\n     * provide values to trigger worst-case behavior.\n     */\n    uint64_t GetCheapHash() const\n    {\n        return ReadLE64(data);\n    }\n\n    /** A more secure, salted hash function.\n     * @note This hash is not stable between little and big endian.\n     */\n    uint64_t GetHash(const uint256 &salt) const;\n};\n\n/* uint256 from const char *.\n * This is a separate function because the constructor uint256(const char*) can result\n * in dangerously catching uint256(0).\n */\ninline uint256 uint256S(const char *str)\n{\n    uint256 rv;\n    rv.SetHex(str);\n    return rv;\n}\n/* uint256 from std::string.\n * This is a separate function because the constructor uint256(const std::string &str) can result\n * in dangerously catching uint256(0) via std::string(const char*).\n */\ninline uint256 uint256S(const std::string &str)\n{\n    uint256 rv;\n    rv.SetHex(str);\n    return rv;\n}\n\n#endif // BITCOIN_UINT256_H\n"
  },
  {
    "path": "src/UChainService/consensus/clone/utilstrencodings.cpp",
    "content": "// Copyright (c) 2009-2010 Satoshi Nakamoto\n// Copyright (c) 2009-2015 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#include \"utilstrencodings.h\"\n\n#include \"tinyformat.h\"\n\n#include <cstdlib>\n#include <cstring>\n#include <errno.h>\n#include <limits>\n\nusing namespace std;\n\nstatic const string CHARS_ALPHA_NUM = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";\n\nstatic const string SAFE_CHARS[] =\n    {\n        CHARS_ALPHA_NUM + \" .,;-_/:?@()\", // SAFE_CHARS_DEFAULT\n        CHARS_ALPHA_NUM + \" .,;-_?@\"      // SAFE_CHARS_UA_COMMENT\n};\n\nstring SanitizeString(const string &str, int rule)\n{\n    string strResult;\n    for (std::string::size_type i = 0; i < str.size(); i++)\n    {\n        if (SAFE_CHARS[rule].find(str[i]) != std::string::npos)\n            strResult.push_back(str[i]);\n    }\n    return strResult;\n}\n\nconst signed char p_util_hexdigit[256] =\n    {\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        0,\n        1,\n        2,\n        3,\n        4,\n        5,\n        6,\n        7,\n        8,\n        9,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        0xa,\n        0xb,\n        0xc,\n        0xd,\n        0xe,\n        0xf,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        0xa,\n        0xb,\n        0xc,\n        0xd,\n        0xe,\n        0xf,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n        -1,\n};\n\nsigned char HexDigit(char c)\n{\n    return p_util_hexdigit[(unsigned char)c];\n}\n\nbool IsHex(const string &str)\n{\n    for (std::string::const_iterator it(str.begin()); it != str.end(); ++it)\n    {\n        if (HexDigit(*it) < 0)\n            return false;\n    }\n    return (str.size() > 0) && (str.size() % 2 == 0);\n}\n\nvector<unsigned char> ParseHex(const char *psz)\n{\n    // convert hex dump to vector\n    vector<unsigned char> vch;\n    while (true)\n    {\n        while (isspace(*psz))\n            psz++;\n        signed char c = HexDigit(*psz++);\n        if (c == (signed char)-1)\n            break;\n        unsigned char n = (c << 4);\n        c = HexDigit(*psz++);\n        if (c == (signed char)-1)\n            break;\n        n |= c;\n        vch.push_back(n);\n    }\n    return vch;\n}\n\nvector<unsigned char> ParseHex(const string &str)\n{\n    return ParseHex(str.c_str());\n}\n\nstring EncodeBase64(const unsigned char *pch, size_t len)\n{\n    static const char *pbase64 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\n    string strRet = \"\";\n    strRet.reserve((len + 2) / 3 * 4);\n\n    int mode = 0, left = 0;\n    const unsigned char *pchEnd = pch + len;\n\n    while (pch < pchEnd)\n    {\n        int enc = *(pch++);\n        switch (mode)\n        {\n        case 0: // we have no bits\n            strRet += pbase64[enc >> 2];\n            left = (enc & 3) << 4;\n            mode = 1;\n            break;\n\n        case 1: // we have two bits\n            strRet += pbase64[left | (enc >> 4)];\n            left = (enc & 15) << 2;\n            mode = 2;\n            break;\n\n        case 2: // we have four bits\n            strRet += pbase64[left | (enc >> 6)];\n            strRet += pbase64[enc & 63];\n            mode = 0;\n            break;\n        }\n    }\n\n    if (mode)\n    {\n        strRet += pbase64[left];\n        strRet += '=';\n        if (mode == 1)\n            strRet += '=';\n    }\n\n    return strRet;\n}\n\nstring EncodeBase64(const string &str)\n{\n    return EncodeBase64((const unsigned char *)str.c_str(), str.size());\n}\n\nvector<unsigned char> DecodeBase64(const char *p, bool *pfInvalid)\n{\n    static const int decode64_table[256] =\n        {\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1,\n            -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,\n            15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,\n            29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,\n            49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};\n\n    if (pfInvalid)\n        *pfInvalid = false;\n\n    vector<unsigned char> vchRet;\n    vchRet.reserve(strlen(p) * 3 / 4);\n\n    int mode = 0;\n    int left = 0;\n\n    while (1)\n    {\n        int dec = decode64_table[(unsigned char)*p];\n        if (dec == -1)\n            break;\n        p++;\n        switch (mode)\n        {\n        case 0: // we have no bits and get 6\n            left = dec;\n            mode = 1;\n            break;\n\n        case 1: // we have 6 bits and keep 4\n            vchRet.push_back((left << 2) | (dec >> 4));\n            left = dec & 15;\n            mode = 2;\n            break;\n\n        case 2: // we have 4 bits and get 6, we keep 2\n            vchRet.push_back((left << 4) | (dec >> 2));\n            left = dec & 3;\n            mode = 3;\n            break;\n\n        case 3: // we have 2 bits and get 6\n            vchRet.push_back((left << 6) | dec);\n            mode = 0;\n            break;\n        }\n    }\n\n    if (pfInvalid)\n        switch (mode)\n        {\n        case 0: // 4n base64 characters processed: ok\n            break;\n\n        case 1: // 4n+1 base64 character processed: impossible\n            *pfInvalid = true;\n            break;\n\n        case 2: // 4n+2 base64 characters processed: require '=='\n            if (left || p[0] != '=' || p[1] != '=' || decode64_table[(unsigned char)p[2]] != -1)\n                *pfInvalid = true;\n            break;\n\n        case 3: // 4n+3 base64 characters processed: require '='\n            if (left || p[0] != '=' || decode64_table[(unsigned char)p[1]] != -1)\n                *pfInvalid = true;\n            break;\n        }\n\n    return vchRet;\n}\n\nstring DecodeBase64(const string &str)\n{\n    vector<unsigned char> vchRet = DecodeBase64(str.c_str());\n    return (vchRet.size() == 0) ? string() : string((const char *)&vchRet[0], vchRet.size());\n}\n\nstring EncodeBase32(const unsigned char *pch, size_t len)\n{\n    static const char *pbase32 = \"abcdefghijklmnopqrstuvwxyz234567\";\n\n    string strRet = \"\";\n    strRet.reserve((len + 4) / 5 * 8);\n\n    int mode = 0, left = 0;\n    const unsigned char *pchEnd = pch + len;\n\n    while (pch < pchEnd)\n    {\n        int enc = *(pch++);\n        switch (mode)\n        {\n        case 0: // we have no bits\n            strRet += pbase32[enc >> 3];\n            left = (enc & 7) << 2;\n            mode = 1;\n            break;\n\n        case 1: // we have three bits\n            strRet += pbase32[left | (enc >> 6)];\n            strRet += pbase32[(enc >> 1) & 31];\n            left = (enc & 1) << 4;\n            mode = 2;\n            break;\n\n        case 2: // we have one bit\n            strRet += pbase32[left | (enc >> 4)];\n            left = (enc & 15) << 1;\n            mode = 3;\n            break;\n\n        case 3: // we have four bits\n            strRet += pbase32[left | (enc >> 7)];\n            strRet += pbase32[(enc >> 2) & 31];\n            left = (enc & 3) << 3;\n            mode = 4;\n            break;\n\n        case 4: // we have two bits\n            strRet += pbase32[left | (enc >> 5)];\n            strRet += pbase32[enc & 31];\n            mode = 0;\n        }\n    }\n\n    static const int nPadding[5] = {0, 6, 4, 3, 1};\n    if (mode)\n    {\n        strRet += pbase32[left];\n        for (int n = 0; n < nPadding[mode]; n++)\n            strRet += '=';\n    }\n\n    return strRet;\n}\n\nstring EncodeBase32(const string &str)\n{\n    return EncodeBase32((const unsigned char *)str.c_str(), str.size());\n}\n\nvector<unsigned char> DecodeBase32(const char *p, bool *pfInvalid)\n{\n    static const int decode32_table[256] =\n        {\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,\n            15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 0, 1, 2,\n            3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,\n            23, 24, 25, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,\n            -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};\n\n    if (pfInvalid)\n        *pfInvalid = false;\n\n    vector<unsigned char> vchRet;\n    vchRet.reserve((strlen(p)) * 5 / 8);\n\n    int mode = 0;\n    int left = 0;\n\n    while (1)\n    {\n        int dec = decode32_table[(unsigned char)*p];\n        if (dec == -1)\n            break;\n        p++;\n        switch (mode)\n        {\n        case 0: // we have no bits and get 5\n            left = dec;\n            mode = 1;\n            break;\n\n        case 1: // we have 5 bits and keep 2\n            vchRet.push_back((left << 3) | (dec >> 2));\n            left = dec & 3;\n            mode = 2;\n            break;\n\n        case 2: // we have 2 bits and keep 7\n            left = left << 5 | dec;\n            mode = 3;\n            break;\n\n        case 3: // we have 7 bits and keep 4\n            vchRet.push_back((left << 1) | (dec >> 4));\n            left = dec & 15;\n            mode = 4;\n            break;\n\n        case 4: // we have 4 bits, and keep 1\n            vchRet.push_back((left << 4) | (dec >> 1));\n            left = dec & 1;\n            mode = 5;\n            break;\n\n        case 5: // we have 1 bit, and keep 6\n            left = left << 5 | dec;\n            mode = 6;\n            break;\n\n        case 6: // we have 6 bits, and keep 3\n            vchRet.push_back((left << 2) | (dec >> 3));\n            left = dec & 7;\n            mode = 7;\n            break;\n\n        case 7: // we have 3 bits, and keep 0\n            vchRet.push_back((left << 5) | dec);\n            mode = 0;\n            break;\n        }\n    }\n\n    if (pfInvalid)\n        switch (mode)\n        {\n        case 0: // 8n base32 characters processed: ok\n            break;\n\n        case 1: // 8n+1 base32 characters processed: impossible\n        case 3: //   +3\n        case 6: //   +6\n            *pfInvalid = true;\n            break;\n\n        case 2: // 8n+2 base32 characters processed: require '======'\n            if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || p[4] != '=' || p[5] != '=' || decode32_table[(unsigned char)p[6]] != -1)\n                *pfInvalid = true;\n            break;\n\n        case 4: // 8n+4 base32 characters processed: require '===='\n            if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || decode32_table[(unsigned char)p[4]] != -1)\n                *pfInvalid = true;\n            break;\n\n        case 5: // 8n+5 base32 characters processed: require '==='\n            if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || decode32_table[(unsigned char)p[3]] != -1)\n                *pfInvalid = true;\n            break;\n\n        case 7: // 8n+7 base32 characters processed: require '='\n            if (left || p[0] != '=' || decode32_table[(unsigned char)p[1]] != -1)\n                *pfInvalid = true;\n            break;\n        }\n\n    return vchRet;\n}\n\nstring DecodeBase32(const string &str)\n{\n    vector<unsigned char> vchRet = DecodeBase32(str.c_str());\n    return (vchRet.size() == 0) ? string() : string((const char *)&vchRet[0], vchRet.size());\n}\n\nstatic bool ParsePrechecks(const std::string &str)\n{\n    if (str.empty()) // No empty string allowed\n        return false;\n    if (str.size() >= 1 && (isspace(str[0]) || isspace(str[str.size() - 1]))) // No padding allowed\n        return false;\n    if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed\n        return false;\n    return true;\n}\n\nbool ParseInt32(const std::string &str, int32_t *out)\n{\n    if (!ParsePrechecks(str))\n        return false;\n    char *endp = NULL;\n    errno = 0; // strtol will not set errno if valid\n    long int n = strtol(str.c_str(), &endp, 10);\n    if (out)\n        *out = (int32_t)n;\n    // Note that strtol returns a *long int*, so even if strtol doesn't report a over/underflow\n    // we still have to check that the returned value is within the range of an *int32_t*. On 64-bit\n    // platforms the size of these types may be different.\n    return endp && *endp == 0 && !errno &&\n           n >= std::numeric_limits<int32_t>::min() &&\n           n <= std::numeric_limits<int32_t>::max();\n}\n\nbool ParseInt64(const std::string &str, int64_t *out)\n{\n    if (!ParsePrechecks(str))\n        return false;\n    char *endp = NULL;\n    errno = 0; // strtoll will not set errno if valid\n    long long int n = strtoll(str.c_str(), &endp, 10);\n    if (out)\n        *out = (int64_t)n;\n    // Note that strtoll returns a *long long int*, so even if strtol doesn't report a over/underflow\n    // we still have to check that the returned value is within the range of an *int64_t*.\n    return endp && *endp == 0 && !errno &&\n           n >= std::numeric_limits<int64_t>::min() &&\n           n <= std::numeric_limits<int64_t>::max();\n}\n\nbool ParseDouble(const std::string &str, double *out)\n{\n    if (!ParsePrechecks(str))\n        return false;\n    if (str.size() >= 2 && str[0] == '0' && str[1] == 'x') // No hexadecimal floats allowed\n        return false;\n    std::istringstream text(str);\n    text.imbue(std::locale::classic());\n    double result;\n    text >> result;\n    if (out)\n        *out = result;\n    return text.eof() && !text.fail();\n}\n\nstd::string FormatParagraph(const std::string &in, size_t width, size_t indent)\n{\n    std::stringstream out;\n    size_t col = 0;\n    size_t ptr = 0;\n    while (ptr < in.size())\n    {\n        // Find beginning of next word\n        ptr = in.find_first_not_of(' ', ptr);\n        if (ptr == std::string::npos)\n            break;\n        // Find end of next word\n        size_t endword = in.find_first_of(' ', ptr);\n        if (endword == std::string::npos)\n            endword = in.size();\n        // Add newline and indentation if this wraps over the allowed width\n        if (col > 0)\n        {\n            if ((col + endword - ptr) > width)\n            {\n                out << '\\n';\n                for (size_t i = 0; i < indent; ++i)\n                    out << ' ';\n                col = 0;\n            }\n            else\n                out << ' ';\n        }\n        // Append word\n        out << in.substr(ptr, endword - ptr);\n        col += endword - ptr + 1;\n        ptr = endword;\n    }\n    return out.str();\n}\n\nstd::string i64tostr(int64_t n)\n{\n    return strprintf(\"%d\", n);\n}\n\nstd::string itostr(int n)\n{\n    return strprintf(\"%d\", n);\n}\n\nint64_t atoi64(const char *psz)\n{\n#ifdef _MSC_VER\n    return _atoi64(psz);\n#else\n    return strtoll(psz, NULL, 10);\n#endif\n}\n\nint64_t atoi64(const std::string &str)\n{\n#ifdef _MSC_VER\n    return _atoi64(str.c_str());\n#else\n    return strtoll(str.c_str(), NULL, 10);\n#endif\n}\n\nint atoi(const std::string &str)\n{\n    return atoi(str.c_str());\n}\n\n/** Upper bound for mantissa.\n * 10^18-1 is the largest arbitrary decimal that will fit in a signed 64-bit integer.\n * Larger integers cannot consist of arbitrary combinations of 0-9:\n *\n *   999999999999999999  1^18-1\n *  9223372036854775807  (1<<63)-1  (max int64_t)\n *  9999999999999999999  1^19-1     (would overflow)\n */\nstatic const int64_t UPPER_BOUND = 1000000000000000000LL - 1LL;\n\n/** Helper function for ParseFixedPoint */\nstatic inline bool ProcessMantissaDigit(char ch, int64_t &mantissa, int &mantissa_tzeros)\n{\n    if (ch == '0')\n        ++mantissa_tzeros;\n    else\n    {\n        for (int i = 0; i <= mantissa_tzeros; ++i)\n        {\n            if (mantissa > (UPPER_BOUND / 10LL))\n                return false; /* overflow */\n            mantissa *= 10;\n        }\n        mantissa += ch - '0';\n        mantissa_tzeros = 0;\n    }\n    return true;\n}\n\nbool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out)\n{\n    int64_t mantissa = 0;\n    int64_t exponent = 0;\n    int mantissa_tzeros = 0;\n    bool mantissa_sign = false;\n    bool exponent_sign = false;\n    int ptr = 0;\n    int end = val.size();\n    int point_ofs = 0;\n\n    if (ptr < end && val[ptr] == '-')\n    {\n        mantissa_sign = true;\n        ++ptr;\n    }\n    if (ptr < end)\n    {\n        if (val[ptr] == '0')\n        {\n            /* pass single 0 */\n            ++ptr;\n        }\n        else if (val[ptr] >= '1' && val[ptr] <= '9')\n        {\n            while (ptr < end && val[ptr] >= '0' && val[ptr] <= '9')\n            {\n                if (!ProcessMantissaDigit(val[ptr], mantissa, mantissa_tzeros))\n                    return false; /* overflow */\n                ++ptr;\n            }\n        }\n        else\n            return false; /* missing expected digit */\n    }\n    else\n        return false; /* empty string or loose '-' */\n    if (ptr < end && val[ptr] == '.')\n    {\n        ++ptr;\n        if (ptr < end && val[ptr] >= '0' && val[ptr] <= '9')\n        {\n            while (ptr < end && val[ptr] >= '0' && val[ptr] <= '9')\n            {\n                if (!ProcessMantissaDigit(val[ptr], mantissa, mantissa_tzeros))\n                    return false; /* overflow */\n                ++ptr;\n                ++point_ofs;\n            }\n        }\n        else\n            return false; /* missing expected digit */\n    }\n    if (ptr < end && (val[ptr] == 'e' || val[ptr] == 'E'))\n    {\n        ++ptr;\n        if (ptr < end && val[ptr] == '+')\n            ++ptr;\n        else if (ptr < end && val[ptr] == '-')\n        {\n            exponent_sign = true;\n            ++ptr;\n        }\n        if (ptr < end && val[ptr] >= '0' && val[ptr] <= '9')\n        {\n            while (ptr < end && val[ptr] >= '0' && val[ptr] <= '9')\n            {\n                if (exponent > (UPPER_BOUND / 10LL))\n                    return false; /* overflow */\n                exponent = exponent * 10 + val[ptr] - '0';\n                ++ptr;\n            }\n        }\n        else\n            return false; /* missing expected digit */\n    }\n    if (ptr != end)\n        return false; /* trailing garbage */\n\n    /* finalize exponent */\n    if (exponent_sign)\n        exponent = -exponent;\n    exponent = exponent - point_ofs + mantissa_tzeros;\n\n    /* finalize mantissa */\n    if (mantissa_sign)\n        mantissa = -mantissa;\n\n    /* convert to one 64-bit fixed-point value */\n    exponent += decimals;\n    if (exponent < 0)\n        return false; /* cannot represent values smaller than 10^-decimals */\n    if (exponent >= 18)\n        return false; /* cannot represent values larger than or equal to 10^(18-decimals) */\n\n    for (int i = 0; i < exponent; ++i)\n    {\n        if (mantissa > (UPPER_BOUND / 10LL) || mantissa < -(UPPER_BOUND / 10LL))\n            return false; /* overflow */\n        mantissa *= 10;\n    }\n    if (mantissa > UPPER_BOUND || mantissa < -UPPER_BOUND)\n        return false; /* overflow */\n\n    if (amount_out)\n        *amount_out = mantissa;\n\n    return true;\n}\n"
  },
  {
    "path": "src/UChainService/consensus/clone/utilstrencodings.h",
    "content": "// Copyright (c) 2009-2010 Satoshi Nakamoto\n// Copyright (c) 2009-2015 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n/**\n * Utilities for converting data from/to strings.\n */\n#ifndef BITCOIN_UTILSTRENCODINGS_H\n#define BITCOIN_UTILSTRENCODINGS_H\n\n#include <stdint.h>\n#include <string>\n#include <vector>\n\n#define BEGIN(a) ((char *)&(a))\n#define END(a) ((char *)&((&(a))[1]))\n#define UBEGIN(a) ((unsigned char *)&(a))\n#define UEND(a) ((unsigned char *)&((&(a))[1]))\n#define ARRAYLEN(array) (sizeof(array) / sizeof((array)[0]))\n\n/** This is needed because the foreach macro can't get over the comma in pair<t1, t2> */\n#define PAIRTYPE(t1, t2) std::pair<t1, t2>\n\n/** Used by SanitizeString() */\nenum SafeChars\n{\n    SAFE_CHARS_DEFAULT,   //!< The full set of allowed chars\n    SAFE_CHARS_UA_COMMENT //!< BIP-0014 subset\n};\n\n/**\n* Remove unsafe chars. Safe chars chosen to allow simple messages/URLs/email\n* addresses, but avoid anything even possibly remotely dangerous like & or >\n* @param[in] str    The string to sanitize\n* @param[in] rule   The set of safe chars to choose (default: least restrictive)\n* @return           A new string without unsafe chars\n*/\nstd::string SanitizeString(const std::string &str, int rule = SAFE_CHARS_DEFAULT);\nstd::vector<unsigned char> ParseHex(const char *psz);\nstd::vector<unsigned char> ParseHex(const std::string &str);\nsigned char HexDigit(char c);\nbool IsHex(const std::string &str);\nstd::vector<unsigned char> DecodeBase64(const char *p, bool *pfInvalid = NULL);\nstd::string DecodeBase64(const std::string &str);\nstd::string EncodeBase64(const unsigned char *pch, size_t len);\nstd::string EncodeBase64(const std::string &str);\nstd::vector<unsigned char> DecodeBase32(const char *p, bool *pfInvalid = NULL);\nstd::string DecodeBase32(const std::string &str);\nstd::string EncodeBase32(const unsigned char *pch, size_t len);\nstd::string EncodeBase32(const std::string &str);\n\nstd::string i64tostr(int64_t n);\nstd::string itostr(int n);\nint64_t atoi64(const char *psz);\nint64_t atoi64(const std::string &str);\nint atoi(const std::string &str);\n\n/**\n * Convert string to signed 32-bit integer with strict parse error feedback.\n * @returns true if the entire string could be parsed as valid integer,\n *   false if not the entire string could be parsed or when overflow or underflow occurred.\n */\nbool ParseInt32(const std::string &str, int32_t *out);\n\n/**\n * Convert string to signed 64-bit integer with strict parse error feedback.\n * @returns true if the entire string could be parsed as valid integer,\n *   false if not the entire string could be parsed or when overflow or underflow occurred.\n */\nbool ParseInt64(const std::string &str, int64_t *out);\n\n/**\n * Convert string to double with strict parse error feedback.\n * @returns true if the entire string could be parsed as valid double,\n *   false if not the entire string could be parsed or when overflow or underflow occurred.\n */\nbool ParseDouble(const std::string &str, double *out);\n\ntemplate <typename T>\nstd::string HexStr(const T itbegin, const T itend, bool fSpaces = false)\n{\n    std::string rv;\n    static const char hexmap[16] = {'0', '1', '2', '3', '4', '5', '6', '7',\n                                    '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};\n    rv.reserve((itend - itbegin) * 3);\n    for (T it = itbegin; it < itend; ++it)\n    {\n        unsigned char val = (unsigned char)(*it);\n        if (fSpaces && it != itbegin)\n            rv.push_back(' ');\n        rv.push_back(hexmap[val >> 4]);\n        rv.push_back(hexmap[val & 15]);\n    }\n\n    return rv;\n}\n\ntemplate <typename T>\ninline std::string HexStr(const T &vch, bool fSpaces = false)\n{\n    return HexStr(vch.begin(), vch.end(), fSpaces);\n}\n\n/**\n * Format a paragraph of text to a fixed width, adding spaces for\n * indentation to any added line.\n */\nstd::string FormatParagraph(const std::string &in, size_t width = 79, size_t indent = 0);\n\n/**\n * Timing-attack-resistant comparison.\n * Takes time proportional to length\n * of first argument.\n */\ntemplate <typename T>\nbool TimingResistantEqual(const T &a, const T &b)\n{\n    if (b.size() == 0)\n        return a.size() == 0;\n    size_t accumulator = a.size() ^ b.size();\n    for (size_t i = 0; i < a.size(); i++)\n        accumulator |= a[i] ^ b[i % b.size()];\n    return accumulator == 0;\n}\n\n/** Parse number as fixed point according to JSON number syntax.\n * See http://json.org/number.gif\n * @returns true on success, false on error.\n * @note The result must be in the range (-10^18,10^18), otherwise an overflow error will trigger.\n */\nbool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out);\n\n#endif // BITCOIN_UTILSTRENCODINGS_H\n"
  },
  {
    "path": "src/UChainService/consensus/clone/version.h",
    "content": "// Copyright (c) 2012-2014 The Bitcoin Core developers\n// Distributed under the MIT software license, see the accompanying\n// file COPYING or http://www.opensource.org/licenses/mit-license.php.\n\n#ifndef BITCOIN_VERSION_H\n#define BITCOIN_VERSION_H\n\n/**\n * network protocol versioning\n */\n\nstatic const int PROTOCOL_VERSION = 70012;\n\n//! initial proto version, to be increased after version/verack negotiation\nstatic const int INIT_PROTO_VERSION = 209;\n\n//! In this version, 'getheaders' was introduced.\nstatic const int GETHEADERS_VERSION = 31800;\n\n//! disconnect from peers older than this proto version\nstatic const int MIN_PEER_PROTO_VERSION = GETHEADERS_VERSION;\n\n//! nTime field added to CAddress, starting with this version;\n//! if possible, avoid requesting addresses nodes older than this\nstatic const int CADDR_TIME_VERSION = 31402;\n\n//! only request blocks from nodes outside this range of versions\nstatic const int NOBLKS_VERSION_START = 32000;\nstatic const int NOBLKS_VERSION_END = 32400;\n\n//! BIP 0031, pong message, is enabled for all versions AFTER this one\nstatic const int BIP0031_VERSION = 60000;\n\n//! \"mempool\" command, enhanced \"getdata\" behavior starts with this version\nstatic const int MEMPOOL_GD_VERSION = 60002;\n\n//! \"filter*\" commands are disabled without NODE_BLOOM after and including this version\nstatic const int NO_BLOOM_VERSION = 70011;\n\n//! \"sendheaders\" command and announcing blocks with headers starts with this version\nstatic const int SENDHEADERS_VERSION = 70012;\n\n#endif // BITCOIN_VERSION_H\n"
  },
  {
    "path": "src/UChainService/consensus/common/libdevcore/Base64.cpp",
    "content": "/*\n   base64.cpp and base64.h\n\n   Copyright (C) 2004-2008 René Nyffenegger\n\n   This source code is provided 'as-is', without any express or implied\n   warranty. In no event will the author be held liable for any damages\n   arising from the use of this software.\n\n   Permission is granted to anyone to use this software for any purpose,\n   including commercial applications, and to alter it and redistribute it\n   freely, subject to the following restrictions:\n\n   1. The origin of this source code must not be misrepresented; you must not\n      claim that you wrote the original source code. If you use this source code\n      in a product, an acknowledgment in the product documentation would be\n      appreciated but is not required.\n\n   2. Altered source versions must be plainly marked as such, and must not be\n      misrepresented as being the original source code.\n\n   3. This notice may not be removed or altered from any source distribution.\n\n   René Nyffenegger rene.nyffenegger@adp-gmbh.ch\n*/\n/// Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c\n/// Originally by René Nyffenegger, modified by some other guy and then devified by Gav Wood.\n\n//#include \"Base64.h\"\n#include <UChainService/consensus/libdevcore/Base64.h>\n\nusing namespace std;\nusing namespace libbitcoin;\n\nstatic inline bool is_base64(byte c)\n{\n    return (isalnum(c) || (c == '+') || (c == '/'));\n}\n\nstatic inline byte find_base64_char_index(byte c)\n{\n    if ('A' <= c && c <= 'Z')\n        return c - 'A';\n    else if ('a' <= c && c <= 'z')\n        return c - 'a' + 1 + find_base64_char_index('Z');\n    else if ('0' <= c && c <= '9')\n        return c - '0' + 1 + find_base64_char_index('z');\n    else if (c == '+')\n        return 1 + find_base64_char_index('9');\n    else if (c == '/')\n        return 1 + find_base64_char_index('+');\n    else\n        return 1 + find_base64_char_index('/');\n}\n\nstring libbitcoin::toBase64(bytesConstRef _in)\n{\n    static const char base64_chars[] =\n        \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n        \"abcdefghijklmnopqrstuvwxyz\"\n        \"0123456789+/\";\n\n    string ret;\n    int i = 0;\n    int j = 0;\n    byte char_array_3[3];\n    byte char_array_4[4];\n\n    auto buf = _in.data();\n    auto bufLen = _in.size();\n\n    while (bufLen--)\n    {\n        char_array_3[i++] = *(buf++);\n        if (i == 3)\n        {\n            char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;\n            char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);\n            char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);\n            char_array_4[3] = char_array_3[2] & 0x3f;\n\n            for (i = 0; i < 4; i++)\n                ret += base64_chars[char_array_4[i]];\n            i = 0;\n        }\n    }\n\n    if (i)\n    {\n        for (j = i; j < 3; j++)\n            char_array_3[j] = '\\0';\n\n        char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;\n        char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);\n        char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);\n        char_array_4[3] = char_array_3[2] & 0x3f;\n\n        for (j = 0; j < i + 1; j++)\n            ret += base64_chars[char_array_4[j]];\n\n        while (i++ < 3)\n            ret += '=';\n    }\n\n    return ret;\n}\n\nbytes libbitcoin::fromBase64(string const &encoded_string)\n{\n    auto in_len = encoded_string.size();\n    int i = 0;\n    int j = 0;\n    int in_ = 0;\n    byte char_array_3[3];\n    byte char_array_4[4];\n    bytes ret;\n\n    while (in_len-- && encoded_string[in_] != '=' && is_base64(encoded_string[in_]))\n    {\n        char_array_4[i++] = encoded_string[in_];\n        in_++;\n        if (i == 4)\n        {\n            for (i = 0; i < 4; i++)\n                char_array_4[i] = find_base64_char_index(char_array_4[i]);\n\n            char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);\n            char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);\n            char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];\n\n            for (i = 0; (i < 3); i++)\n                ret.push_back(char_array_3[i]);\n            i = 0;\n        }\n    }\n\n    if (i)\n    {\n        for (j = i; j < 4; j++)\n            char_array_4[j] = 0;\n\n        for (j = 0; j < 4; j++)\n            char_array_4[j] = find_base64_char_index(char_array_4[j]);\n\n        char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);\n        char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);\n        char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];\n\n        for (j = 0; j < i - 1; j++)\n            ret.push_back(char_array_3[j]);\n    }\n\n    return ret;\n}\n"
  },
  {
    "path": "src/UChainService/consensus/common/libdevcore/Common.cpp",
    "content": "/*\n    This file is part of cpp-ethereum.\n\n    cpp-ethereum is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    cpp-ethereum is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/** @file Common.cpp\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n */\n\n#include <UChainService/consensus/libdevcore/Common.h>\n#include <UChainService/consensus/libdevcore/Exceptions.h>\n#include <UChainService/consensus/libdevcore/Log.h>\n#include <UChainService/consensus/libdevcore/BuildInfo.h>\nusing namespace std;\nusing namespace libbitcoin;\n\nnamespace libbitcoin\n{\n\nchar const *Version = ETH_PROJECT_VERSION;\n\nconst u256 Invalid256 = ~(u256)0;\n\nvoid InvariantChecker::checkInvariants(HasInvariants const *_this, char const *_fn, char const *_file, int _line, bool _pre)\n{\n    if (!_this->invariants())\n    {\n        cwarn << (_pre ? \"Pre\" : \"Post\") << \"invariant failed in\" << _fn << \"at\" << _file << \":\" << _line;\n        ::boost::exception_detail::throw_exception_(FailedInvariant(), _fn, _file, _line);\n    }\n}\n\nstruct TimerChannel : public LogChannel\n{\n    static const char *name();\n    static const int verbosity = 0;\n};\n\n#if defined(_WIN32)\nconst char *TimerChannel::name()\n{\n    return EthRed \" ! \";\n}\n#else\nconst char *TimerChannel::name()\n{\n    return EthRed \" ⚡ \";\n}\n#endif\n\nTimerHelper::~TimerHelper()\n{\n    auto e = std::chrono::high_resolution_clock::now() - m_t;\n    if (!m_ms || e > chrono::milliseconds(m_ms))\n        clog(TimerChannel) << m_id << chrono::duration_cast<chrono::milliseconds>(e).count() << \"ms\";\n}\n\nuint64_t utcTime()\n{\n    // TODO: Fix if possible to not use time(0) and merge only after testing in all platforms\n    // time_t t = time(0);\n    // return mktime(gmtime(&t));\n    return time(0);\n}\n\nstring inUnits(bigint const &_b, strings const &_units)\n{\n    ostringstream ret;\n    u256 b;\n    if (_b < 0)\n    {\n        ret << \"-\";\n        b = (u256)-_b;\n    }\n    else\n        b = (u256)_b;\n\n    u256 biggest = 1;\n    for (unsigned i = _units.size() - 1; !!i; --i)\n        biggest *= 1000;\n\n    if (b > biggest * 1000)\n    {\n        ret << (b / biggest) << \" \" << _units.back();\n        return ret.str();\n    }\n    ret << setprecision(3);\n\n    u256 unit = biggest;\n    for (auto it = _units.rbegin(); it != _units.rend(); ++it)\n    {\n        auto i = *it;\n        if (i != _units.front() && b >= unit)\n        {\n            ret << (double(b / (unit / 1000)) / 1000.0) << \" \" << i;\n            return ret.str();\n        }\n        else\n            unit /= 1000;\n    }\n    ret << b << \" \" << _units.front();\n    return ret.str();\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/consensus/common/libdevcore/CommonData.cpp",
    "content": "/*\n    This file is part of cpp-ethereum.\n\n    cpp-ethereum is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    cpp-ethereum is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/** @file CommonData.cpp\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n */\n\n//#include \"CommonData.h\"\n#include <UChainService/consensus/libdevcore/CommonData.h>\n#include <random>\n\n#if defined(_MSC_VER)\n#pragma warning(push)\n#pragma warning(disable : 4724) // potential mod by 0, line 78 of boost/random/uniform_int_distribution.hpp (boost 1.55)\n#endif\n#include <boost/random/uniform_int_distribution.hpp>\n#if defined(_MSC_VER)\n#pragma warning(pop)\n#endif\n//#include \"Exceptions.h\"\n//#include \"Log.h\"\n#include <UChainService/consensus/libdevcore/Exceptions.h>\n#include <UChainService/consensus/libdevcore/Log.h>\nusing namespace std;\nusing namespace libbitcoin;\n\nnamespace\n{\nint fromHexChar(char _i) noexcept\n{\n    if (_i >= '0' && _i <= '9')\n        return _i - '0';\n    if (_i >= 'a' && _i <= 'f')\n        return _i - 'a' + 10;\n    if (_i >= 'A' && _i <= 'F')\n        return _i - 'A' + 10;\n    return -1;\n}\n} // namespace\n\nbool libbitcoin::isHex(string const &_s) noexcept\n{\n    auto it = _s.begin();\n    if (_s.compare(0, 2, \"0x\") == 0)\n        it += 2;\n    return std::all_of(it, _s.end(), [](char c) { return fromHexChar(c) != -1; });\n}\n\nstd::string libbitcoin::escaped(std::string const &_s, bool _all)\n{\n    static const map<char, char> prettyEscapes{{'\\r', 'r'}, {'\\n', 'n'}, {'\\t', 't'}, {'\\v', 'v'}};\n    std::string ret;\n    ret.reserve(_s.size() + 2);\n    ret.push_back('\"');\n    for (auto i : _s)\n        if (i == '\"' && !_all)\n            ret += \"\\\\\\\"\";\n        else if (i == '\\\\' && !_all)\n            ret += \"\\\\\\\\\";\n        else if (prettyEscapes.count(i) && !_all)\n        {\n            ret += '\\\\';\n            ret += prettyEscapes.find(i)->second;\n        }\n        else if (i < ' ' || _all)\n        {\n            ret += \"\\\\x\";\n            ret.push_back(\"0123456789abcdef\"[(uint8_t)i / 16]);\n            ret.push_back(\"0123456789abcdef\"[(uint8_t)i % 16]);\n        }\n        else\n            ret.push_back(i);\n    ret.push_back('\"');\n    return ret;\n}\n\nstd::string libbitcoin::randomWord()\n{\n    static std::mt19937_64 s_eng(0);\n    std::string ret(boost::random::uniform_int_distribution<int>(1, 5)(s_eng), ' ');\n    char const n[] = \"qwertyuiop\"; //asdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890\";\n    boost::random::uniform_int_distribution<int> d(0, sizeof(n) - 2);\n    for (char &c : ret)\n        c = n[d(s_eng)];\n    return ret;\n}\n\nbytes libbitcoin::fromHex(std::string const &_s, WhenError _throw)\n{\n    unsigned s = (_s.size() >= 2 && _s[0] == '0' && _s[1] == 'x') ? 2 : 0;\n    std::vector<uint8_t> ret;\n    ret.reserve((_s.size() - s + 1) / 2);\n\n    if (_s.size() % 2)\n    {\n        int h = fromHexChar(_s[s++]);\n        if (h != -1)\n            ret.push_back(h);\n        else if (_throw == WhenError::Throw)\n            BOOST_THROW_EXCEPTION(BadHexCharacter());\n        else\n            return bytes();\n    }\n    for (unsigned i = s; i < _s.size(); i += 2)\n    {\n        int h = fromHexChar(_s[i]);\n        int l = fromHexChar(_s[i + 1]);\n        if (h != -1 && l != -1)\n            ret.push_back((byte)(h * 16 + l));\n        else if (_throw == WhenError::Throw)\n            BOOST_THROW_EXCEPTION(BadHexCharacter());\n        else\n            return bytes();\n    }\n    return ret;\n}\n\nbytes libbitcoin::asNibbles(bytesConstRef const &_s)\n{\n    std::vector<uint8_t> ret;\n    ret.reserve(_s.size() * 2);\n    for (auto i : _s)\n    {\n        ret.push_back(i / 16);\n        ret.push_back(i % 16);\n    }\n    return ret;\n}\n\nstd::string libbitcoin::toString(string32 const &_s)\n{\n    std::string ret;\n    for (unsigned i = 0; i < 32 && _s[i]; ++i)\n        ret.push_back(_s[i]);\n    return ret;\n}\n"
  },
  {
    "path": "src/UChainService/consensus/common/libdevcore/CommonIO.cpp",
    "content": "/*\n    This file is part of cpp-ethereum.\n\n    cpp-ethereum is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    cpp-ethereum is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/** @file CommonIO.cpp\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n */\n\n#include <UChainService/consensus/libdevcore/CommonIO.h>\n#include <iostream>\n#include <cstdlib>\n#include <fstream>\n#include <stdio.h>\n#if defined(_WIN32)\n#include <windows.h>\n#else\n#include <termios.h>\n#endif\n#include <boost/filesystem.hpp>\n#include <UChainService/consensus/libdevcore/Exceptions.h>\nusing namespace std;\nusing namespace libbitcoin;\n\nstring libbitcoin::memDump(bytes const &_bytes, unsigned _width, bool _html)\n{\n    stringstream ret;\n    if (_html)\n        ret << \"<pre style=\\\"font-family: Monospace,Lucida Console,Courier,Courier New,sans-serif; font-size: small\\\">\";\n    for (unsigned i = 0; i < _bytes.size(); i += _width)\n    {\n        ret << hex << setw(4) << setfill('0') << i << \" \";\n        for (unsigned j = i; j < i + _width; ++j)\n            if (j < _bytes.size())\n                if (_bytes[j] >= 32 && _bytes[j] < 127)\n                    if ((char)_bytes[j] == '<' && _html)\n                        ret << \"&lt;\";\n                    else if ((char)_bytes[j] == '&' && _html)\n                        ret << \"&amp;\";\n                    else\n                        ret << (char)_bytes[j];\n                else\n                    ret << '?';\n            else\n                ret << ' ';\n        ret << \" \";\n        for (unsigned j = i; j < i + _width && j < _bytes.size(); ++j)\n            ret << setfill('0') << setw(2) << hex << (unsigned)_bytes[j] << \" \";\n        ret << \"\\n\";\n    }\n    if (_html)\n        ret << \"</pre>\";\n    return ret.str();\n}\n\ntemplate <typename _T>\ninline _T contentsGeneric(std::string const &_file)\n{\n    _T ret;\n    size_t const c_elementSize = sizeof(typename _T::value_type);\n    std::ifstream is(_file, std::ifstream::binary);\n    if (!is)\n        return ret;\n\n    // get length of file:\n    is.seekg(0, is.end);\n    streamoff length = is.tellg();\n    if (length == 0)\n        return ret; // do not read empty file (MSVC does not like it)\n    is.seekg(0, is.beg);\n\n    ret.resize((length + c_elementSize - 1) / c_elementSize);\n    is.read(const_cast<char *>(reinterpret_cast<char const *>(ret.data())), length);\n    return ret;\n}\n\nbytes libbitcoin::contents(string const &_file)\n{\n    return contentsGeneric<bytes>(_file);\n}\n\nbytesSec libbitcoin::contentsSec(string const &_file)\n{\n    bytes b = contentsGeneric<bytes>(_file);\n    bytesSec ret(b);\n    bytesRef(&b).cleanse();\n    return ret;\n}\n\nstring libbitcoin::contentsString(string const &_file)\n{\n    return contentsGeneric<string>(_file);\n}\n\nvoid libbitcoin::writeFile(std::string const &_file, bytesConstRef _data, bool _writeDeleteRename)\n{\n    namespace fs = boost::filesystem;\n    if (_writeDeleteRename)\n    {\n        fs::path tempPath = fs::unique_path(_file + \"-%%%%%%\");\n        writeFile(tempPath.string(), _data, false);\n        // will delete _file if it exists\n        fs::rename(tempPath, _file);\n    }\n    else\n    {\n        // create directory if not existent\n        fs::path p(_file);\n        if (!fs::exists(p.parent_path()))\n        {\n            fs::create_directories(p.parent_path());\n            DEV_IGNORE_EXCEPTIONS(fs::permissions(p.parent_path(), fs::owner_all));\n        }\n\n        ofstream s(_file, ios::trunc | ios::binary);\n        s.write(reinterpret_cast<char const *>(_data.data()), _data.size());\n        if (!s)\n            BOOST_THROW_EXCEPTION(FileError() << errinfo_comment(\"Could not write to file: \" + _file));\n        DEV_IGNORE_EXCEPTIONS(fs::permissions(_file, fs::owner_read | fs::owner_write));\n    }\n}\n\nstd::string libbitcoin::getPassword(std::string const &_prompt)\n{\n#if defined(_WIN32)\n    cout << _prompt << flush;\n    // Get current Console input flags\n    HANDLE hStdin;\n    DWORD fdwSaveOldMode;\n    if ((hStdin = GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE)\n        BOOST_THROW_EXCEPTION(ExternalFunctionFailure(\"GetStdHandle\"));\n    if (!GetConsoleMode(hStdin, &fdwSaveOldMode))\n        BOOST_THROW_EXCEPTION(ExternalFunctionFailure(\"GetConsoleMode\"));\n    // Set console flags to no echo\n    if (!SetConsoleMode(hStdin, fdwSaveOldMode & (~ENABLE_ECHO_INPUT)))\n        BOOST_THROW_EXCEPTION(ExternalFunctionFailure(\"SetConsoleMode\"));\n    // Read the string\n    std::string ret;\n    std::getline(cin, ret);\n    // Restore old input mode\n    if (!SetConsoleMode(hStdin, fdwSaveOldMode))\n        BOOST_THROW_EXCEPTION(ExternalFunctionFailure(\"SetConsoleMode\"));\n    return ret;\n#else\n    struct termios oflags;\n    struct termios nflags;\n    char password[256];\n\n    // disable echo in the terminal\n    tcgetattr(fileno(stdin), &oflags);\n    nflags = oflags;\n    nflags.c_lflag &= ~ECHO;\n    nflags.c_lflag |= ECHONL;\n\n    if (tcsetattr(fileno(stdin), TCSANOW, &nflags) != 0)\n        BOOST_THROW_EXCEPTION(ExternalFunctionFailure(\"tcsetattr\"));\n\n    printf(\"%s\", _prompt.c_str());\n    if (!fgets(password, sizeof(password), stdin))\n        BOOST_THROW_EXCEPTION(ExternalFunctionFailure(\"fgets\"));\n    password[strlen(password) - 1] = 0;\n\n    // restore terminal\n    if (tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0)\n        BOOST_THROW_EXCEPTION(ExternalFunctionFailure(\"tcsetattr\"));\n\n    return password;\n#endif\n}\n"
  },
  {
    "path": "src/UChainService/consensus/common/libdevcore/FixedHash.cpp",
    "content": "/*\n    This file is part of cpp-ethereum.\n\n    cpp-ethereum is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    cpp-ethereum is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/** @file FixedHash.cpp\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n */\n\n#include <UChainService/consensus/libdevcore/FixedHash.h>\n#include <ctime>\n#include <boost/algorithm/string.hpp>\nusing namespace std;\nusing namespace libbitcoin;\n#ifdef __MINGW32__\nboost::random_device libbitcoin::s_fixedHashEngine;\n#else\nstd::random_device libbitcoin::s_fixedHashEngine;\n#endif\n\nh128 libbitcoin::fromUUID(std::string const &_uuid)\n{\n    try\n    {\n        return h128(boost::replace_all_copy(_uuid, \"-\", \"\"));\n    }\n    catch (...)\n    {\n        return h128();\n    }\n}\n\nstd::string libbitcoin::toUUID(h128 const &_uuid)\n{\n    std::string ret = toHex(_uuid.ref());\n    for (unsigned i : {20, 16, 12, 8})\n        ret.insert(ret.begin() + i, '-');\n    return ret;\n}\n"
  },
  {
    "path": "src/UChainService/consensus/common/libdevcore/Guards.cpp",
    "content": "/*\n    This file is part of cpp-ethereum.\n\n    cpp-ethereum is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    cpp-ethereum is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/** @file Guards.cpp\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n */\n\n#include <UChainService/consensus/libdevcore/Guards.h>\nusing namespace std;\nusing namespace libbitcoin;\n\nnamespace dev\n{\n}\n"
  },
  {
    "path": "src/UChainService/consensus/common/libdevcore/Log.cpp",
    "content": "/*\n    This file is part of cpp-ethereum.\n\n    cpp-ethereum is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    cpp-ethereum is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/** @file Log.cpp\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n */\n\n#include <UChainService/consensus/libdevcore/Log.h>\n\n#include <string>\n#include <iostream>\n#include <thread>\n#ifdef __APPLE__\n#include <pthread.h>\n#endif\n#if !defined(ETH_EMSCRIPTEN)\n#include <boost/asio/ip/tcp.hpp>\n#endif\n#include <UChainService/consensus/libdevcore/Guards.h>\nusing namespace std;\nusing namespace libbitcoin;\n\n//⊳⊲◀▶■▣▢□▷◁▧▨▩▲◆◉◈◇◎●◍◌○◼☑☒☎☢☣☰☀♽♥♠✩✭❓✔✓✖✕✘✓✔✅⚒⚡⦸⬌∅⁕«««»»»⚙\n\n// Logging\nint libbitcoin::g_logVerbosity = 5;\nmutex x_logOverride;\n\n/// Map of Log Channel types to bool, false forces the channel to be disabled, true forces it to be enabled.\n/// If a channel has no entry, then it will output as long as its verbosity (LogChannel::verbosity) is less than\n/// or equal to the currently output verbosity (g_logVerbosity).\nstatic map<type_info const *, bool> s_logOverride;\n\nbool libbitcoin::isChannelVisible(std::type_info const *_ch, bool _default)\n{\n    Guard l(x_logOverride);\n    if (s_logOverride.count(_ch))\n        return s_logOverride[_ch];\n    return _default;\n}\n\nLogOverrideAux::LogOverrideAux(std::type_info const *_ch, bool _value) : m_ch(_ch)\n{\n    Guard l(x_logOverride);\n    m_old = s_logOverride.count(_ch) ? (int)s_logOverride[_ch] : c_null;\n    s_logOverride[m_ch] = _value;\n}\n\nLogOverrideAux::~LogOverrideAux()\n{\n    Guard l(x_logOverride);\n    if (m_old == c_null)\n        s_logOverride.erase(m_ch);\n    else\n        s_logOverride[m_ch] = (bool)m_old;\n}\n\n#if defined(_WIN32)\nconst char *LogChannel::name()\n{\n    return EthGray \"...\";\n}\nconst char *LeftChannel::name() { return EthNavy \"<--\"; }\nconst char *RightChannel::name() { return EthGreen \"-->\"; }\nconst char *WarnChannel::name() { return EthOnRed EthBlackBold \"  X\"; }\nconst char *NoteChannel::name() { return EthBlue \"  i\"; }\nconst char *DebugChannel::name() { return EthWhite \"  D\"; }\nconst char *TraceChannel::name() { return EthGray \"...\"; }\n#else\nconst char *LogChannel::name()\n{\n    return EthGray \"···\";\n}\nconst char *LeftChannel::name() { return EthNavy \"◀▬▬\"; }\nconst char *RightChannel::name() { return EthGreen \"▬▬▶\"; }\nconst char *WarnChannel::name() { return EthOnRed EthBlackBold \"  ✘\"; }\nconst char *NoteChannel::name() { return EthBlue \"  ℹ\"; }\nconst char *DebugChannel::name() { return EthWhite \"  ◇\"; }\nconst char *TraceChannel::name() { return EthGray \"...\"; }\n#endif\n\nLogOutputStreamBase::LogOutputStreamBase(char const *_id, std::type_info const *_info, unsigned _v, bool _autospacing) : m_autospacing(_autospacing),\n                                                                                                                         m_verbosity(_v)\n{\n    Guard l(x_logOverride);\n    auto it = s_logOverride.find(_info);\n    if ((it != s_logOverride.end() && it->second == true) || (it == s_logOverride.end() && (int)_v <= g_logVerbosity))\n    {\n        time_t rawTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());\n        unsigned ms = chrono::duration_cast<chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count() % 1000;\n        char buf[24];\n        if (strftime(buf, 24, \"%X\", localtime(&rawTime)) == 0)\n            buf[0] = '\\0'; // empty if case strftime fails\n        static char const *c_begin = \"  \" EthViolet;\n        static char const *c_sep1 = EthReset EthBlack \"|\" EthNavy;\n        static char const *c_sep2 = EthReset EthBlack \"|\" EthTeal;\n        static char const *c_end = EthReset \"  \";\n        m_sstr << _id << c_begin << buf << \".\" << setw(3) << setfill('0') << ms;\n        m_sstr << c_sep1 << getThreadName() << ThreadContext::join(c_sep2) << c_end;\n    }\n}\n\n#if !defined(ETH_EMSCRIPTEN)\nvoid LogOutputStreamBase::append(boost::asio::ip::basic_endpoint<boost::asio::ip::tcp> const &_t)\n{\n    m_sstr << EthNavyUnder \"tcp://\" << _t << EthReset;\n}\n#endif\n\n/// Associate a name with each thread for nice logging.\nstruct ThreadLocalLogName\n{\n    ThreadLocalLogName(std::string const &_name) { m_name.reset(new string(_name)); }\n    boost::thread_specific_ptr<std::string> m_name;\n};\n\n/// Associate a name with each thread for nice logging.\nstruct ThreadLocalLogContext\n{\n    ThreadLocalLogContext() = default;\n\n    void push(std::string const &_name)\n    {\n        if (!m_contexts.get())\n            m_contexts.reset(new vector<string>);\n        m_contexts->push_back(_name);\n    }\n\n    void pop()\n    {\n        m_contexts->pop_back();\n    }\n\n    string join(string const &_prior)\n    {\n        string ret;\n        if (m_contexts.get())\n            for (auto const &i : *m_contexts)\n                ret += _prior + i;\n        return ret;\n    }\n\n    boost::thread_specific_ptr<std::vector<std::string>> m_contexts;\n};\n\nThreadLocalLogContext g_logThreadContext;\n\nThreadLocalLogName g_logThreadName(\"main\");\n\nvoid libbitcoin::ThreadContext::push(string const &_n)\n{\n    g_logThreadContext.push(_n);\n}\n\nvoid libbitcoin::ThreadContext::pop()\n{\n    g_logThreadContext.pop();\n}\n\nstring libbitcoin::ThreadContext::join(string const &_prior)\n{\n    return g_logThreadContext.join(_prior);\n}\n\n// foward declare without all of Windows.h\n#if defined(_WIN32)\nextern \"C\" __declspec(dllimport) void __stdcall OutputDebugStringA(const char *lpOutputString);\n#endif\n\nstring libbitcoin::getThreadName()\n{\n#if defined(__GLIBC__) || defined(__APPLE__)\n    char buffer[128];\n    pthread_getname_np(pthread_self(), buffer, 127);\n    buffer[127] = 0;\n    return buffer;\n#else\n    return g_logThreadName.m_name.get() ? *g_logThreadName.m_name.get() : \"<unknown>\";\n#endif\n}\n\nvoid libbitcoin::setThreadName(string const &_n)\n{\n#if defined(__GLIBC__)\n    pthread_setname_np(pthread_self(), _n.c_str());\n#elif defined(__APPLE__)\n    pthread_setname_np(_n.c_str());\n#else\n    g_logThreadName.m_name.reset(new std::string(_n));\n#endif\n}\n\nvoid libbitcoin::simpleDebugOut(std::string const &_s, char const *)\n{\n    static SpinLock s_lock;\n    SpinGuard l(s_lock);\n\n    cerr << _s << endl\n         << flush;\n\n// helpful to use OutputDebugString on windows\n#if defined(_WIN32)\n    {\n        OutputDebugStringA(_s.data());\n        OutputDebugStringA(\"\\n\");\n    }\n#endif\n}\n\nstd::function<void(std::string const &, char const *)> libbitcoin::g_logPost = simpleDebugOut;\n"
  },
  {
    "path": "src/UChainService/consensus/common/libdevcore/RLP.cpp",
    "content": "/*\n    This file is part of cpp-ethereum.\n\n    cpp-ethereum is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    cpp-ethereum is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/** @file RLP.cpp\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n */\n\n#include <UChainService/consensus/libdevcore/RLP.h>\nusing namespace std;\nusing namespace libbitcoin;\n\nbytes libbitcoin::RLPNull = rlp(\"\");\nbytes libbitcoin::RLPEmptyList = rlpList();\n\nRLP::RLP(bytesConstRef _d, Strictness _s) : m_data(_d)\n{\n    if ((_s & FailIfTooBig) && actualSize() < _d.size())\n    {\n        if (_s & ThrowOnFail)\n            BOOST_THROW_EXCEPTION(OversizeRLP());\n        else\n            m_data.reset();\n    }\n    if ((_s & FailIfTooSmall) && actualSize() > _d.size())\n    {\n        if (_s & ThrowOnFail)\n            BOOST_THROW_EXCEPTION(UndersizeRLP());\n        else\n            m_data.reset();\n    }\n}\n\nRLP::iterator &RLP::iterator::operator++()\n{\n    if (m_remaining)\n    {\n        m_currentItem.retarget(m_currentItem.next().data(), m_remaining);\n        m_currentItem = m_currentItem.cropped(0, sizeAsEncoded(m_currentItem));\n        m_remaining -= std::min<size_t>(m_remaining, m_currentItem.size());\n    }\n    else\n        m_currentItem.retarget(m_currentItem.next().data(), 0);\n    return *this;\n}\n\nRLP::iterator::iterator(RLP const &_parent, bool _begin)\n{\n    if (_begin && _parent.isList())\n    {\n        auto pl = _parent.payload();\n        m_currentItem = pl.cropped(0, sizeAsEncoded(pl));\n        m_remaining = pl.size() - m_currentItem.size();\n    }\n    else\n    {\n        m_currentItem = _parent.data().cropped(_parent.data().size());\n        m_remaining = 0;\n    }\n}\n\nRLP RLP::operator[](size_t _i) const\n{\n    if (_i < m_lastIndex)\n    {\n        m_lastEnd = sizeAsEncoded(payload());\n        m_lastItem = payload().cropped(0, m_lastEnd);\n        m_lastIndex = 0;\n    }\n    for (; m_lastIndex < _i && m_lastItem.size(); ++m_lastIndex)\n    {\n        m_lastItem = payload().cropped(m_lastEnd);\n        m_lastItem = m_lastItem.cropped(0, sizeAsEncoded(m_lastItem));\n        m_lastEnd += m_lastItem.size();\n    }\n    return RLP(m_lastItem, ThrowOnFail | FailIfTooSmall);\n}\n\nRLPs RLP::toList(int _flags) const\n{\n    RLPs ret;\n    if (!isList())\n    {\n        if (_flags & ThrowOnFail)\n            BOOST_THROW_EXCEPTION(BadCast());\n        else\n            return ret;\n    }\n    for (auto const &i : *this)\n        ret.push_back(i);\n    return ret;\n}\n\nsize_t RLP::actualSize() const\n{\n    if (isNull())\n        return 0;\n    if (isSingleByte())\n        return 1;\n    if (isData() || isList())\n        return payloadOffset() + length();\n    return 0;\n}\n\nvoid RLP::requireGood() const\n{\n    if (isNull())\n        BOOST_THROW_EXCEPTION(BadRLP());\n    byte n = m_data[0];\n    if (n != c_rlpDataImmLenStart + 1)\n        return;\n    if (m_data.size() < 2)\n        BOOST_THROW_EXCEPTION(BadRLP());\n    if (m_data[1] < c_rlpDataImmLenStart)\n        BOOST_THROW_EXCEPTION(BadRLP());\n}\n\nbool RLP::isInt() const\n{\n    if (isNull())\n        return false;\n    requireGood();\n    byte n = m_data[0];\n    if (n < c_rlpDataImmLenStart)\n        return !!n;\n    else if (n == c_rlpDataImmLenStart)\n        return true;\n    else if (n <= c_rlpDataIndLenZero)\n    {\n        if (m_data.size() <= 1)\n            BOOST_THROW_EXCEPTION(BadRLP());\n        return m_data[1] != 0;\n    }\n    else if (n < c_rlpListStart)\n    {\n        if (m_data.size() <= size_t(1 + n - c_rlpDataIndLenZero))\n            BOOST_THROW_EXCEPTION(BadRLP());\n        return m_data[1 + n - c_rlpDataIndLenZero] != 0;\n    }\n    else\n        return false;\n    return false;\n}\n\nsize_t RLP::length() const\n{\n    if (isNull())\n        return 0;\n    requireGood();\n    size_t ret = 0;\n    byte const n = m_data[0];\n    if (n < c_rlpDataImmLenStart)\n        return 1;\n    else if (n <= c_rlpDataIndLenZero)\n        return n - c_rlpDataImmLenStart;\n    else if (n < c_rlpListStart)\n    {\n        if (m_data.size() <= size_t(n - c_rlpDataIndLenZero))\n            BOOST_THROW_EXCEPTION(BadRLP());\n        if (m_data.size() > 1)\n            if (m_data[1] == 0)\n                BOOST_THROW_EXCEPTION(BadRLP());\n        unsigned lengthSize = n - c_rlpDataIndLenZero;\n        if (lengthSize > sizeof(ret))\n            // We did not check, but would most probably not fit in our memory.\n            BOOST_THROW_EXCEPTION(UndersizeRLP());\n        // No leading zeroes.\n        if (!m_data[1])\n            BOOST_THROW_EXCEPTION(BadRLP());\n        for (unsigned i = 0; i < lengthSize; ++i)\n            ret = (ret << 8) | m_data[i + 1];\n        // Must be greater than the limit.\n        if (ret < c_rlpListStart - c_rlpDataImmLenStart - c_rlpMaxLengthBytes)\n            BOOST_THROW_EXCEPTION(BadRLP());\n    }\n    else if (n <= c_rlpListIndLenZero)\n        return n - c_rlpListStart;\n    else\n    {\n        unsigned lengthSize = n - c_rlpListIndLenZero;\n        if (m_data.size() <= lengthSize)\n            BOOST_THROW_EXCEPTION(BadRLP());\n        if (m_data.size() > 1)\n            if (m_data[1] == 0)\n                BOOST_THROW_EXCEPTION(BadRLP());\n        if (lengthSize > sizeof(ret))\n            // We did not check, but would most probably not fit in our memory.\n            BOOST_THROW_EXCEPTION(UndersizeRLP());\n        if (!m_data[1])\n            BOOST_THROW_EXCEPTION(BadRLP());\n        for (unsigned i = 0; i < lengthSize; ++i)\n            ret = (ret << 8) | m_data[i + 1];\n        if (ret < 0x100 - c_rlpListStart - c_rlpMaxLengthBytes)\n            BOOST_THROW_EXCEPTION(BadRLP());\n    }\n    // We have to be able to add payloadOffset to length without overflow.\n    // This rejects roughly 4GB-sized RLPs on some platforms.\n    if (ret >= std::numeric_limits<size_t>::max() - 0x100)\n        BOOST_THROW_EXCEPTION(UndersizeRLP());\n    return ret;\n}\n\nsize_t RLP::items() const\n{\n    if (isList())\n    {\n        bytesConstRef d = payload();\n        size_t i = 0;\n        for (; d.size(); ++i)\n            d = d.cropped(sizeAsEncoded(d));\n        return i;\n    }\n    return 0;\n}\n\nRLPStream &RLPStream::appendRaw(bytesConstRef _s, size_t _itemCount)\n{\n    m_out.insert(m_out.end(), _s.begin(), _s.end());\n    noteAppended(_itemCount);\n    return *this;\n}\n\nvoid RLPStream::noteAppended(size_t _itemCount)\n{\n    if (!_itemCount)\n        return;\n    //    cdebug << \"noteAppended(\" << _itemCount << \")\";\n    while (m_listStack.size())\n    {\n        if (m_listStack.back().first < _itemCount)\n            BOOST_THROW_EXCEPTION(RLPException() << errinfo_comment(\"itemCount too large\") << RequirementError((bigint)m_listStack.back().first, (bigint)_itemCount));\n        m_listStack.back().first -= _itemCount;\n        if (m_listStack.back().first)\n            break;\n        else\n        {\n            auto p = m_listStack.back().second;\n            m_listStack.pop_back();\n            size_t s = m_out.size() - p; // list size\n            auto brs = bytesRequired(s);\n            unsigned encodeSize = s < c_rlpListImmLenCount ? 1 : (1 + brs);\n            //            cdebug << \"s: \" << s << \", p: \" << p << \", m_out.size(): \" << m_out.size() << \", encodeSize: \" << encodeSize << \" (br: \" << brs << \")\";\n            auto os = m_out.size();\n            m_out.resize(os + encodeSize);\n            memmove(m_out.data() + p + encodeSize, m_out.data() + p, os - p);\n            if (s < c_rlpListImmLenCount)\n                m_out[p] = (byte)(c_rlpListStart + s);\n            else if (c_rlpListIndLenZero + brs <= 0xff)\n            {\n                m_out[p] = (byte)(c_rlpListIndLenZero + brs);\n                byte *b = &(m_out[p + brs]);\n                for (; s; s >>= 8)\n                    *(b--) = (byte)s;\n            }\n            else\n                BOOST_THROW_EXCEPTION(RLPException() << errinfo_comment(\"itemCount too large for RLP\"));\n        }\n        _itemCount = 1; // for all following iterations, we've effectively appended a single item only since we completed a list.\n    }\n}\n\nRLPStream &RLPStream::appendList(size_t _items)\n{\n    //    cdebug << \"appendList(\" << _items << \")\";\n    if (_items)\n        m_listStack.push_back(std::make_pair(_items, m_out.size()));\n    else\n        appendList(bytes());\n    return *this;\n}\n\nRLPStream &RLPStream::appendList(bytesConstRef _rlp)\n{\n    if (_rlp.size() < c_rlpListImmLenCount)\n        m_out.push_back((byte)(_rlp.size() + c_rlpListStart));\n    else\n        pushCount(_rlp.size(), c_rlpListIndLenZero);\n    appendRaw(_rlp, 1);\n    return *this;\n}\n\nRLPStream &RLPStream::append(bytesConstRef _s, bool _compact)\n{\n    size_t s = _s.size();\n    byte const *d = _s.data();\n    if (_compact)\n        for (size_t i = 0; i < _s.size() && !*d; ++i, --s, ++d)\n        {\n        }\n\n    if (s == 1 && *d < c_rlpDataImmLenStart)\n        m_out.push_back(*d);\n    else\n    {\n        if (s < c_rlpDataImmLenCount)\n            m_out.push_back((byte)(s + c_rlpDataImmLenStart));\n        else\n            pushCount(s, c_rlpDataIndLenZero);\n        appendRaw(bytesConstRef(d, s), 0);\n    }\n    noteAppended();\n    return *this;\n}\n\nRLPStream &RLPStream::append(bigint _i)\n{\n    if (!_i)\n        m_out.push_back(c_rlpDataImmLenStart);\n    else if (_i < c_rlpDataImmLenStart)\n        m_out.push_back((byte)_i);\n    else\n    {\n        unsigned br = bytesRequired(_i);\n        if (br < c_rlpDataImmLenCount)\n            m_out.push_back((byte)(br + c_rlpDataImmLenStart));\n        else\n        {\n            auto brbr = bytesRequired(br);\n            if (c_rlpDataIndLenZero + brbr > 0xff)\n                BOOST_THROW_EXCEPTION(RLPException() << errinfo_comment(\"Number too large for RLP\"));\n            m_out.push_back((byte)(c_rlpDataIndLenZero + brbr));\n            pushInt(br, brbr);\n        }\n        pushInt(_i, br);\n    }\n    noteAppended();\n    return *this;\n}\n\nvoid RLPStream::pushCount(size_t _count, byte _base)\n{\n    auto br = bytesRequired(_count);\n    if (int(br) + _base > 0xff)\n        BOOST_THROW_EXCEPTION(RLPException() << errinfo_comment(\"Count too large for RLP\"));\n    m_out.push_back((byte)(br + _base)); // max 8 bytes.\n    pushInt(_count, br);\n}\n\nstatic void streamOut(std::ostream &_out, libbitcoin::RLP const &_d, unsigned _depth = 0)\n{\n    if (_depth > 64)\n        _out << \"<max-depth-reached>\";\n    else if (_d.isNull())\n        _out << \"null\";\n    else if (_d.isInt())\n        _out << std::showbase << std::hex << std::nouppercase << _d.toInt<bigint>(RLP::LaissezFaire) << dec;\n    else if (_d.isData())\n        _out << escaped(_d.toString(), false);\n    else if (_d.isList())\n    {\n        _out << \"[\";\n        int j = 0;\n        for (auto i : _d)\n        {\n            _out << (j++ ? \", \" : \" \");\n            streamOut(_out, i, _depth + 1);\n        }\n        _out << \" ]\";\n    }\n}\n\nstd::ostream &libbitcoin::operator<<(std::ostream &_out, RLP const &_d)\n{\n    streamOut(_out, _d);\n    return _out;\n}\n"
  },
  {
    "path": "src/UChainService/consensus/common/libdevcore/SHA3.cpp",
    "content": "/*\n    This file is part of cpp-ethereum.\n\n    cpp-ethereum is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    cpp-ethereum is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.\n*/\n/** @file SHA3.cpp\n * @author Gav Wood <i@gavwood.com>\n * @date 2014\n */\n\n#include <UChainService/consensus/libdevcore/SHA3.h>\n#include <cstdint>\n#include <cstdio>\n#include <cstdlib>\n#include <cstring>\n#include <UChainService/consensus/libdevcore/RLP.h>\n#include <UChainService/consensus/libdevcore/picosha2.h>\nusing namespace std;\nusing namespace libbitcoin;\n\nnamespace libbitcoin\n{\n\nh256 EmptySHA3 = sha3(bytesConstRef());\nh256 EmptyListSHA3 = sha3(rlpList());\n\nnamespace keccak\n{\n\n/** libkeccak-tiny\n *\n * A single-file implementation of SHA-3 and SHAKE.\n *\n * Implementor: David Leon Gil\n * License: CC0, attribution kindly requested. Blame taken too,\n * but not liability.\n */\n\n#define decshake(bits) \\\n  int shake##bits(uint8_t *, size_t, const uint8_t *, size_t);\n\n#define decsha3(bits) \\\n  int sha3_##bits(uint8_t *, size_t, const uint8_t *, size_t);\n\ndecshake(128)\n    decshake(256)\n        decsha3(224)\n            decsha3(256)\n                decsha3(384)\n                    decsha3(512)\n\n    /******** The Keccak-f[1600] permutation ********/\n\n    /*** Constants. ***/\n    static const uint8_t rho[24] =\n        {1, 3, 6, 10, 15, 21,\n         28, 36, 45, 55, 2, 14,\n         27, 41, 56, 8, 25, 43,\n         62, 18, 39, 61, 20, 44};\nstatic const uint8_t pi[24] =\n    {10, 7, 11, 17, 18, 3,\n     5, 16, 8, 21, 24, 4,\n     15, 23, 19, 13, 12, 2,\n     20, 14, 22, 9, 6, 1};\nstatic const uint64_t RC[24] =\n    {1ULL, 0x8082ULL, 0x800000000000808aULL, 0x8000000080008000ULL,\n     0x808bULL, 0x80000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL,\n     0x8aULL, 0x88ULL, 0x80008009ULL, 0x8000000aULL,\n     0x8000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL,\n     0x8000000000008002ULL, 0x8000000000000080ULL, 0x800aULL, 0x800000008000000aULL,\n     0x8000000080008081ULL, 0x8000000000008080ULL, 0x80000001ULL, 0x8000000080008008ULL};\n\n/*** Helper macros to unroll the permutation. ***/\n#define rol(x, s) (((x) << s) | ((x) >> (64 - s)))\n#define REPEAT6(e) e e e e e e\n#define REPEAT24(e) REPEAT6(e e e e)\n#define REPEAT5(e) e e e e e\n#define FOR5(v, s, e) \\\n  v = 0;              \\\n  REPEAT5(e; v += s;)\n\n/*** Keccak-f[1600] ***/\nstatic inline void keccakf(void *state)\n{\n  uint64_t *a = (uint64_t *)state;\n  uint64_t b[5] = {0};\n  uint64_t t = 0;\n  uint8_t x, y;\n\n  for (int i = 0; i < 24; i++)\n  {\n    // Theta\n    FOR5(x, 1,\n         b[x] = 0;\n         FOR5(y, 5,\n              b[x] ^= a[x + y];))\n    FOR5(x, 1,\n         FOR5(y, 5,\n              a[y + x] ^= b[(x + 4) % 5] ^ rol(b[(x + 1) % 5], 1);))\n    // Rho and pi\n    t = a[1];\n    x = 0;\n    REPEAT24(b[0] = a[pi[x]];\n             a[pi[x]] = rol(t, rho[x]);\n             t = b[0];\n             x++;)\n    // Chi\n    FOR5(y,\n         5,\n         FOR5(x, 1,\n              b[x] = a[y + x];)\n             FOR5(x, 1,\n                  a[y + x] = b[x] ^ ((~b[(x + 1) % 5]) & b[(x + 2) % 5]);))\n    // Iota\n    a[0] ^= RC[i];\n  }\n}\n\n/******** The FIPS202-defined functions. ********/\n\n/*** Some helper macros. ***/\n\n#define _(S) \\\n  do         \\\n  {          \\\n    S        \\\n  } while (0)\n#define FOR(i, ST, L, S) \\\n  _(for (size_t i = 0; i < L; i += ST) { S; })\n#define mkapply_ds(NAME, S)                   \\\n  static inline void NAME(uint8_t *dst,       \\\n                          const uint8_t *src, \\\n                          size_t len)         \\\n  {                                           \\\n    FOR(i, 1, len, S);                        \\\n  }\n#define mkapply_sd(NAME, S)                   \\\n  static inline void NAME(const uint8_t *src, \\\n                          uint8_t *dst,       \\\n                          size_t len)         \\\n  {                                           \\\n    FOR(i, 1, len, S);                        \\\n  }\n\nmkapply_ds(xorin, dst[i] ^= src[i])     // xorin\n    mkapply_sd(setout, dst[i] = src[i]) // setout\n\n#define P keccakf\n#define Plen 200\n\n// Fold P*F over the full blocks of an input.\n#define foldP(I, L, F) \\\n  while (L >= rate)    \\\n  {                    \\\n    F(a, I, rate);     \\\n    P(a);              \\\n    I += rate;         \\\n    L -= rate;         \\\n  }\n\n    /** The sponge-based hash construction. **/\n    static inline int hash(uint8_t *out, size_t outlen,\n                           const uint8_t *in, size_t inlen,\n                           size_t rate, uint8_t delim)\n{\n  if ((out == NULL) || ((in == NULL) && inlen != 0) || (rate >= Plen))\n  {\n    return -1;\n  }\n  uint8_t a[Plen] = {0};\n  // Absorb input.\n  foldP(in, inlen, xorin);\n  // Xor in the DS and pad frame.\n  a[inlen] ^= delim;\n  a[rate - 1] ^= 0x80;\n  // Xor in the last block.\n  xorin(a, in, inlen);\n  // Apply P\n  P(a);\n  // Squeeze output.\n  foldP(out, outlen, setout);\n  setout(a, out, outlen);\n  memset(a, 0, 200);\n  return 0;\n}\n\n/*** Helper macros to define SHA3 and SHAKE instances. ***/\n#define defshake(bits)                                           \\\n  int shake##bits(uint8_t *out, size_t outlen,                   \\\n                  const uint8_t *in, size_t inlen)               \\\n  {                                                              \\\n    return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x1f); \\\n  }\n#define defsha3(bits)                                            \\\n  int sha3_##bits(uint8_t *out, size_t outlen,                   \\\n                  const uint8_t *in, size_t inlen)               \\\n  {                                                              \\\n    if (outlen > (bits / 8))                                     \\\n    {                                                            \\\n      return -1;                                                 \\\n    }                                                            \\\n    return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x01); \\\n  }\n\n/*** FIPS202 SHAKE VOFs ***/\ndefshake(128)\n    defshake(256)\n\n    /*** FIPS202 SHA3 FOFs ***/\n    defsha3(224)\n        defsha3(256)\n            defsha3(384)\n                defsha3(512)\n\n} // namespace keccak\n\nunsigned g_sha3Counter = 0;\n\nbool sha3(bytesConstRef _input, bytesRef o_output)\n{\n  // FIXME: What with unaligned memory?\n  if (o_output.size() != 32)\n    return false;\n  ++g_sha3Counter;\n  keccak::sha3_256(o_output.data(), 32, _input.data(), _input.size());\n  //    keccak::keccak(ret.data(), 32, (uint64_t const*)_input.data(), _input.size());\n  return true;\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/consensus/common/libdevcore/cmake_install.cmake",
    "content": "# Install script for directory: /home/shikamaru/Project/uc/src/lib/consensus/common/libdevcore\n\n# Set the install prefix\nif(NOT DEFINED CMAKE_INSTALL_PREFIX)\n  set(CMAKE_INSTALL_PREFIX \"/usr/local\")\nendif()\nstring(REGEX REPLACE \"/$\" \"\" CMAKE_INSTALL_PREFIX \"${CMAKE_INSTALL_PREFIX}\")\n\n# Set the install configuration name.\nif(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)\n  if(BUILD_TYPE)\n    string(REGEX REPLACE \"^[^A-Za-z0-9_]+\" \"\"\n           CMAKE_INSTALL_CONFIG_NAME \"${BUILD_TYPE}\")\n  else()\n    set(CMAKE_INSTALL_CONFIG_NAME \"\")\n  endif()\n  message(STATUS \"Install configuration: \\\"${CMAKE_INSTALL_CONFIG_NAME}\\\"\")\nendif()\n\n# Set the component getting installed.\nif(NOT CMAKE_INSTALL_COMPONENT)\n  if(COMPONENT)\n    message(STATUS \"Install component: \\\"${COMPONENT}\\\"\")\n    set(CMAKE_INSTALL_COMPONENT \"${COMPONENT}\")\n  else()\n    set(CMAKE_INSTALL_COMPONENT)\n  endif()\nendif()\n\n# Install shared libraries without execute permission?\nif(NOT DEFINED CMAKE_INSTALL_SO_NO_EXE)\n  set(CMAKE_INSTALL_SO_NO_EXE \"1\")\nendif()\n\nif(NOT CMAKE_INSTALL_COMPONENT OR \"${CMAKE_INSTALL_COMPONENT}\" STREQUAL \"Unspecified\")\n  file(INSTALL DESTINATION \"${CMAKE_INSTALL_PREFIX}/lib\" TYPE STATIC_LIBRARY FILES \"/home/shikamaru/Project/uc/src/lib/consensus/common/libdevcore/libdevcore.a\")\nendif()\n\nif(CMAKE_INSTALL_COMPONENT)\n  set(CMAKE_INSTALL_MANIFEST \"install_manifest_${CMAKE_INSTALL_COMPONENT}.txt\")\nelse()\n  set(CMAKE_INSTALL_MANIFEST \"install_manifest.txt\")\nendif()\n\nstring(REPLACE \";\" \"\\n\" CMAKE_INSTALL_MANIFEST_CONTENT\n       \"${CMAKE_INSTALL_MANIFEST_FILES}\")\nfile(WRITE \"/home/shikamaru/Project/uc/src/lib/consensus/common/libdevcore/${CMAKE_INSTALL_MANIFEST}\"\n     \"${CMAKE_INSTALL_MANIFEST_CONTENT}\")\n"
  },
  {
    "path": "src/UChainService/consensus/consensus/consensus.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-consensus.\n *\n * UChain-consensus is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include \"UChainService/consensus.hpp\"\n#include \"UChainService/consensus/consensus.hpp\"\n\n#include <cstddef>\n#include <iostream>\n#include <stdexcept>\n#include <string.h>\n#include <UChainService/consensus/define.hpp>\n#include <UChainService/consensus/export.hpp>\n#include <UChainService/consensus/version.hpp>\n#include \"primitives/transaction.h\"\n#include \"pubkey.h\"\n#include \"script/interpreter.h\"\n#include \"script/script_error.h\"\n#include \"version.h\"\n\nnamespace libbitcoin\n{\nnamespace consensus\n{\n\n// Static initialization of libsecp256k1 initialization context.\nECCVerifyHandle TxInputStream::secp256k1_context_ = ECCVerifyHandle();\n\nTxInputStream::TxInputStream(const unsigned char *transaction,\n                             size_t transaction_size)\n    : source_(transaction), remaining_(transaction_size)\n{\n}\n\nTxInputStream &TxInputStream::read(char *destination, size_t size)\n{\n    if (size > remaining_)\n        throw std::ios_base::failure(\"end of data\");\n\n    memcpy(destination, source_, size);\n    remaining_ -= size;\n    source_ += size;\n    return *this;\n}\n\n// This mapping decouples the consensus API from the satoshi implementation\n// files. We prefer to keep our copies of consensus files isomorphic.\n// This function is not published (but non-static for testability).\nverify_result_type script_error_to_verify_result(ScriptError_t code)\n{\n    switch (code)\n    {\n    // Logical result\n    case SCRIPT_ERR_OK:\n        return verify_result_eval_true;\n    case SCRIPT_ERR_EVAL_FALSE:\n        return verify_result_eval_false;\n\n    // Max size errors\n    case SCRIPT_ERR_SCRIPT_SIZE:\n        return verify_result_script_size;\n    case SCRIPT_ERR_PUSH_SIZE:\n        return verify_result_push_size;\n    case SCRIPT_ERR_OP_COUNT:\n        return verify_result_op_count;\n    case SCRIPT_ERR_STACK_SIZE:\n        return verify_result_stack_size;\n    case SCRIPT_ERR_SIG_COUNT:\n        return verify_result_sig_count;\n    case SCRIPT_ERR_PUBKEY_COUNT:\n        return verify_result_pubkey_count;\n\n    // Failed verify operations\n    case SCRIPT_ERR_VERIFY:\n        return verify_result_verify;\n    case SCRIPT_ERR_EQUALVERIFY:\n        return verify_result_equalverify;\n    case SCRIPT_ERR_CHECKMULTISIGVERIFY:\n        return verify_result_checkmultisigverify;\n    case SCRIPT_ERR_CHECKSIGVERIFY:\n        return verify_result_checksigverify;\n    case SCRIPT_ERR_NUMEQUALVERIFY:\n        return verify_result_numequalverify;\n\n    // Logical/Format/Canonical errors\n    case SCRIPT_ERR_BAD_OPCODE:\n        return verify_result_bad_opcode;\n    case SCRIPT_ERR_DISABLED_OPCODE:\n        return verify_result_disabled_opcode;\n    case SCRIPT_ERR_INVALID_STACK_OPERATION:\n        return verify_result_invalid_stack_operation;\n    case SCRIPT_ERR_INVALID_ALTSTACK_OPERATION:\n        return verify_result_invalid_altstack_operation;\n    case SCRIPT_ERR_UNBALANCED_CONDITIONAL:\n        return verify_result_unbalanced_conditional;\n\n    // BIP65\n    case SCRIPT_ERR_NEGATIVE_LOCKTIME:\n        return verify_result_negative_locktime;\n    case SCRIPT_ERR_UNSATISFIED_LOCKTIME:\n        return verify_result_unsatisfied_locktime;\n\n    // BIP62\n    case SCRIPT_ERR_SIG_HASHTYPE:\n        return verify_result_sig_hashtype;\n    case SCRIPT_ERR_SIG_DER:\n        return verify_result_sig_der;\n    case SCRIPT_ERR_MINIMALDATA:\n        return verify_result_minimaldata;\n    case SCRIPT_ERR_SIG_PUSHONLY:\n        return verify_result_sig_pushonly;\n    case SCRIPT_ERR_SIG_HIGH_S:\n        return verify_result_sig_high_s;\n    case SCRIPT_ERR_SIG_NULLDUMMY:\n        return verify_result_sig_nulldummy;\n    case SCRIPT_ERR_PUBKEYTYPE:\n        return verify_result_pubkeytype;\n    case SCRIPT_ERR_CLEANSTACK:\n        return verify_result_cleanstack;\n\n    // Softfork safeness\n    case SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS:\n        return verify_result_discourage_upgradable_nops;\n\n    // Other\n    case SCRIPT_ERR_OP_RETURN:\n        return verify_result_op_return;\n    case SCRIPT_ERR_UNKNOWN_ERROR:\n    case SCRIPT_ERR_ERROR_COUNT:\n    default:\n        return verify_result_unknown_error;\n    }\n}\n\n// This mapping decouples the consensus API from the satoshi implementation\n// files. We prefer to keep our copies of consensus files isomorphic.\n// This function is not published (but non-static for testability).\nunsigned int verify_flags_to_script_flags(unsigned int flags)\n{\n    unsigned int script_flags = SCRIPT_VERIFY_NONE;\n\n    if ((flags & verify_flags_p2sh) != 0)\n        script_flags |= SCRIPT_VERIFY_P2SH;\n    if ((flags & verify_flags_strictenc) != 0)\n        script_flags |= SCRIPT_VERIFY_STRICTENC;\n    if ((flags & verify_flags_dersig) != 0)\n        script_flags |= SCRIPT_VERIFY_DERSIG;\n    if ((flags & verify_flags_low_s) != 0)\n        script_flags |= SCRIPT_VERIFY_LOW_S;\n    if ((flags & verify_flags_nulldummy) != 0)\n        script_flags |= SCRIPT_VERIFY_NULLDUMMY;\n    if ((flags & verify_flags_sigpushonly) != 0)\n        script_flags |= SCRIPT_VERIFY_SIGPUSHONLY;\n    if ((flags & verify_flags_minimaldata) != 0)\n        script_flags |= SCRIPT_VERIFY_MINIMALDATA;\n    if ((flags & verify_flags_discourage_upgradable_nops) != 0)\n        script_flags |= SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS;\n    if ((flags & verify_flags_cleanstack) != 0)\n        script_flags |= SCRIPT_VERIFY_CLEANSTACK;\n    if ((flags & verify_flags_checklocktimeverify) != 0)\n        script_flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;\n    if ((flags & verify_flags_checkattenuationverify) != 0)\n        script_flags |= SCRIPT_VERIFY_CHECKATTENUATIONVERIFY;\n\n    return script_flags;\n}\n\n// This function is published. The implementation exposes no satoshi internals.\nverify_result_type verify_script(const unsigned char *transaction,\n                                 size_t transaction_size, const unsigned char *prevout_script,\n                                 size_t prevout_script_size, unsigned int tx_input_index,\n                                 unsigned int flags)\n{\n    if (transaction_size > 0 && transaction == NULL)\n        throw std::invalid_argument(\"transaction\");\n\n    if (prevout_script_size > 0 && prevout_script == NULL)\n        throw std::invalid_argument(\"prevout_script\");\n\n    CTransaction tx;\n    try\n    {\n        TxInputStream stream(transaction, transaction_size);\n        Unserialize(stream, tx, SER_NETWORK, PROTOCOL_VERSION);\n    }\n    catch (const std::exception &e)\n    {\n        return verify_result_tx_invalid;\n    }\n\n    if (tx_input_index >= tx.vin.size())\n        return verify_result_tx_input_invalid;\n\n    if (tx.GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION) != transaction_size)\n        return verify_result_tx_size_invalid;\n\n    ScriptError_t error;\n    TransactionSignatureChecker checker(&tx, tx_input_index);\n    const unsigned int script_flags = verify_flags_to_script_flags(flags);\n    CScript output_script(prevout_script, prevout_script + prevout_script_size);\n    const CScript &input_script = tx.vin[tx_input_index].scriptSig;\n\n    // See libbitcoin-blockchain : validate.cpp :\n    // if (!output_script.run(input.script, current_tx, input_index, flags))...\n    VerifyScript(input_script, output_script, script_flags, checker, &error);\n\n    return script_error_to_verify_result(error);\n}\n\n} // namespace consensus\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/consensus/miner.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/consensus/miner.hpp>\n#include <UChain/blockchain/block_chain.hpp>\n#include <UChain/blockchain/block_chain_impl.hpp>\n#include <UChain/blockchain/validate_block.hpp>\n#include <UChain/node/p2p_node.hpp>\n\n#include <algorithm>\n#include <functional>\n#include <system_error>\n#include <boost/thread.hpp>\n//#include <UChainService/consensus/miner/MinerAux.h>\n//#include <UChainService/consensus/libdevcore/BasicType.h>\n#include <UChain/coin/chain/script/operation.hpp>\n#include <UChain/coin/config/hash160.hpp>\n#include <UChain/coin/wallet/ec_public.hpp>\n#include <UChain/coin/constants.hpp>\n#include <UChain/blockchain/validate_block.hpp>\n#include <UChain/blockchain/validate_tx_engine.hpp>\n#include <UChain/coin/utility/time.hpp>\n#define LOG_HEADER \"consensus\"\nusing namespace std;\nusing namespace std::this_thread;\n\nnamespace libbitcoin\n{\nnamespace consensus\n{\n\nstatic BC_CONSTEXPR unsigned int min_tx_fee = 100000;\n\n// tuples: (priority, fee_per_kb, fee, transaction_ptr)\ntypedef boost::tuple<double, double, uint64_t, miner::transaction_ptr> transaction_priority;\n\nnamespace\n{\n// fee : per kb\nbool sort_by_fee_per_kb(const transaction_priority &a, const transaction_priority &b)\n{\n    if (a.get<1>() == b.get<1>())\n        return a.get<0>() < b.get<0>();\n    return a.get<1>() < b.get<1>();\n};\n\n// priority : coin age\nbool sort_by_priority(const transaction_priority &a, const transaction_priority &b)\n{\n    if (a.get<0>() == b.get<0>())\n        return a.get<1>() < b.get<1>();\n    return a.get<0>() < b.get<0>();\n};\n} // end of anonymous namespace\n\nminer::miner(p2p_node &node)\n    : node_(node), state_(state::init_), new_block_number_(0), new_block_limit_(0), createblockms_(0), setting_(node_.chain_impl().chain_settings())\n{\n    /*if (setting_.use_testnet_rules) {\n        bc::HeaderAux::set_as_testnet();\n    }*/\n    mine_candidate_list = {};\n    mine_address_list = {};\n}\n\nminer::~miner()\n{\n    stop();\n}\n\nbool miner::get_input_ucn(const transaction &tx, const std::vector<transaction_ptr> &transactions,\n                          uint64_t &total_inputs, previous_out_map_t &previous_out_map) const\n{\n    total_inputs = 0;\n    block_chain_impl &block_chain = node_.chain_impl();\n    for (auto &input : tx.inputs)\n    {\n        transaction prev_tx;\n        uint64_t prev_height = 0;\n        uint64_t input_value = 0;\n        if (block_chain.get_transaction(prev_tx, prev_height, input.previous_output.hash))\n        {\n            input_value = prev_tx.outputs[input.previous_output.index].value;\n            previous_out_map[input.previous_output] =\n                std::make_pair(prev_height, prev_tx.outputs[input.previous_output.index]);\n        }\n        else\n        {\n            const hash_digest &hash = input.previous_output.hash;\n            const auto found = [&hash](const transaction_ptr &entry) {\n                return entry->hash() == hash;\n            };\n            auto it = std::find_if(transactions.begin(), transactions.end(), found);\n            if (it != transactions.end())\n            {\n                input_value = (*it)->outputs[input.previous_output.index].value;\n                previous_out_map[input.previous_output] =\n                    std::make_pair(max_uint64, (*it)->outputs[input.previous_output.index]);\n            }\n            else\n            {\n#ifdef UC_DEBUG\n                log::debug(LOG_HEADER) << \"previous transaction not ready: \" << encode_hash(hash);\n#endif\n                return false;\n            }\n        }\n\n        total_inputs += input_value;\n    }\n\n    return true;\n}\n\nbool miner::get_transaction(std::vector<transaction_ptr> &transactions,\n                            previous_out_map_t &previous_out_map, tx_fee_map_t &tx_fee_map) const\n{\n    boost::mutex mutex;\n    mutex.lock();\n    auto f = [&transactions, &mutex](const error_code &code, const vector<transaction_ptr> &transactions_) -> void {\n        transactions = transactions_;\n        mutex.unlock();\n    };\n    node_.pool().fetch(f);\n\n    boost::unique_lock<boost::mutex> lock(mutex);\n\n    if (transactions.empty() == false)\n    {\n        set<hash_digest> sets;\n        for (auto i = transactions.begin(); i != transactions.end();)\n        {\n            auto &tx = **i;\n            auto hash = tx.hash();\n\n            uint64_t total_input_value = 0;\n            bool ready = get_input_ucn(tx, transactions, total_input_value, previous_out_map);\n            if (!ready)\n            {\n                // erase tx but not delete it from pool if parent tx is not ready\n                i = transactions.erase(i);\n                break;\n            }\n\n            uint64_t total_output_value = tx.total_output_value();\n            uint64_t fee = total_input_value - total_output_value;\n\n            // check fees\n            if (fee < min_tx_fee || !blockchain::validate_tx_engine::check_special_fees(setting_.use_testnet_rules, tx, fee))\n            {\n                i = transactions.erase(i);\n                // delete it from pool if not enough fee\n                node_.pool().delete_tx(hash);\n                break;\n            }\n\n            auto transaction_is_ok = true;\n            for (auto &output : tx.outputs)\n            {\n                if (tx.version >= transaction_version::check_output_script && output.script.pattern() == script_pattern::non_standard)\n                {\n#ifdef UC_DEBUG\n                    log::error(LOG_HEADER) << \"transaction output script error! tx:\" << tx.to_string(1);\n#endif\n                    node_.pool().delete_tx(hash);\n                    transaction_is_ok = false;\n                    break;\n                }\n            }\n\n            if (transaction_is_ok && (sets.find(hash) == sets.end()))\n            {\n                tx_fee_map[hash] = fee;\n                sets.insert(hash);\n                ++i;\n            }\n            else\n            {\n                i = transactions.erase(i);\n            }\n        }\n    }\n    return transactions.empty() == false;\n}\n\nbool miner::script_hash_signature_operations_count(size_t &count, const chain::input &input, vector<transaction_ptr> &transactions)\n{\n    const auto &previous_output = input.previous_output;\n    transaction previous_tx;\n    boost::uint64_t h;\n    if (node_.chain_impl().get_transaction(previous_tx, h, previous_output.hash) == false)\n    {\n        bool found = false;\n        for (auto &tx : transactions)\n        {\n            if (previous_output.hash == tx->hash())\n            {\n                previous_tx = *tx;\n                found = true;\n                break;\n            }\n        }\n\n        if (found == false)\n            return false;\n    }\n\n    const auto &previous_tx_out = previous_tx.outputs[previous_output.index];\n    return blockchain::validate_block::script_hash_signature_operations_count(count, previous_tx_out.script, input.script);\n}\n\nbool miner::script_hash_signature_operations_count(\n    size_t &count, const chain::input::list &inputs, vector<transaction_ptr> &transactions)\n{\n    count = 0;\n    for (const auto &input : inputs)\n    {\n        size_t c = 0;\n        if (script_hash_signature_operations_count(c, input, transactions) == false)\n            return false;\n        count += c;\n    }\n    return true;\n}\n\n#define VALUE(a) (a < 'a' ? (a - '0') : (a - 'a' + 10))\nstd::string transfer_public_key(const string &key)\n{\n    string pub_key;\n    for (auto i = key.begin(); i != key.end(); i += 2)\n    {\n        unsigned char a = 0;\n        a = (VALUE(*i) << 4) + VALUE(*(i + 1));\n        pub_key.push_back(a);\n    }\n\n    return pub_key;\n}\n\nminer::block_ptr miner::create_genesis_block(bool is_mainnet)\n{\n    string text;\n    if (is_mainnet)\n    {\n        text = \"2018-02-14 00:00:00 UC start running mainnet.\";\n    }\n    else\n    {\n        text = \"2018-10-18 14:16:55 UC start running testnet.\";\n    }\n\n    block_ptr pblock = make_shared<block>();\n\n    // Create coinbase tx\n    transaction tx_new;\n    tx_new.inputs.resize(1);\n    tx_new.inputs[0].previous_output = {null_hash, max_uint32};\n    tx_new.inputs[0].script.operations = {{chain::opcode::raw_data, {text.begin(), text.end()}}};\n    tx_new.outputs.resize(1);\n\n    // init for testnet/mainnet\n    bc::wallet::payment_address genesis_address(get_foundation_address(!is_mainnet));\n    tx_new.outputs[0].script.operations = chain::operation::to_pay_key_hash_pattern(short_hash(genesis_address));\n    pblock->header.timestamp = 1550073600;\n\n    tx_new.outputs[0].value = total_reward * coin_price();\n\n    // Add our coinbase tx as first transaction\n    pblock->transactions.push_back(tx_new);\n\n    // Fill in header\n    pblock->header.previous_block_hash = null_hash;\n    pblock->header.merkle = pblock->generate_merkle_root(pblock->transactions);\n    pblock->header.transaction_count = 1;\n    pblock->header.version = 1;\n    /*pblock->header.bits = 1;\n    pblock->header.nonce = 0;*/\n    pblock->header.number = 0;\n    //pblock->header.mixhash = 0;\n\n    return pblock;\n}\n\nminer::transaction_ptr miner::create_coinbase_tx(\n    const bc::wallet::payment_address &pay_address, uint64_t value, uint64_t block_height)\n{\n    transaction_ptr ptransaction = make_shared<message::tx_message>();\n\n    //auto start =unix_millisecond();\n    const uint64_t unspent_token = fetch_utxo(ptransaction, pay_address);\n    //log::info(LOG_HEADER) << \"solo miner fetch_utxo for \" << unix_millisecond() - start << \" ms\";\n    if (!unspent_token)\n    {\n        ptransaction->version = version;\n        ptransaction->inputs.resize(1);\n        ptransaction->inputs[0].previous_output = {null_hash, max_uint32};\n        script_number number(block_height);\n        ptransaction->inputs[0].script.operations.push_back({chain::opcode::special, number.data()});\n    }\n    else\n    {\n        ptransaction->version = transaction_version::check_output_script;\n    }\n    ptransaction->locktime = 0;\n\n    ptransaction->outputs.resize(1);\n\n    ptransaction->outputs[0].script.operations = chain::operation::to_pay_key_hash_pattern(short_hash(pay_address));\n\n    auto transfer = chain::token_transfer(UC_BLOCK_TOKEN_SYMBOL, unspent_token + 1);\n    auto ass = token(TOKEN_TRANSFERABLE_TYPE, transfer);\n\n    ptransaction->outputs[0].value = 0; //1 block\n    ptransaction->outputs[0].attach_data = asset(UC_TOKEN_TYPE, 1, ass);\n\n    return ptransaction;\n}\n\nminer::transaction_ptr miner::create_lock_coinbase_tx(\n    const bc::wallet::payment_address &pay_address, uint64_t value,\n    uint64_t block_height, int lock_height, uint32_t reward_lock_time)\n{\n\n    if (!(lock_height > 0 && value > 0))\n    {\n        return nullptr;\n    }\n\n    transaction_ptr ptransaction = make_shared<message::tx_message>();\n\n    ptransaction->version = version;\n    ptransaction->inputs.resize(1);\n    ptransaction->inputs[0].previous_output = {null_hash, max_uint32};\n    script_number number(block_height);\n    ptransaction->inputs[0].script.operations.push_back({chain::opcode::special, number.data()});\n\n    ptransaction->outputs.resize(1);\n\n    ptransaction->locktime = reward_lock_time;\n\n    ptransaction->outputs[0].script.operations = chain::operation::to_pay_key_hash_with_lock_height_pattern(short_hash(pay_address), lock_height);\n\n    ptransaction->outputs[0].value = value;\n\n    return ptransaction;\n}\n\nuint64_t miner::fetch_utxo(const transaction_ptr &ptx, const bc::wallet::payment_address &address)\n{\n    block_chain_impl &block_chain = node_.chain_impl();\n    uint64_t height = 0, index = 0, unspent_ucn{0}, unspent_token{0};\n    block_chain.get_last_height(height);\n\n    auto fromheight = height > mine_fetch_utxo_height_windows ? height - mine_fetch_utxo_height_windows : 0;\n    auto &&rows = block_chain.get_address_history(address, true, fromheight);\n    if (!rows.size())\n    {\n        return false;\n    }\n\n    for (auto &row : rows)\n    {\n        chain::output output;\n        chain::input input;\n        if (!get_spendable_output(output, row, height))\n        {\n            continue;\n        }\n\n        if (output.get_script_address() != address.encoded())\n        {\n            continue;\n        }\n\n        auto token_symbol = output.get_token_symbol();\n\n        if (!(output.is_token_transfer() && token_symbol == UC_BLOCK_TOKEN_SYMBOL))\n        {\n            continue;\n        }\n\n        //auto ucn_amount = row.value;\n        auto token_total_amount = output.get_token_amount();\n        auto cert_type = output.get_token_cert_type();\n\n        //BITCOIN_ASSERT(ucn_amount == 0);\n        BITCOIN_ASSERT(cert_type == token_cert_ns::none);\n        if (token_total_amount == 0)\n            continue;\n\n        if (index && row.output.hash == ptx->inputs[index - 1].previous_output.hash && row.output.index == ptx->inputs[index - 1].previous_output.index)\n            continue;\n        input.previous_output = {row.output.hash, row.output.index};\n        //input.script = output.script;\n        input.sequence = max_input_sequence;\n        ptx->inputs.push_back(input);\n        //spend UTXO\n        bc::chain::script ss;\n        bc::explorer::config::hashtype sign_type;\n        uint8_t hash_type = (signature_hash_algorithm)sign_type;\n        bc::explorer::config::ec_private config_private_key(pri_key);\n        const ec_secret &private_key = config_private_key;\n\n        bc::explorer::config::script config_contract(output.script);\n        const bc::chain::script &contract = config_contract;\n\n        // gen sign\n        bc::endorsement endorse;\n        if (!bc::chain::script::create_endorsement(endorse, private_key,\n                                                   contract, *ptx, index, hash_type))\n        {\n            return false;\n        }\n\n        // do script\n        bc::wallet::ec_private ec_private_key(private_key, 0u, true);\n        auto &&public_key = ec_private_key.to_public();\n        data_chunk public_key_data;\n        public_key.to_data(public_key_data);\n\n        ss.operations.push_back({bc::chain::opcode::special, endorse});\n        ss.operations.push_back({bc::chain::opcode::special, public_key_data});\n\n        // if pre-output script is deposit tx.\n        if (contract.pattern() == bc::chain::script_pattern::pay_key_hash_with_lock_height)\n        {\n            uint64_t lock_height = chain::operation::get_lock_height_from_pay_key_hash_with_lock_height(\n                contract.operations);\n            ss.operations.push_back({bc::chain::opcode::special, script_number(lock_height).data()});\n        }\n        ptx->inputs[index++].script = ss;\n        // unspent_ucn += row.value;\n        unspent_token += output.get_token_amount();\n        break;\n    }\n    rows.clear();\n    return unspent_token;\n}\n\nbool miner::get_spendable_output(chain::output &output, const chain::history &row, uint64_t height)\n{\n    if (row.spend.hash != null_hash)\n    {\n        return false;\n    }\n\n    block_chain_impl &block_chain = node_.chain_impl();\n    chain::transaction tx_temp;\n    uint64_t tx_height;\n    if (!block_chain.get_transaction(row.output.hash, tx_temp, tx_height))\n    {\n        return false;\n    }\n\n    BITCOIN_ASSERT(row.output.index < tx_temp.outputs.size());\n    output = tx_temp.outputs.at(row.output.index);\n\n    if (chain::operation::is_pay_key_hash_with_lock_height_pattern(output.script.operations))\n    {\n        if (row.output_height == 0)\n        {\n            // deposit utxo in transaction pool\n            return false;\n        }\n        else\n        {\n            // deposit utxo in block\n            auto lock_height = chain::operation::\n                get_lock_height_from_pay_key_hash_with_lock_height(output.script.operations);\n            if ((row.output_height + lock_height) > height)\n            {\n                // utxo already in block but deposit not expire\n                return false;\n            }\n        }\n    }\n    else if (tx_temp.is_coinbase())\n    { // incase readd deposit\n        // coin base ucn maturity ucn check\n        // coinbase_maturity ucn check\n        if (row.output_height == 0 /*|| (row.output_height + coinbase_maturity) > height*/)\n        {\n            return false;\n        }\n    }\n\n    return true;\n}\n\n//int bucket_size = mine_block_produce_minsecons000;\nvector<uint64_t> lock_heights = {1728000, 7776000, 20736000, 41472000, 93312000};\nvector<uint64_t> coinage_rewards = {300000, 1990000, 5200000, 10000000, 24000000};\n\nint miner::get_lock_heights_index(uint64_t height)\n{\n    int ret = -1;\n    auto it = find(lock_heights.begin(), lock_heights.end(), height);\n    if (it != lock_heights.end())\n    {\n        ret = it - lock_heights.begin();\n    }\n    return ret;\n}\n\nuint64_t miner::calculate_block_subsidy(uint64_t block_height, bool is_testnet)\n{\n    return 0; //min_tx_fee;///uint64_t(3 * coin_price() * pow(0.95, block_height / bucket_size));\n}\n\nuint64_t miner::calculate_lockblock_reward(uint64_t lcok_heights, uint64_t num)\n{\n    int lock_heights_index = get_lock_heights_index(lcok_heights);\n    if (lock_heights_index >= 0)\n    {\n        double n = ((double)coinage_rewards[lock_heights_index]) / coin_price();\n        return (uint64_t)(n * num);\n    }\n    return 0;\n}\n\nstruct transaction_dependent\n{\n    std::shared_ptr<hash_digest> hash;\n    unsigned short dpendens;\n    bool is_need_process;\n    transaction_priority transaction;\n\n    transaction_dependent() : dpendens(0), is_need_process(false) {}\n    transaction_dependent(const hash_digest &_hash, unsigned short _dpendens, bool _is_need_process)\n        : dpendens(_dpendens), is_need_process(_is_need_process) { hash = make_shared<hash_digest>(_hash); }\n};\n\nminer::block_ptr miner::create_new_block(const bc::wallet::payment_address &pay_address, uint64_t current_block_height)\n{\n    block_ptr pblock;\n    vector<transaction_ptr> transactions;\n    map<hash_digest, transaction_dependent> transaction_dependents;\n    previous_out_map_t previous_out_map;\n    tx_fee_map_t tx_fee_map;\n    get_transaction(transactions, previous_out_map, tx_fee_map);\n\n    vector<transaction_priority> transaction_prioritys;\n    block_chain_impl &block_chain = node_.chain_impl();\n\n    header prev_header;\n    if (current_block_height == max_uint64)\n    {\n        if (!block_chain.get_last_height(current_block_height) || !block_chain.get_header(prev_header, current_block_height))\n        {\n            log::warning(LOG_HEADER) << \"get_last_height or get_header fail. current_block_height:\" << current_block_height;\n            return pblock;\n        }\n    }\n    else if (!block_chain.get_header(prev_header, current_block_height))\n    {\n        log::warning(LOG_HEADER) << \"get_last_height or get_header fail. current_block_height:\" << current_block_height;\n        return pblock;\n    }\n    else\n    {\n        pblock = make_shared<block>();\n    }\n\n    // Create coinbase tx\n    pblock->transactions.push_back(*create_coinbase_tx(pay_address, 0, current_block_height + 1));\n\n    // Largest block you're willing to create:\n    unsigned int block_max_size = blockchain::max_block_size / 2;\n    // Limit to betweeen 1K and max_block_size-1K for sanity:\n    block_max_size = max((unsigned int)1000, min((unsigned int)(blockchain::max_block_size - 1000), block_max_size));\n\n    // How much of the block should be dedicated to high-priority transactions,\n    // included regardless of the fees they pay\n    unsigned int block_priority_size = 27000;\n    block_priority_size = min(block_max_size, block_priority_size);\n\n    // Minimum block size you want to create; block will be filled with free transactions\n    // until there are no more or the block reaches this size:\n    unsigned int block_min_size = 0;\n    block_min_size = min(block_max_size, block_min_size);\n\n    uint64_t total_fee = 0;\n    unsigned int block_size = 0;\n    unsigned int total_tx_sig_length = blockchain::validate_block::validate_block::legacy_sigops_count(*pblock->transactions.begin());\n    for (auto tx : transactions)\n    {\n        auto tx_hash = tx->hash();\n        double priority = 0;\n        for (const auto &input : tx->inputs)\n        {\n            auto prev_pair = previous_out_map[input.previous_output];\n            uint64_t prev_height = prev_pair.first;\n            const auto &prev_output = prev_pair.second;\n\n            if (prev_height != max_uint64)\n            {\n                uint64_t input_value = prev_output.value;\n                priority += (double)input_value * (current_block_height - prev_height + 1);\n            }\n            else\n            {\n                transaction_dependents[input.previous_output.hash].hash = make_shared<hash_digest>(tx_hash);\n                transaction_dependents[tx_hash].dpendens++;\n            }\n        }\n\n        uint64_t serialized_size = tx->serialized_size(0);\n\n        // Priority is sum(valuein * age) / txsize\n        priority /= serialized_size;\n\n        // This is a more accurate fee-per-kilobyte than is used by the client code, because the\n        // client code rounds up the size to the nearest 1K. That's good, because it gives an\n        // incentive to create smaller transactions.\n        auto tx_fee = tx_fee_map[tx_hash];\n        double fee_per_kb = double(tx_fee) / (double(serialized_size) / 1000.0);\n        transaction_prioritys.push_back(transaction_priority(priority, fee_per_kb, tx_fee, tx));\n    }\n\n    vector<transaction_ptr> blocked_transactions;\n    auto sort_func = sort_by_fee_per_kb;\n    bool is_resort = false;\n    make_heap(transaction_prioritys.begin(), transaction_prioritys.end(), sort_func);\n\n    transaction_priority *next_transaction_priority = NULL;\n    uint32_t reward_lock_time = current_block_height - 1;\n    while (!transaction_prioritys.empty() || next_transaction_priority)\n    {\n        transaction_priority temp_priority;\n        if (next_transaction_priority)\n        {\n            temp_priority = *next_transaction_priority;\n        }\n        else\n        {\n            temp_priority = transaction_prioritys.front();\n        }\n\n        double priority = temp_priority.get<0>();\n        double fee_per_kb = temp_priority.get<1>();\n        uint64_t fee = temp_priority.get<2>();\n        transaction_ptr ptx = temp_priority.get<3>();\n\n        if (next_transaction_priority)\n        {\n            next_transaction_priority = NULL;\n        }\n        else\n        {\n            pop_heap(transaction_prioritys.begin(), transaction_prioritys.end(), sort_func);\n            transaction_prioritys.pop_back();\n        }\n\n        hash_digest h = ptx->hash();\n        if (transaction_dependents[h].dpendens != 0)\n        {\n            transaction_dependents[h].transaction = temp_priority;\n            transaction_dependents[h].is_need_process = true;\n            continue;\n        }\n\n        // Size limits\n        uint64_t serialized_size = ptx->serialized_size(1);\n        vector<transaction_ptr> coinage_reward_coinbases;\n        transaction_ptr coinage_reward_coinbase;\n        for (const auto &output : ptx->outputs)\n        {\n            if (chain::operation::is_pay_key_hash_with_lock_height_pattern(output.script.operations))\n            {\n                int lock_height = chain::operation::get_lock_height_from_pay_key_hash_with_lock_height(output.script.operations);\n                coinage_reward_coinbase = create_lock_coinbase_tx(ptx->has_candidate_register() ? bc::wallet::payment_address(bc::get_developer_community_address(block_chain.chain_settings().use_testnet_rules)) : bc::wallet::payment_address::extract(ptx->outputs[0].script),\n                                                                  calculate_lockblock_reward(lock_height, output.value),\n                                                                  current_block_height + 1, lock_height, reward_lock_time);\n\n                if (!coinage_reward_coinbase)\n                {\n                    continue;\n                }\n                unsigned int tx_sig_length = blockchain::validate_block::validate_block::legacy_sigops_count(*coinage_reward_coinbase);\n                if (total_tx_sig_length + tx_sig_length >= blockchain::max_block_script_sigops)\n                {\n                    continue;\n                }\n\n                total_tx_sig_length += tx_sig_length;\n                serialized_size += coinage_reward_coinbase->serialized_size(1);\n                coinage_reward_coinbases.push_back(coinage_reward_coinbase);\n                --reward_lock_time;\n            }\n        }\n\n        if (block_size + serialized_size >= block_max_size)\n            continue;\n\n        // Legacy limits on sigOps:\n        unsigned int tx_sig_length = blockchain::validate_block::validate_block::legacy_sigops_count(*ptx);\n        if (total_tx_sig_length + tx_sig_length >= blockchain::max_block_script_sigops)\n            continue;\n\n        // Skip free transactions if we're past the minimum block size:\n        if (is_resort && (fee_per_kb < min_tx_fee_per_kb) && (block_size + serialized_size >= block_min_size))\n            break;\n\n        // Prioritize by fee once past the priority size or we run out of high-priority\n        // transactions:\n        if (is_resort == false &&\n            ((block_size + serialized_size >= block_priority_size) || (priority < coin_price() * 144 / 250)))\n        {\n            sort_func = sort_by_priority;\n            is_resort = true;\n            make_heap(transaction_prioritys.begin(), transaction_prioritys.end(), sort_func);\n        }\n\n        size_t c;\n        if (!miner::script_hash_signature_operations_count(c, ptx->inputs, transactions) && total_tx_sig_length + tx_sig_length + c >= blockchain::max_block_script_sigops)\n            continue;\n        tx_sig_length += c;\n\n        blocked_transactions.push_back(ptx);\n        for (auto &i : coinage_reward_coinbases)\n        {\n            pblock->transactions.push_back(*i);\n        }\n\n        block_size += serialized_size;\n        total_tx_sig_length += tx_sig_length;\n        total_fee += fee;\n\n        if (transaction_dependents[h].hash)\n        {\n            transaction_dependent &d = transaction_dependents[*transaction_dependents[h].hash];\n            if (--d.dpendens == 0 && d.is_need_process)\n            {\n                next_transaction_priority = &d.transaction;\n            }\n        }\n    }\n\n    for (auto i : blocked_transactions)\n    {\n        pblock->transactions.push_back(*i);\n    }\n\n    uint64_t total_value =\n        total_fee + calculate_block_subsidy(current_block_height + 1, setting_.use_testnet_rules);\n\n    if (total_value > 0)\n    {\n        pblock->transactions[0].outputs.resize(2);\n        pblock->transactions[0].outputs[1].script.operations = chain::operation::to_pay_key_hash_pattern(short_hash(pay_address));\n        pblock->transactions[0].outputs[1].value = total_value;\n    }\n\n    // Fill in header\n    pblock->header.number = current_block_height + 1;\n    pblock->header.transaction_count = pblock->transactions.size();\n    pblock->header.previous_block_hash = prev_header.hash();\n    pblock->header.merkle = pblock->generate_merkle_root(pblock->transactions);\n    pblock->header.timestamp = get_adjust_time(pblock->header.number);\n    pblock->header.version = version;\n    /*pblock->header.bits = HeaderAux::calculateDifficulty(pblock->header, prev_header);\n    pblock->header.nonce = 0;\n    pblock->header.mixhash = 0;*/\n\n    return pblock;\n}\n\nunsigned int miner::get_adjust_time(uint64_t height) const\n{\n    typedef std::chrono::system_clock wall_clock;\n    const auto now = wall_clock::now();\n    unsigned int t = wall_clock::to_time_t(now);\n    return t;\n\n    /*if (height >= future_blocktime_fork_height) {\n        return t;\n    }\n    else {\n        unsigned int t_past = get_median_time_past(height);\n        return max(t, t_past + 1);\n    }*/\n}\n\nunsigned int miner::get_median_time_past(uint64_t height) const\n{\n    block_chain_impl &block_chain = node_.chain_impl();\n\n    int num = min<uint64_t>(height, median_time_span);\n    vector<uint64_t> times;\n\n    for (int i = 0; i < num; i++)\n    {\n        header header;\n        if (block_chain.get_header(header, height - i - 1))\n        {\n            times.push_back(header.timestamp);\n        }\n    }\n\n    sort(times.begin(), times.end());\n    return times.empty() ? 0 : times[times.size() / 2];\n}\n\nuint64_t miner::store_block(block_ptr block)\n{\n    uint64_t height;\n    boost::mutex mutex;\n    mutex.lock();\n    auto f = [&height, &mutex](const error_code &code, boost::uint64_t new_height) -> void {\n        if (new_height == 0 && code.value() != 0)\n            log::error(LOG_HEADER) << \"store_block error: \" << code.message();\n\n        height = new_height;\n        mutex.unlock();\n    };\n    node_.chain().store(block, f);\n\n    boost::unique_lock<boost::mutex> lock(mutex);\n    return height;\n}\n\ntemplate <class _T>\nstd::string to_string(_T const &_t)\n{\n    std::ostringstream o;\n    o << _t;\n    return o.str();\n}\n\nconst static BC_CONSTEXPR unsigned int num_block_per_cycle = 6;\nconst static BC_CONSTEXPR unsigned int num_miner_node = 2;\n\nvoid miner::generate_miner_list()\n{\n    mine_candidate_list.clear();\n    mine_address_list.clear();\n    auto sh_vec = node_.chain_impl().get_registered_candidates();\n    if (nullptr == sh_vec)\n    {\n        return;\n    }\n\n    uint64_t height = 0;\n    node_.chain_impl().get_last_height(height);\n    int64_t start_height = 0;\n    int64_t end_height = 0;\n\n    if (height > num_block_per_cycle * num_miner_node)\n    {\n        uint64_t sub_height = height % (num_block_per_cycle * num_miner_node);\n        end_height = height - sub_height;\n        start_height = end_height - num_block_per_cycle * num_miner_node;\n    }\n\n    for (auto &elem : *sh_vec)\n    {\n        auto &&rows = node_.chain_impl().get_address_history(bc::wallet::payment_address(elem.candidate.get_address()), start_height);\n\n        chain::transaction tx_temp;\n        uint64_t tx_height;\n\n        for (auto &row : rows)\n        {\n            // spend unconfirmed (or no spend attempted)\n            if ((row.spend.hash == null_hash) && node_.chain_impl().get_transaction(row.output.hash, tx_temp, tx_height))\n            {\n                BITCOIN_ASSERT(row.output.index < tx_temp.outputs.size());\n                const auto &output = tx_temp.outputs.at(row.output.index);\n                if (output.get_script_address() != elem.candidate.get_address())\n                {\n                    continue;\n                }\n                if (output.is_vote())\n                {\n                    auto token_amount = output.get_token_amount();\n                    uint64_t locked_amount = 0;\n                    if (token_amount && operation::is_pay_key_hash_with_attenuation_model_pattern(output.script.operations))\n                    {\n                        const auto &attenuation_model_param = output.get_attenuation_model_param();\n                        auto diff_height = row.output_height ? (height - row.output_height) : 0;\n                        auto available_amount = attenuation_model::get_available_token_amount(\n                            token_amount, diff_height, attenuation_model_param);\n                        locked_amount = token_amount - available_amount;\n                    }\n\n                    if (elem.to_uid == output.get_to_uid())\n                    {\n                        elem.vote += token_amount;\n                    }\n                }\n            }\n\n            if (row.output_height >= end_height)\n            {\n                break;\n            }\n        }\n    }\n\n    //vote first and height next.\n    std::sort(sh_vec->begin(), sh_vec->end(), [](const candidate_info &a, const candidate_info &b) {\n        return a.vote > b.vote ? true : a.output_height > b.output_height;\n    });\n\n    for (auto &elem : *sh_vec)\n    {\n        mine_candidate_list.push_back(elem);\n\n        mine_address_list.push_back(elem.candidate.get_address());\n\n        if (mine_candidate_list.size() == num_miner_node)\n        {\n            break;\n        }\n    }\n}\n\nvoid miner::work(const bc::wallet::payment_address pay_address)\n{\n    log::info(LOG_HEADER) << \"solo miner start with address: \" << pay_address.encoded();\n\n    auto sh_vec = node_.chain_impl().get_registered_candidates();\n    if (nullptr == sh_vec)\n    {\n        log::info(LOG_HEADER) << \"no candidates found \";\n\n        return;\n    }\n\n    bool ifcandidate = false;\n\n    for (auto &elem : *sh_vec)\n    {\n        if (elem.candidate.get_address() == pay_address.encoded())\n        {\n            ifcandidate = true;\n        }\n    }\n\n    if (!ifcandidate)\n    {\n        log::error(LOG_HEADER) << pay_address.encoded() << \" is not a candidate address \";\n        return;\n    }\n\n    int64_t cycle_starttime = 0;\n    while (state_ != state::exit_)\n    {\n        state_ = state::init_;\n        auto millissecond = unix_millisecond();\n        uint64_t current_block_height;\n\n        if (node_.chain_impl().get_last_height(current_block_height))\n        {\n            generate_miner_list();\n            int index = get_mine_index(pay_address.encoded());\n            if (index == -1)\n            {\n                auto sleeptime = unix_millisecond() - millissecond;\n                auto sleepmin = sleeptime < mine_block_produce_minsecons ? mine_block_produce_minsecons - sleeptime : 0;\n                sleep_for(asio::milliseconds(sleepmin));\n                continue;\n            }\n\n            /*if (current_block_height%(num_block_per_cycle*mine_address_list.size()) == 0 || millissecond-cycle_starttime >= num_block_per_cycle*mine_address_list.size()*mine_block_produce_minsecons)\n            {\n                cycle_starttime =  millissecond;\n            }*/\n\n            /*if (cycle_starttime == 0)\n            {\n                cycle_starttime = millissecond;\n            }*/\n\n            if (is_index_in_turn_with_now_height(current_block_height, index))\n            {\n                state_ = state::creating_block_;\n                block_ptr block = create_new_block(pay_address, current_block_height);\n\n                if (block)\n                {\n                    /*if (MinerAux::search(block->header, std::bind(&miner::is_stop_miner, this, block->header.number)))\n                    {*/\n                    boost::uint64_t height = store_block(block);\n                    if (height == 0)\n                    {\n                        continue;\n                    }\n\n                    log::debug(LOG_HEADER) << \"solo miner create new block at heigth:\" << height;\n\n                    ++new_block_number_;\n                    if ((new_block_limit_ != 0) && (new_block_number_ >= new_block_limit_))\n                    {\n                        thread_.reset();\n                        stop();\n                        break;\n                    }\n                    //}\n                    cycle_starttime = unix_millisecond();\n                }\n            }\n            else if (is_time_inturn_with_this_cycle(cycle_starttime))\n            {\n                uint16_t lost_block = get_lost_block(current_block_height, index);\n\n                for (uint16_t i = lost_block; i > 0; i--)\n                {\n                    state_ = state::creating_block_;\n                    block_ptr block = create_new_block(pay_address, current_block_height);\n\n                    if (block)\n                    {\n                        /*if (MinerAux::search(block->header, std::bind(&miner::is_stop_miner, this, block->header.number)))\n                    {*/\n                        boost::uint64_t height = store_block(block);\n                        if (height == 0)\n                        {\n                            continue;\n                        }\n\n                        log::debug(LOG_HEADER) << \"solo miner create new block at heigth:\" << height;\n\n                        ++new_block_number_;\n                        if ((new_block_limit_ != 0) && (new_block_number_ >= new_block_limit_))\n                        {\n                            thread_.reset();\n                            stop();\n                            break;\n                        }\n                        //}\n                    }\n                    if (!node_.chain_impl().get_last_height(current_block_height))\n                    {\n                        break;\n                    }\n                }\n            }\n        }\n\n        createblockms_ = unix_millisecond() - millissecond;\n        auto sleepmin = createblockms_ < mine_block_produce_minsecons ? mine_block_produce_minsecons - createblockms_ : 0;\n        //log::info(LOG_HEADER) << \"solo miner create new block for \" << createblockms_<<\" ms\";\n        sleep_for(asio::milliseconds(sleepmin));\n    }\n}\n\nint miner::get_mine_index(const string &pay_address) const\n{\n    auto it = find(mine_address_list.begin(), mine_address_list.end(), pay_address);\n\n    if (it == mine_address_list.end())\n    {\n        return -1;\n    }\n    else\n    {\n        return it - mine_address_list.begin();\n    }\n}\n\nbool miner::is_address_inturn(const string &pay_address) const\n{\n    uint64_t current_block_height;\n    if (!node_.chain_impl().get_last_height(current_block_height))\n    {\n        return false;\n    }\n    const int index = get_mine_index(pay_address);\n    if (index == -1)\n    {\n        return false;\n    }\n    return is_index_in_turn_with_now_height(current_block_height, index);\n}\n\nbool miner::is_address_in_turn_with_now_height(uint64_t height, const string &pay_address) const\n{\n    int index = get_mine_index(pay_address);\n    if (index == -1)\n    {\n        return false;\n    }\n    return is_index_in_turn_with_now_height(height, index);\n}\n\nbool miner::is_index_in_turn_with_now_height(uint64_t current_block_height, const int index) const\n{\n    return current_block_height % (mine_address_list.size() * num_block_per_cycle) >= index * num_block_per_cycle && current_block_height % (mine_address_list.size() * num_block_per_cycle) < (index + 1) * num_block_per_cycle;\n}\n\nbool miner::is_time_inturn_with_this_cycle(int64_t cycle_starttime) const\n{\n    if (cycle_starttime == 0)\n    {\n        return false;\n    }\n\n    auto expect_time_window = mine_block_produce_minsecons * num_block_per_cycle * (mine_address_list.size() - 1);\n\n    auto real_time_window = unix_millisecond() - cycle_starttime;\n\n    auto time_interval = real_time_window > expect_time_window ? real_time_window - expect_time_window : 0;\n\n    if (time_interval > mine_block_produce_minsecons)\n    {\n        return true;\n    }\n\n    return false;\n}\n\nuint16_t miner::get_lost_block(uint64_t height, const int index)\n{\n    if (mine_address_list.size() == 0)\n    {\n        return 0;\n    }\n\n    auto cycle_block_start = height % (num_block_per_cycle * num_miner_node);\n    auto cycle_block = cycle_block_start % (num_block_per_cycle * mine_address_list.size());\n    auto expect_cycle_block = index * num_block_per_cycle;\n    if (expect_cycle_block == 0 && cycle_block > 0)\n    {\n        expect_cycle_block = num_block_per_cycle * mine_address_list.size();\n    }\n    return expect_cycle_block > cycle_block ? expect_cycle_block - cycle_block : 0;\n}\n\nbool miner::is_stop_miner(uint64_t block_height) const\n{\n    return (state_ == state::exit_) || (get_height() > block_height);\n}\n\nbool miner::start(const bc::wallet::payment_address &pay_address, uint16_t number)\n{\n    if (!thread_)\n    {\n        new_block_limit_ = number;\n        thread_.reset(new boost::thread(bind(&miner::work, this, pay_address)));\n    }\n    pay_address_ = pay_address;\n    return true;\n}\n\nbool miner::start(const std::string &public_key, uint16_t number)\n{\n    bc::wallet::payment_address pay_address = libbitcoin::wallet::ec_public(public_key).to_payment_address();\n    if (pay_address)\n    {\n        return start(pay_address, number);\n    }\n    return false;\n}\n\nbool miner::stop()\n{\n    if (thread_)\n    {\n        state_ = state::exit_;\n        thread_->join();\n        thread_.reset();\n    }\n\n    state_ = state::init_;\n    new_block_number_ = 0;\n    new_block_limit_ = 0;\n    return true;\n}\n\nuint64_t miner::get_height() const\n{\n    uint64_t height = 0;\n    node_.chain_impl().get_last_height(height);\n    return height;\n}\n\n/*bool miner::set_miner_public_key(const string& public_key)\n{\n    libbitcoin::wallet::ec_public ec_public_key(public_key);\n    pay_address_ = ec_public_key.to_payment_address();\n    if (pay_address_) {\n        log::debug(LOG_HEADER) << \"set_miner_public_key[\" << pay_address_.encoded() << \"] success\";\n        return true;\n    }\n    else {\n        log::error(LOG_HEADER) << \"set_miner_public_key[\" << public_key << \"] is not availabe!\";\n        return false;\n    }\n}*/\n\nbool miner::set_miner_pri_key(const string &pri_key)\n{\n    this->pri_key = pri_key;\n}\n\nbool miner::set_miner_payment_address(const bc::wallet::payment_address &address)\n{\n    if (address)\n    {\n        log::debug(LOG_HEADER) << \"set_miner_payment_address[\" << address.encoded() << \"] success\";\n    }\n    else\n    {\n        log::error(LOG_HEADER) << \"set_miner_payment_address[\" << address.encoded() << \"] is not availabe!\";\n        return false;\n    }\n\n    pay_address_ = address;\n    return true;\n}\n\nconst std::string miner::get_miner_address() const\n{\n    return pay_address_.encoded();\n}\n\nminer::block_ptr miner::get_block(bool is_force_create_block)\n{\n    static std::mutex mtx;\n    std::lock_guard<std::mutex> lock(mtx);\n\n    if (is_force_create_block)\n    {\n        new_block_ = create_new_block(pay_address_);\n        log::debug(LOG_HEADER) << \"force create new block\";\n        return new_block_;\n    }\n\n    if (!new_block_)\n    {\n        if (pay_address_)\n        {\n            new_block_ = create_new_block(pay_address_);\n        }\n        else\n        {\n            log::error(LOG_HEADER) << \"get_block not set pay address\";\n        }\n    }\n    else\n    {\n        if (get_height() >= new_block_->header.number)\n        {\n            new_block_ = create_new_block(pay_address_);\n        }\n    }\n\n    return new_block_;\n}\n\n/*bool miner::get_work(std::string& seed_hash, std::string& header_hash, std::string& boundary)\n{\n    block_ptr block = get_block();\n    if (block) {\n        header_hash = \"0x\" + to_string(HeaderAux::hashHead(new_block_->header));\n        seed_hash = \"0x\" + to_string(HeaderAux::seedHash(new_block_->header));\n        boundary = \"0x\" + to_string(HeaderAux::boundary(new_block_->header));\n        return true;\n    }\n    return false;\n}*/\n\n/*bool miner::put_result(const std::string& nonce, const std::string& mix_hash,\n                       const std::string& header_hash, const uint64_t &nounce_mask)\n{\n    bool ret = false;\n    if (!get_block()) {\n        return ret;\n    }\n\n    if (header_hash == \"0x\" + to_string(HeaderAux::hashHead(new_block_->header))) {\n        auto s_nonce = \"0x\" + nonce;\n        uint64_t n_nonce;\n#ifdef MAC_OSX\n        size_t sz = 0;\n        n_nonce = std::stoull(s_nonce, &sz, 16);\n#else\n        if (sscanf(s_nonce.c_str(), \"%lx\", &n_nonce) != 1) {\n            log::error(LOG_HEADER) << \"nonce change error\\n\";\n            return false;\n        }\n#endif\n        // nounce_mask defination is moved to the caller by chengzhiping 2018-3-15.\n        uint64_t nonce_t = n_nonce ^ nounce_mask;\n        new_block_->header.nonce = (u64) nonce_t;\n        new_block_->header.mixhash = (FixedHash<32>::Arith)h256(mix_hash);\n        uint64_t height = store_block(new_block_);\n        if (height != 0) {\n            log::debug(LOG_HEADER) << \"put_result nonce:\" << nonce << \" mix_hash:\"\n                                   << mix_hash << \" success with height:\" << height;\n            ret = true;\n        }\n        else {\n            get_block(true);\n            log::debug(LOG_HEADER) << \"put_result nonce:\" << nonce << \" mix_hash:\" << mix_hash << \" fail\";\n        }\n    }\n    else {\n        log::error(LOG_HEADER) << \"put_result header_hash check fail. header_hash:\"\n                               << header_hash << \" hashHead:\" << to_string(HeaderAux::hashHead(new_block_->header));\n    }\n\n    return ret;\n}*/\n\nvoid miner::get_state(uint64_t &height, uint32_t &miners, /*uint64_t &rate, string& difficulty,*/ bool &is_mining)\n{\n    //rate = MinerAux::getRate();\n    block_chain_impl &block_chain = node_.chain_impl();\n    header prev_header;\n    block_chain.get_last_height(height);\n    block_chain.get_header(prev_header, height);\n    //difficulty = to_string((u256)prev_header.bits);\n    is_mining = thread_ ? true : false;\n    miners = mine_candidate_list.size();\n}\n\nbool miner::is_creating_block() const\n{\n    return state_ == state::creating_block_;\n}\n\nvector<candidate_info> &miner::get_miners()\n{\n    if (!thread_)\n    {\n        generate_miner_list();\n    }\n\n    return mine_candidate_list;\n}\n\nvector<std::string> &miner::get_miner_addresses()\n{\n    return mine_address_list;\n}\n\nbool miner::get_block_header(chain::header &block_header, const string &para)\n{\n    if (para == \"pending\")\n    {\n        block_ptr block = get_block();\n        if (block)\n        {\n            block_header = block->header;\n            return true;\n        }\n    }\n    else if (!para.empty())\n    {\n        block_chain_impl &block_chain = node_.chain_impl();\n        uint64_t height{0};\n        if (para == \"latest\")\n        {\n            if (!block_chain.get_last_height(height))\n            {\n                return false;\n            }\n        }\n        else if (para == \"earliest\")\n        {\n            height = 0;\n        }\n        else if (para[0] >= '0' && para[0] <= '9')\n        {\n            height = atol(para.c_str());\n        }\n        else\n        {\n            return false;\n        }\n\n        if (block_chain.get_header(block_header, height))\n            return true;\n    }\n\n    return false;\n}\n\n} // namespace consensus\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/data/CMakeLists.txt",
    "content": "FILE(GLOB_RECURSE data_SOURCES \"*.cpp\")\n\nADD_DEFINITIONS(-DBCD_STATIC=1)\n\nSET(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -Wno-braced-scalar-init\")\n\nADD_LIBRARY(data_static STATIC ${data_SOURCES})\nSET_TARGET_PROPERTIES(data_static PROPERTIES OUTPUT_NAME uc_data)\nTARGET_LINK_LIBRARIES(data_static ${Boost_LIBRARIES} ${txs_LIBRARY} ${bitcoin_LIBRARY})\nINSTALL(TARGETS data_static DESTINATION lib)\n\nIF(ENABLE_SHARED_LIBS)\n    ADD_DEFINITIONS(-DBCD_DLL=1)\n  ADD_LIBRARY(data_shared SHARED ${data_SOURCES})\n  SET_TARGET_PROPERTIES(data_shared PROPERTIES OUTPUT_NAME uc_data)\n  TARGET_LINK_LIBRARIES(data_shared ${Boost_LIBRARIES} ${txs_LIBRARY} ${bitcoin_LIBRARY})\n  INSTALL(TARGETS data_shared DESTINATION lib)\nENDIF()\n"
  },
  {
    "path": "src/UChainService/data/database/address_token_db.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS) \n *\n * This file is part of ucd.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/data/databases/address_token_db.hpp>\n//#include <UChainService/txs/wallet/address_token.hpp>\n\n#include <cstdint>\n#include <cstddef>\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/memory/memory.hpp>\n#include <UChain/database/primitives/record_multimap_iterable.hpp>\n#include <UChain/database/primitives/record_multimap_iterator.hpp>\n\n#define LOG_ADDRESS_TOKEN_DATABASE \"address_token_database\"\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nusing namespace boost::filesystem;\nusing namespace bc::chain;\n\nBC_CONSTEXPR size_t number_buckets = 97210744;\nBC_CONSTEXPR size_t header_size = record_hash_table_header_size(number_buckets);\nBC_CONSTEXPR size_t initial_lookup_file_size = header_size + minimum_records_size;\n\nBC_CONSTEXPR size_t record_size = hash_table_multimap_record_size<short_hash>();\n\nBC_CONSTEXPR size_t token_transfer_record_size = 1 + 36 + 4 + 8 + 2 + 4 + TOKEN_DETAIL_FIX_SIZE; // TOKEN_DETAIL_FIX_SIZE is the biggest one\n//      + std::max({UCN_FIX_SIZE, TOKEN_DETAIL_FIX_SIZE, TOKEN_TRANSFER_FIX_SIZE});\nBC_CONSTEXPR size_t row_record_size = hash_table_record_size<hash_digest>(token_transfer_record_size);\n\naddress_token_database::address_token_database(const path &lookup_filename,\n                                               const path &rows_filename, std::shared_ptr<shared_mutex> mutex)\n    : lookup_file_(lookup_filename, mutex),\n      lookup_header_(lookup_file_, number_buckets),\n      lookup_manager_(lookup_file_, header_size, record_size),\n      lookup_map_(lookup_header_, lookup_manager_),\n      rows_file_(rows_filename, mutex),\n      rows_manager_(rows_file_, 0, row_record_size),\n      rows_list_(rows_manager_),\n      rows_multimap_(lookup_map_, rows_list_)\n{\n}\n\n// Close does not call stop because there is no way to detect thread join.\naddress_token_database::~address_token_database()\n{\n    close();\n}\n\n// Create.\n// ----------------------------------------------------------------------------\n\n// Initialize files and start.\nbool address_token_database::create()\n{\n    // Resize and create require a started file.\n    if (!lookup_file_.start() ||\n        !rows_file_.start())\n        return false;\n\n    // These will throw if insufficient disk space.\n    lookup_file_.resize(initial_lookup_file_size);\n    rows_file_.resize(minimum_records_size);\n\n    if (!lookup_header_.create() ||\n        !lookup_manager_.create() ||\n        !rows_manager_.create())\n        return false;\n\n    // Should not call start after create, already started.\n    return lookup_header_.start() &&\n           lookup_manager_.start() &&\n           rows_manager_.start();\n}\n\n// Startup and shutdown.\n// ----------------------------------------------------------------------------\n\nbool address_token_database::start()\n{\n    return lookup_file_.start() &&\n           rows_file_.start() &&\n           lookup_header_.start() &&\n           lookup_manager_.start() &&\n           rows_manager_.start();\n}\n\nbool address_token_database::stop()\n{\n    return lookup_file_.stop() &&\n           rows_file_.stop();\n}\n\nbool address_token_database::close()\n{\n    return lookup_file_.close() &&\n           rows_file_.close();\n}\n\n// ----------------------------------------------------------------------------\nvoid address_token_database::store_input(const short_hash &key,\n                                         const output_point &inpoint, uint32_t input_height,\n                                         const input_point &previous, uint32_t timestamp)\n{\n    auto write = [&](memory_ptr data) {\n        auto serial = make_serializer(REMAP_ADDRESS(data));\n        serial.write_byte(static_cast<uint8_t>(point_kind::spend)); // 1\n        serial.write_data(inpoint.to_data());                       // 36\n        serial.write_4_bytes_little_endian(input_height);           // 4\n        serial.write_8_bytes_little_endian(previous.checksum());    // 8\n\n        serial.write_2_bytes_little_endian(0);         // 2 use ucn type fill incase invalid when deser\n        serial.write_4_bytes_little_endian(timestamp); // 4\n        // token data should be here but input has no these data\n    };\n    rows_multimap_.add_row(key, write);\n}\n\nvoid address_token_database::delete_last_row(const short_hash &key)\n{\n    rows_multimap_.delete_last_row(key);\n}\n\n/// get all record of key from database\nbusiness_record::list address_token_database::get(const short_hash &key,\n                                                  size_t from_height, size_t limit) const\n{\n    // Read the height value from the row.\n    const auto read_height = [](uint8_t *data) {\n        static constexpr file_offset height_position = 1 + 36;\n        const auto height_address = data + height_position;\n        return from_little_endian_unsafe<uint32_t>(height_address);\n    };\n\n    // Read a row from the data for the history list.\n    const auto read_row = [](uint8_t *data) {\n        auto deserial = make_deserializer_unsafe(data);\n        return business_record{\n            // output or spend?\n            static_cast<point_kind>(deserial.read_byte()),\n\n            // point\n            point::factory_from_data(deserial),\n\n            // height\n            deserial.read_4_bytes_little_endian(),\n\n            // value or checksum\n            {deserial.read_8_bytes_little_endian()},\n\n            // business_kd;\n            //deserial.read_2_bytes_little_endian(),\n            // timestamp;\n            //deserial.read_4_bytes_little_endian(),\n\n            asset_data::factory_from_data(deserial) // 2 + 4 are in this class\n        };\n    };\n\n    business_record::list result;\n    const auto start = rows_multimap_.lookup(key);\n    const auto records = record_multimap_iterable(rows_list_, start);\n\n    for (const auto index : records)\n    {\n        // Stop once we reach the limit (if specified).\n        if (limit > 0 && result.size() >= limit)\n            break;\n\n        // This obtains a remap safe address pointer against the rows file.\n        const auto record = rows_list_.get(index);\n        const auto address = REMAP_ADDRESS(record);\n\n        // Skip rows below from_height.\n        if (from_height == 0 || read_height(address) >= from_height) // from current block height\n            result.emplace_back(read_row(address));\n    }\n\n    // TODO: we could sort result here.\n    return result;\n}\n\n/// get all record of key from database\nstd::shared_ptr<business_record::list> address_token_database::get(\n    const std::string &address, const std::string &symbol,\n    size_t start_height, size_t end_height, uint64_t limit, uint64_t page_number) const\n{\n    data_chunk addr_data(address.begin(), address.end());\n    auto key = ripemd160_hash(addr_data);\n\n    // Read the height value from the row.\n    const auto read_height = [](uint8_t *data) {\n        static constexpr file_offset height_position = 1 + 36;\n        const auto height_address = data + height_position;\n        return from_little_endian_unsafe<uint32_t>(height_address);\n    };\n\n    // Read a row from the data for the history list.\n    const auto read_row = [](uint8_t *data) {\n        auto deserial = make_deserializer_unsafe(data);\n        return business_record{\n            // output or spend?\n            static_cast<point_kind>(deserial.read_byte()),\n\n            // point\n            point::factory_from_data(deserial),\n\n            // height\n            deserial.read_4_bytes_little_endian(),\n\n            // value or checksum\n            {deserial.read_8_bytes_little_endian()},\n\n            // business_kd;\n            //deserial.read_2_bytes_little_endian(),\n            // timestamp;\n            //deserial.read_4_bytes_little_endian(),\n\n            asset_data::factory_from_data(deserial) // 2 + 4 are in this class\n        };\n    };\n\n    auto result = std::make_shared<business_record::list>();\n    const auto start = rows_multimap_.lookup(key);\n    const auto records = record_multimap_iterable(rows_list_, start);\n\n    uint64_t cnt = 0;\n    for (const auto index : records)\n    {\n        // Stop once we reach the limit (if specified).\n        if (limit > 0 && result->size() >= limit)\n            break;\n\n        // This obtains a remap safe address pointer against the rows file.\n        const auto record = rows_list_.get(index);\n        const auto address = REMAP_ADDRESS(record);\n        auto height = read_height(address);\n        std::string token_symbol;\n\n        // Skip rows below from_height.\n        if ((start_height <= height) && ((end_height == 0) || (height < end_height)))\n        { // from current block height\n            //result->emplace_back(read_row(address));\n            auto row = read_row(address);\n            if (symbol.empty())\n            { // all utxo\n                cnt++;\n                if ((limit > 0) && (page_number > 0) && ((cnt - 1) / limit) < (page_number - 1))\n                    continue; // skip previous page record\n                result->emplace_back(row);\n            }\n            else\n            { // token symbol utxo\n                // token business process\n                token_symbol = \"\";\n                if (row.data.get_kind_value() == business_kind::token_issue)\n                {\n                    auto transfer = boost::get<token_detail>(row.data.get_data());\n                    token_symbol = transfer.get_symbol();\n                }\n\n                if (row.data.get_kind_value() == business_kind::token_transfer)\n                {\n                    auto transfer = boost::get<token_transfer>(row.data.get_data());\n                    token_symbol = transfer.get_symbol();\n                }\n\n                if (row.data.get_kind_value() == business_kind::token_cert)\n                {\n                    auto cert = boost::get<token_cert>(row.data.get_data());\n                    token_symbol = cert.get_symbol();\n                }\n\n                if (symbol == token_symbol)\n                {\n                    cnt++;\n                    if ((limit > 0) && (page_number > 0) && ((cnt - 1) / limit) < (page_number - 1))\n                        continue; // skip previous page record\n                    result->emplace_back(row);\n                }\n            }\n        }\n    }\n\n    // TODO: we could sort result here.\n    return result;\n}\n\n/// get all record of key from database\nstd::shared_ptr<business_record::list> address_token_database::get(const std::string &address, size_t start_height,\n                                                                   size_t end_height) const\n{\n    data_chunk addr_data(address.begin(), address.end());\n    auto key = ripemd160_hash(addr_data);\n\n    // Read the height value from the row.\n    const auto read_height = [](uint8_t *data) {\n        static constexpr file_offset height_position = 1 + 36;\n        const auto height_address = data + height_position;\n        return from_little_endian_unsafe<uint32_t>(height_address);\n    };\n\n    // Read a row from the data for the history list.\n    const auto read_row = [](uint8_t *data) {\n        auto deserial = make_deserializer_unsafe(data);\n        return business_record{\n            // output or spend?\n            static_cast<point_kind>(deserial.read_byte()),\n\n            // point\n            point::factory_from_data(deserial),\n\n            // height\n            deserial.read_4_bytes_little_endian(),\n\n            // value or checksum\n            {deserial.read_8_bytes_little_endian()},\n\n            // business_kd;\n            //deserial.read_2_bytes_little_endian(),\n            // timestamp;\n            //deserial.read_4_bytes_little_endian(),\n\n            asset_data::factory_from_data(deserial) // 2 + 4 are in this class\n        };\n    };\n\n    auto result = std::make_shared<business_record::list>();\n    const auto start = rows_multimap_.lookup(key);\n    const auto records = record_multimap_iterable(rows_list_, start);\n\n    for (const auto index : records)\n    {\n        // This obtains a remap safe address pointer against the rows file.\n        const auto record = rows_list_.get(index);\n        const auto address = REMAP_ADDRESS(record);\n        auto height = read_height(address);\n        // Skip rows below from_height.\n        if ((start_height <= height) && ((end_height == 0) || (height < end_height)))\n        {\n            result->emplace_back(read_row(address));\n        }\n    }\n\n    // TODO: we could sort result here.\n    return result;\n}\n\n/// get all record of key from database\nstd::shared_ptr<business_record::list> address_token_database::get(size_t idx) const\n{\n    // Read a row from the data for the history list.\n    const auto read_row = [](uint8_t *data) {\n        auto deserial = make_deserializer_unsafe(data);\n        return business_record{\n            // output or spend?\n            static_cast<point_kind>(deserial.read_byte()),\n\n            // point\n            point::factory_from_data(deserial),\n\n            // height\n            deserial.read_4_bytes_little_endian(),\n\n            // value or checksum\n            {deserial.read_8_bytes_little_endian()},\n\n            // business_kd;\n            //deserial.read_2_bytes_little_endian(),\n            // timestamp;\n            //deserial.read_4_bytes_little_endian(),\n\n            asset_data::factory_from_data(deserial) // 2 + 4 are in this class\n        };\n    };\n\n    auto result = std::make_shared<business_record::list>();\n    auto sh_idx_vec = rows_multimap_.lookup(idx);\n\n    for (auto each : *sh_idx_vec)\n    {\n        const auto records = record_multimap_iterable(rows_list_, each);\n        for (const auto index : records)\n        {\n            // This obtains a remap safe address pointer against the rows file.\n            const auto record = rows_list_.get(index);\n            const auto address = REMAP_ADDRESS(record);\n            result->emplace_back(read_row(address));\n        }\n    }\n\n    // TODO: we could sort result here.\n    return result;\n}\n\n/// get one record by index from row_list\nbusiness_record address_token_database::get_record(size_t idx) const\n{\n    // Read a row from the data for the history list.\n    const auto read_row = [](uint8_t *data) {\n        auto deserial = make_deserializer_unsafe(data);\n        return business_record{\n            // output or spend?\n            static_cast<point_kind>(deserial.read_byte()),\n\n            // point\n            point::factory_from_data(deserial),\n\n            // height\n            deserial.read_4_bytes_little_endian(),\n\n            // value or checksum\n            {deserial.read_8_bytes_little_endian()},\n\n            // business_kd;\n            //deserial.read_2_bytes_little_endian(),\n            // timestamp;\n            //deserial.read_4_bytes_little_endian(),\n\n            asset_data::factory_from_data(deserial) // 2 + 4 are in this class\n        };\n    };\n\n    // This obtains a remap safe address pointer against the rows file.\n    const auto record = rows_list_.get(idx);\n    const auto address = REMAP_ADDRESS(record);\n    return read_row(address);\n}\n\nbusiness_history::list address_token_database::get_business_history(const short_hash &key,\n                                                                    size_t from_height) const\n{\n    business_record::list compact = get(key, from_height, 0);\n    business_history::list result;\n\n    // Process and remove all outputs.\n    for (auto output = compact.begin(); output != compact.end();)\n    {\n        if (output->kind == point_kind::output)\n        {\n            business_history row;\n            row.output = output->point;\n            row.output_height = output->height;\n            row.value = output->val_chk_sum.value;\n            row.spend = {null_hash, max_uint32};\n            row.temporary_checksum = output->point.checksum();\n            row.data = output->data;\n            result.emplace_back(row);\n            output = compact.erase(output);\n            continue;\n        }\n\n        ++output;\n    }\n\n    // All outputs have been removed, process the spends.\n    for (const auto &spend : compact)\n    {\n        auto found = false;\n\n        // Update outputs with the corresponding spends.\n        for (auto &row : result)\n        {\n            if (row.temporary_checksum == spend.val_chk_sum.previous_checksum && row.spend.hash == null_hash)\n            {\n                row.spend = spend.point;\n                row.spend_height = spend.height;\n                found = true;\n                break;\n            }\n        }\n\n        // This will only happen if the history height cutoff comes between\n        // an output and its spend. In this case we return just the spend.\n        if (!found)\n        {\n            business_history row;\n            row.output = {null_hash, max_uint32};\n            row.output_height = max_uint64;\n            row.value = max_uint64;\n            row.spend = spend.point;\n            row.spend_height = spend.height;\n            result.emplace_back(row);\n        }\n    }\n\n    compact.clear();\n\n    // Clear all remaining checksums from unspent rows.\n    for (auto &row : result)\n        if (row.spend.hash == null_hash)\n            row.spend_height = max_uint64;\n\n    // TODO: sort by height and index of output, spend or both in order.\n    return result;\n}\n\n// get address tokens in the database(blockchain)\nstd::shared_ptr<business_history::list> address_token_database::get_address_business_history(\n    const std::string &address, size_t from_height) const\n{\n    data_chunk data(address.begin(), address.end());\n    auto key = ripemd160_hash(data);\n    business_history::list result = get_business_history(key, from_height);\n    auto unspent = std::make_shared<business_history::list>();\n\n    for (auto &row : result)\n    {\n        if ((row.spend.hash == null_hash))\n        { // unspent business\n            row.status = business_status::unspent;\n            unspent->emplace_back(row);\n        }\n\n        if (row.output_height != 0 && (row.spend.hash == null_hash || row.spend_height == 0))\n        { // confirmed business\n            row.status = business_status::confirmed;\n            unspent->emplace_back(row);\n        }\n    }\n\n    return unspent;\n}\n\n// get special kind of token in the database(blockchain)\n/*\n status -- // 0 -- unspent  1 -- confirmed\n*/\nbusiness_history::list address_token_database::get_business_history(const std::string &address,\n                                                                    size_t from_height, business_kind kind, uint8_t status) const\n{\n    data_chunk data(address.begin(), address.end());\n    auto key = ripemd160_hash(data);\n    business_history::list result = get_business_history(key, from_height);\n    business_history::list unspent;\n\n    // token type check\n    if ((kind != business_kind::token_issue)       // token_detail\n        && (kind != business_kind::token_transfer) // token_transfer\n        && (kind != business_kind::token_cert)     // token_cert\n        && (kind != business_kind::ucn_award) && (kind != business_kind::ucn))\n        return unspent;\n\n    for (const auto &row : result)\n    {\n        if (row.data.get_kind_value() != kind)\n            continue;\n\n        if ((row.spend.hash == null_hash) && (status == business_status::unspent)) // unspent business\n            unspent.emplace_back(row);\n\n        if (row.output_height != 0 && (row.spend.hash == null_hash || row.spend_height == 0) && (status == business_status::confirmed)) // confirmed business\n            unspent.emplace_back(row);\n    }\n\n    return unspent;\n}\n\n// get special kind of token in the database(blockchain)\n/*\n status -- // 0 -- unspent  1 -- confirmed\n*/\nbusiness_history::list address_token_database::get_business_history(const std::string &address,\n                                                                    size_t from_height, business_kind kind, uint32_t time_begin, uint32_t time_end) const\n{\n    data_chunk data(address.begin(), address.end());\n    auto key = ripemd160_hash(data);\n    business_history::list result = get_business_history(key, from_height);\n    business_history::list unspent;\n\n    // token type check\n    if ((kind != business_kind::token_issue)       // token_detail\n        && (kind != business_kind::token_transfer) // token_transfer\n        && (kind != business_kind::token_cert)     // token_cert\n        && (kind != business_kind::ucn_award) && (kind != business_kind::ucn))\n        return unspent;\n\n    for (auto &row : result)\n    {\n        if (row.data.get_kind_value() != kind || row.data.get_timestamp() < time_begin || row.data.get_timestamp() > time_end)\n            continue;\n\n        if ((row.spend.hash == null_hash))\n        { //0 -- unspent business\n            row.status = business_status::unspent;\n            unspent.emplace_back(row);\n        }\n\n        if (row.output_height != 0 && (row.spend.hash == null_hash || row.spend_height == 0))\n        { // 1 -- confirmed business\n            row.status = business_status::confirmed;\n            unspent.emplace_back(row);\n        }\n    }\n\n    return unspent;\n}\n\n// get all kinds of token in the database(blockchain)\nbusiness_address_token::list address_token_database::get_tokens(const std::string &address,\n                                                                size_t from_height) const\n{\n    return get_tokens(address, from_height, business_kind::unknown);\n}\n\n// get special kind of token in the database(blockchain)\nbusiness_address_token::list address_token_database::get_tokens(const std::string &address,\n                                                                size_t from_height, business_kind kind) const\n{\n    data_chunk data(address.begin(), address.end());\n    auto key = ripemd160_hash(data);\n    business_history::list result = get_business_history(key, from_height);\n    business_address_token::list unspent;\n\n    // get by kind\n    if (kind != business_kind::unknown)\n    {\n        // token type check\n        if ((kind != business_kind::token_issue)        // token_detail\n            && (kind != business_kind::token_transfer)) // token_transfer\n            return unspent;\n    }\n\n    for (const auto &row : result)\n    {\n        auto kind_value = row.data.get_kind_value();\n        if (kind != business_kind::unknown)\n        {\n            if (kind_value != kind)\n                continue;\n        }\n        else\n        {\n            if ((kind_value != business_kind::token_issue)        // token_detail\n                && (kind_value != business_kind::token_transfer)) // token_transfer\n                continue;\n        }\n\n        uint8_t status = business_status::unknown;\n        if (row.spend.hash == null_hash)\n            status = business_status::unspent; // 0 -- unspent  1 -- confirmed\n\n        if (row.output_height != 0 &&\n            (row.spend.hash == null_hash || row.spend_height == 0))\n            status = business_status::confirmed;\n\n        business_address_token detail;\n        if (kind_value == business_kind::token_issue)\n        {\n            // token issue\n            auto issue_info = boost::get<token_detail>(row.data.get_data());\n            detail.quantity = issue_info.get_maximum_supply();\n            detail.detail = issue_info;\n        }\n        else\n        {\n            //token transfer\n            auto transfer_info = boost::get<token_transfer>(row.data.get_data());\n            detail.quantity = transfer_info.get_quantity();\n            detail.detail.set_symbol(transfer_info.get_symbol());\n        }\n\n        detail.address = address; // wallet address\n        detail.status = status;   // 0 -- unspent  1 -- confirmed\n        unspent.emplace_back(detail);\n    }\n\n    return unspent;\n}\n\nbusiness_address_message::list address_token_database::get_messages(const std::string &address,\n                                                                    size_t from_height) const\n{\n    data_chunk data(address.begin(), address.end());\n    auto key = ripemd160_hash(data);\n    business_history::list result = get_business_history(key, from_height);\n    business_address_message::list unspent;\n    for (const auto &row : result)\n    {\n        if ((row.data.get_kind_value() != business_kind::message))\n            continue;\n\n        uint8_t status = business_status::unknown;\n        if (row.spend.hash == null_hash)\n            status = business_status::unspent; // 0 -- unspent  1 -- confirmed\n\n        if (row.output_height != 0 &&\n            (row.spend.hash == null_hash || row.spend_height == 0))\n            status = business_status::confirmed;\n\n        business_address_message detail;\n        auto issue_info = boost::get<chain::blockchain_message>(row.data.get_data());\n        detail.msg = issue_info;\n\n        detail.address = address; // wallet address\n        detail.status = status;   // 0 -- unspent  1 -- confirmed\n        unspent.emplace_back(detail);\n    }\n\n    return unspent;\n}\n\nbusiness_address_token_cert::list address_token_database::get_token_certs(const std::string &address,\n                                                                          const std::string &symbol, token_cert_type cert_type, size_t from_height) const\n{\n    data_chunk data(address.begin(), address.end());\n    auto key = ripemd160_hash(data);\n    business_history::list result = get_business_history(key, from_height);\n    business_address_token_cert::list unspent;\n    for (const auto &row : result)\n    {\n        if ((row.data.get_kind_value() != business_kind::token_cert)) // token_cert\n            continue;\n\n        auto cert_info = boost::get<token_cert>(row.data.get_data());\n        if (!symbol.empty())\n        {\n            if (symbol != cert_info.get_symbol())\n            {\n                continue;\n            }\n        }\n\n        if (cert_type != token_cert_ns::none)\n        {\n            if (cert_type != cert_info.get_type())\n            {\n                continue;\n            }\n        }\n\n        uint8_t status = business_status::unknown;\n        if (row.spend.hash == null_hash)\n            status = business_status::unspent;\n\n        if (row.output_height != 0 &&\n            (row.spend.hash == null_hash || row.spend_height == 0))\n            status = business_status::confirmed;\n\n        if (status == business_status::unknown)\n        {\n            continue;\n        }\n\n        business_address_token_cert cert;\n        cert.certs = cert_info;\n        cert.address = address; // wallet address\n        cert.status = status;   // 0 -- unspent  1 -- confirmed\n        unspent.emplace_back(cert);\n    }\n\n    return unspent;\n}\n\nbusiness_history::list address_token_database::get_token_certs_history(const std::string &address,\n                                                                       const std::string &symbol, token_cert_type cert_type,\n                                                                       size_t from_height) const\n{\n    data_chunk data(address.begin(), address.end());\n    auto key = ripemd160_hash(data);\n    business_history::list result = get_business_history(key, from_height);\n    business_history::list unspent(result.size());\n\n    auto it = std::copy_if(result.begin(), result.end(), unspent.begin(), [&symbol, &cert_type](business_history &row) {\n        if ((row.data.get_kind_value() != business_kind::token_cert)) // token_cert\n            return false;\n\n        auto cert_info = boost::get<token_cert>(row.data.get_data());\n        if (!symbol.empty())\n        {\n            if (symbol != cert_info.get_symbol())\n            {\n                return false;\n            }\n        }\n\n        if (cert_type != token_cert_ns::none)\n        {\n            if (cert_type != cert_info.get_type())\n            {\n                return false;\n            }\n        }\n        return true;\n    });\n\n    unspent.resize(std::distance(unspent.begin(), it));\n    return unspent;\n}\n\nvoid address_token_database::sync()\n{\n    lookup_manager_.sync();\n    rows_manager_.sync();\n}\n\naddress_token_statinfo address_token_database::statinfo() const\n{\n    return {\n        lookup_header_.size(),\n        lookup_manager_.count(),\n        rows_manager_.count()};\n}\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/data/database/address_uid_db.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS) \n *\n * This file is part of ucd.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/data/databases/address_uid_db.hpp>\n//#include <UChainService/txs/wallet/address_uid.hpp>\n\n#include <cstdint>\n#include <cstddef>\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/memory/memory.hpp>\n#include <UChain/database/primitives/record_multimap_iterable.hpp>\n#include <UChain/database/primitives/record_multimap_iterator.hpp>\n\n#define LOG_ADDRESS_UID_DATABASE \"address_uid_database\"\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nusing namespace boost::filesystem;\nusing namespace bc::chain;\n\nBC_CONSTEXPR size_t number_buckets = 97210744;\nBC_CONSTEXPR size_t header_size = record_hash_table_header_size(number_buckets);\nBC_CONSTEXPR size_t initial_lookup_file_size = header_size + minimum_records_size;\n\nBC_CONSTEXPR size_t record_size = hash_table_multimap_record_size<short_hash>();\n\nBC_CONSTEXPR size_t uid_transfer_record_size = 1 + 36 + 4 + 8 + 2 + 4 + UID_DETAIL_FIX_SIZE; // UID_DETAIL_FIX_SIZE is the biggest one\n//        + std::max({UCN_FIX_SIZE, UID_DETAIL_FIX_SIZE, UID_TRANSFER_FIX_SIZE});\nBC_CONSTEXPR size_t row_record_size = hash_table_record_size<hash_digest>(uid_transfer_record_size);\n\naddress_uid_database::address_uid_database(const path &lookup_filename,\n                                           const path &rows_filename, std::shared_ptr<shared_mutex> mutex)\n    : lookup_file_(lookup_filename, mutex),\n      lookup_header_(lookup_file_, number_buckets),\n      lookup_manager_(lookup_file_, header_size, record_size),\n      lookup_map_(lookup_header_, lookup_manager_),\n      rows_file_(rows_filename, mutex),\n      rows_manager_(rows_file_, 0, row_record_size),\n      rows_list_(rows_manager_),\n      rows_multimap_(lookup_map_, rows_list_)\n{\n}\n\n// Close does not call stop because there is no way to detect thread join.\naddress_uid_database::~address_uid_database()\n{\n    close();\n}\n\n// Create.\n// ----------------------------------------------------------------------------\n\n// Initialize files and start.\nbool address_uid_database::create()\n{\n    // Resize and create require a started file.\n    if (!lookup_file_.start() ||\n        !rows_file_.start())\n        return false;\n\n    // These will throw if insufficient disk space.\n    lookup_file_.resize(initial_lookup_file_size);\n    rows_file_.resize(minimum_records_size);\n\n    if (!lookup_header_.create() ||\n        !lookup_manager_.create() ||\n        !rows_manager_.create())\n        return false;\n\n    // Should not call start after create, already started.\n    return lookup_header_.start() &&\n           lookup_manager_.start() &&\n           rows_manager_.start();\n}\n\n// Startup and shutdown.\n// ----------------------------------------------------------------------------\n\nbool address_uid_database::start()\n{\n    return lookup_file_.start() &&\n           rows_file_.start() &&\n           lookup_header_.start() &&\n           lookup_manager_.start() &&\n           rows_manager_.start();\n}\n\nbool address_uid_database::stop()\n{\n    return lookup_file_.stop() &&\n           rows_file_.stop();\n}\n\nbool address_uid_database::close()\n{\n    return lookup_file_.close() &&\n           rows_file_.close();\n}\n\n// ----------------------------------------------------------------------------\nvoid address_uid_database::store_input(const short_hash &key,\n                                       const output_point &inpoint, uint32_t input_height,\n                                       const input_point &previous, uint32_t timestamp)\n{\n    auto write = [&](memory_ptr data) {\n        auto serial = make_serializer(REMAP_ADDRESS(data));\n        serial.write_byte(static_cast<uint8_t>(point_kind::spend)); // 1\n        serial.write_data(inpoint.to_data());                       // 36\n        serial.write_4_bytes_little_endian(input_height);           // 4\n        serial.write_8_bytes_little_endian(previous.checksum());    // 8\n\n        serial.write_2_bytes_little_endian(0);         // 2 use ucn type fill incase invalid when deser\n        serial.write_4_bytes_little_endian(timestamp); // 4\n        // uid data should be here but input has no these data\n    };\n    rows_multimap_.add_row(key, write);\n}\n\nvoid address_uid_database::delete_old_uid(const short_hash &key)\n{\n    delete_last_row(key);\n}\n\nvoid address_uid_database::delete_last_row(const short_hash &key)\n{\n    rows_multimap_.delete_last_row(key);\n}\n/// get all record of key from database\nbusiness_record::list address_uid_database::get(const short_hash &key,\n                                                size_t from_height, size_t limit) const\n{\n    // Read the height value from the row.\n    const auto read_height = [](uint8_t *data) {\n        static constexpr file_offset height_position = 1 + 36;\n        const auto height_address = data + height_position;\n        return from_little_endian_unsafe<uint32_t>(height_address);\n    };\n\n    // Read a row from the data for the history list.\n    const auto read_row = [](uint8_t *data) {\n        auto deserial = make_deserializer_unsafe(data);\n        return business_record{\n            // output or spend?\n            static_cast<point_kind>(deserial.read_byte()),\n\n            // point\n            point::factory_from_data(deserial),\n\n            // height\n            deserial.read_4_bytes_little_endian(),\n\n            // value or checksum\n            {deserial.read_8_bytes_little_endian()},\n\n            // business_kd;\n            //deserial.read_2_bytes_little_endian(),\n            // timestamp;\n            //deserial.read_4_bytes_little_endian(),\n\n            asset_data::factory_from_data(deserial) // 2 + 4 are in this class\n        };\n    };\n\n    business_record::list result;\n    const auto start = rows_multimap_.lookup(key);\n    const auto records = record_multimap_iterable(rows_list_, start);\n\n    for (const auto index : records)\n    {\n        // Stop once we reach the limit (if specified).\n        if (limit > 0 && result.size() >= limit)\n            break;\n\n        // This obtains a remap safe address pointer against the rows file.\n        const auto record = rows_list_.get(index);\n        const auto address = REMAP_ADDRESS(record);\n\n        // Skip rows below from_height.\n        if (from_height == 0 || read_height(address) <= from_height) // from current block height\n            result.emplace_back(read_row(address));\n    }\n\n    // TODO: we could sort result here.\n    return result;\n}\n/// get all record of key from database\nstd::shared_ptr<std::vector<business_record>> address_uid_database::get(const std::string &address, const std::string &symbol,\n                                                                        size_t start_height, size_t end_height, uint64_t limit, uint64_t page_number) const\n{\n    data_chunk addr_data(address.begin(), address.end());\n    auto key = ripemd160_hash(addr_data);\n\n    // Read the height value from the row.\n    const auto read_height = [](uint8_t *data) {\n        static constexpr file_offset height_position = 1 + 36;\n        const auto height_address = data + height_position;\n        return from_little_endian_unsafe<uint32_t>(height_address);\n    };\n\n    // Read a row from the data for the history list.\n    const auto read_row = [](uint8_t *data) {\n        auto deserial = make_deserializer_unsafe(data);\n        return business_record{\n            // output or spend?\n            static_cast<point_kind>(deserial.read_byte()),\n\n            // point\n            point::factory_from_data(deserial),\n\n            // height\n            deserial.read_4_bytes_little_endian(),\n\n            // value or checksum\n            {deserial.read_8_bytes_little_endian()},\n\n            // business_kd;\n            //deserial.read_2_bytes_little_endian(),\n            // timestamp;\n            //deserial.read_4_bytes_little_endian(),\n\n            asset_data::factory_from_data(deserial) // 2 + 4 are in this class\n        };\n    };\n\n    auto result = std::make_shared<std::vector<business_record>>();\n    const auto start = rows_multimap_.lookup(key);\n    const auto records = record_multimap_iterable(rows_list_, start);\n\n    uint64_t cnt = 0;\n    for (const auto index : records)\n    {\n        // Stop once we reach the limit (if specified).\n        if (limit > 0 && result->size() >= limit)\n            break;\n\n        // This obtains a remap safe address pointer against the rows file.\n        const auto record = rows_list_.get(index);\n        const auto address = REMAP_ADDRESS(record);\n        auto height = read_height(address);\n        std::string uid_symbol;\n\n        // Skip rows below from_height.\n        if (((start_height == 0) && (end_height == 0)) || ((start_height <= height) && (height < end_height)))\n        { // from current block height\n            //result->emplace_back(read_row(address));\n            auto row = read_row(address);\n            if (symbol.empty())\n            { // all utxo\n                cnt++;\n                if ((limit > 0) && (page_number > 0) && ((cnt - 1) / limit) < (page_number - 1))\n                    continue; // skip previous page record\n                result->emplace_back(row);\n            }\n            else\n            { // uid symbol utxo\n                // uid business process\n                uid_symbol = \"\";\n                if (row.data.get_kind_value() == business_kind::uid_register)\n                {\n                    auto transfer = boost::get<uid_detail>(row.data.get_data());\n                    uid_symbol = transfer.get_symbol();\n                }\n                else if (row.data.get_kind_value() == business_kind::uid_transfer)\n                {\n                    auto transfer = boost::get<uid_detail>(row.data.get_data());\n                    uid_symbol = transfer.get_symbol();\n                }\n\n                if (symbol == uid_symbol)\n                {\n                    cnt++;\n                    if ((limit > 0) && (page_number > 0) && ((cnt - 1) / limit) < (page_number - 1))\n                        continue; // skip previous page record\n                    result->emplace_back(row);\n                }\n            }\n        }\n    }\n\n    // TODO: we could sort result here.\n    return result;\n}\n\n/// get all record of key from database\nstd::shared_ptr<std::vector<business_record>> address_uid_database::get(const std::string &address, size_t start_height,\n                                                                        size_t end_height) const\n{\n    data_chunk addr_data(address.begin(), address.end());\n    auto key = ripemd160_hash(addr_data);\n\n    // Read the height value from the row.\n    const auto read_height = [](uint8_t *data) {\n        static constexpr file_offset height_position = 1 + 36;\n        const auto height_address = data + height_position;\n        return from_little_endian_unsafe<uint32_t>(height_address);\n    };\n\n    // Read a row from the data for the history list.\n    const auto read_row = [](uint8_t *data) {\n        auto deserial = make_deserializer_unsafe(data);\n        return business_record{\n            // output or spend?\n            static_cast<point_kind>(deserial.read_byte()),\n\n            // point\n            point::factory_from_data(deserial),\n\n            // height\n            deserial.read_4_bytes_little_endian(),\n\n            // value or checksum\n            {deserial.read_8_bytes_little_endian()},\n\n            // business_kd;\n            //deserial.read_2_bytes_little_endian(),\n            // timestamp;\n            //deserial.read_4_bytes_little_endian(),\n\n            asset_data::factory_from_data(deserial) // 2 + 4 are in this class\n        };\n    };\n\n    auto result = std::make_shared<std::vector<business_record>>();\n    const auto start = rows_multimap_.lookup(key);\n    const auto records = record_multimap_iterable(rows_list_, start);\n\n    for (const auto index : records)\n    {\n        // This obtains a remap safe address pointer against the rows file.\n        const auto record = rows_list_.get(index);\n        const auto address = REMAP_ADDRESS(record);\n        auto height = read_height(address);\n        // Skip rows below from_height.\n        if (((start_height == 0) && (end_height == 0)) || ((start_height <= height) && (height < end_height))) // from current block height\n            result->emplace_back(read_row(address));\n    }\n\n    // TODO: we could sort result here.\n    return result;\n}\n\n/// get all record of key from database\nstd::shared_ptr<std::vector<business_record>> address_uid_database::get(size_t idx) const\n{\n    // Read a row from the data for the history list.\n    const auto read_row = [](uint8_t *data) {\n        auto deserial = make_deserializer_unsafe(data);\n        return business_record{\n            // output or spend?\n            static_cast<point_kind>(deserial.read_byte()),\n\n            // point\n            point::factory_from_data(deserial),\n\n            // height\n            deserial.read_4_bytes_little_endian(),\n\n            // value or checksum\n            {deserial.read_8_bytes_little_endian()},\n\n            // business_kd;\n            //deserial.read_2_bytes_little_endian(),\n            // timestamp;\n            //deserial.read_4_bytes_little_endian(),\n\n            asset_data::factory_from_data(deserial) // 2 + 4 are in this class\n        };\n    };\n\n    auto result = std::make_shared<std::vector<business_record>>();\n    auto sh_idx_vec = rows_multimap_.lookup(idx);\n\n    for (auto each : *sh_idx_vec)\n    {\n\n        const auto records = record_multimap_iterable(rows_list_, each);\n\n        for (const auto index : records)\n        {\n            // This obtains a remap safe address pointer against the rows file.\n            const auto record = rows_list_.get(index);\n            const auto address = REMAP_ADDRESS(record);\n            result->emplace_back(read_row(address));\n        }\n    }\n\n    // TODO: we could sort result here.\n    return result;\n}\n/// get one record by index from row_list\nbusiness_record address_uid_database::get_record(size_t idx) const\n{\n    // Read a row from the data for the history list.\n    const auto read_row = [](uint8_t *data) {\n        auto deserial = make_deserializer_unsafe(data);\n        return business_record{\n            // output or spend?\n            static_cast<point_kind>(deserial.read_byte()),\n\n            // point\n            point::factory_from_data(deserial),\n\n            // height\n            deserial.read_4_bytes_little_endian(),\n\n            // value or checksum\n            {deserial.read_8_bytes_little_endian()},\n\n            // business_kd;\n            //deserial.read_2_bytes_little_endian(),\n            // timestamp;\n            //deserial.read_4_bytes_little_endian(),\n\n            asset_data::factory_from_data(deserial) // 2 + 4 are in this class\n        };\n    };\n\n    // This obtains a remap safe address pointer against the rows file.\n    const auto record = rows_list_.get(idx);\n    const auto address = REMAP_ADDRESS(record);\n    return read_row(address);\n}\nbusiness_history::list address_uid_database::get_business_history(const short_hash &key,\n                                                                  size_t from_height) const\n{\n    business_record::list compact = get(key, from_height, 0);\n\n    business_history::list result;\n\n    // Process and remove all outputs.\n    for (auto output = compact.begin(); output != compact.end();)\n    {\n        if (output->kind == point_kind::output)\n        {\n            business_history row;\n            row.output = output->point;\n            row.output_height = output->height;\n            row.value = output->val_chk_sum.value;\n            row.spend = {null_hash, max_uint32};\n            row.temporary_checksum = output->point.checksum();\n            row.data = output->data;\n            result.emplace_back(row);\n            output = compact.erase(output);\n            continue;\n        }\n\n        ++output;\n    }\n\n    // All outputs have been removed, process the spends.\n    for (const auto &spend : compact)\n    {\n        auto found = false;\n\n        // Update outputs with the corresponding spends.\n        for (auto &row : result)\n        {\n            if (row.temporary_checksum == spend.val_chk_sum.previous_checksum &&\n                row.spend.hash == null_hash)\n            {\n                row.spend = spend.point;\n                row.spend_height = spend.height;\n                found = true;\n                break;\n            }\n        }\n\n        // This will only happen if the history height cutoff comes between\n        // an output and its spend. In this case we return just the spend.\n        if (!found)\n        {\n            business_history row;\n            row.output = {null_hash, max_uint32};\n            row.output_height = max_uint64;\n            row.value = max_uint64;\n            row.spend = spend.point;\n            row.spend_height = spend.height;\n            result.emplace_back(row);\n        }\n    }\n\n    compact.clear();\n\n    // Clear all remaining checksums from unspent rows.\n    for (auto &row : result)\n        if (row.spend.hash == null_hash)\n            row.spend_height = max_uint64;\n\n    // TODO: sort by height and index of output, spend or both in order.\n    return result;\n}\n\n// get address uids in the database(blockchain)\nstd::shared_ptr<std::vector<business_history>> address_uid_database::get_address_business_history(const std::string &address,\n                                                                                                  size_t from_height) const\n{\n    data_chunk data(address.begin(), address.end());\n    auto key = ripemd160_hash(data);\n    business_history::list result = get_business_history(key, from_height);\n    auto unspent = std::make_shared<std::vector<business_history>>();\n\n    for (auto &row : result)\n    {\n        if ((row.spend.hash == null_hash))\n        { // unspent business\n            row.status = business_status::unspent;\n            unspent->emplace_back(row);\n        }\n\n        if (row.output_height != 0 && (row.spend.hash == null_hash || row.spend_height == 0))\n        { // confirmed business\n            row.status = business_status::confirmed;\n            unspent->emplace_back(row);\n        }\n    }\n    return unspent;\n}\n\n// get special kind of uid in the database(blockchain)\n/*\n status -- // 0 -- unspent  1 -- confirmed\n*/\nbusiness_history::list address_uid_database::get_business_history(const std::string &address,\n                                                                  size_t from_height, business_kind kind, uint8_t status) const\n{\n    data_chunk data(address.begin(), address.end());\n    auto key = ripemd160_hash(data);\n    business_history::list result = get_business_history(key, from_height);\n    business_history::list unspent;\n    // uid type check\n    if ((kind != business_kind::uid_register)    // uid_detail\n        && (kind != business_kind::uid_transfer) // uid_transfer\n        && (kind != business_kind::ucn))\n        return unspent;\n\n    for (const auto &row : result)\n    {\n        if (row.data.get_kind_value() != kind)\n            continue;\n\n        if ((row.spend.hash == null_hash) && (status == 0)) // unspent business\n            unspent.emplace_back(row);\n\n        if (row.output_height != 0 && (row.spend.hash == null_hash || row.spend_height == 0) && (status == 1)) // confirmed business\n            unspent.emplace_back(row);\n    }\n    return unspent;\n}\n\n// get special kind of uid in the database(blockchain)\n/*\n status -- // 0 -- unspent  1 -- confirmed\n*/\nbusiness_history::list address_uid_database::get_business_history(const std::string &address,\n                                                                  size_t from_height, business_kind kind, uint32_t time_begin, uint32_t time_end) const\n{\n    data_chunk data(address.begin(), address.end());\n    auto key = ripemd160_hash(data);\n    business_history::list result = get_business_history(key, from_height);\n    business_history::list unspent;\n    // uid type check\n    if ((kind != business_kind::uid_register)    // uid_detail\n        && (kind != business_kind::uid_transfer) // uid_transfer\n        && (kind != business_kind::ucn))\n        return unspent;\n\n    for (auto &row : result)\n    {\n        if (row.data.get_kind_value() != kind || row.data.get_timestamp() < time_begin || row.data.get_timestamp() > time_end)\n            continue;\n\n        if ((row.spend.hash == null_hash))\n        { //0 -- unspent business\n            row.status = 0;\n            unspent.emplace_back(row);\n        }\n\n        if (row.output_height != 0 && (row.spend.hash == null_hash || row.spend_height == 0))\n        { // 1 -- confirmed business\n            row.status = 1;\n            unspent.emplace_back(row);\n        }\n    }\n    return unspent;\n}\n\n// get special kind of uid in the database(blockchain)\nbusiness_address_uid::list address_uid_database::get_uids(const std::string &address,\n                                                          size_t from_height, business_kind kind) const\n{\n    data_chunk data(address.begin(), address.end());\n    auto key = ripemd160_hash(data);\n    business_history::list result = get_business_history(key, from_height);\n    business_address_uid::list unspent;\n    // uid type check\n    if ((kind != business_kind::uid_register)     // uid_detail\n        && (kind != business_kind::uid_transfer)) // uid_transfer\n        return unspent;\n\n    for (const auto &row : result)\n    {\n        if (row.data.get_kind_value() != kind)\n            continue;\n\n        uint8_t status = 0xff;\n        if (row.spend.hash == null_hash)\n            status = 0; // 0 -- unspent  1 -- confirmed\n\n        if (row.output_height != 0 &&\n            (row.spend.hash == null_hash || row.spend_height == 0))\n            status = 1;\n\n        business_address_uid detail;\n        if (row.data.get_kind_value() == business_kind::uid_register) // uid register\n        {\n            auto issue_info = boost::get<uid_detail>(row.data.get_data());\n            detail.detail = issue_info;\n        }\n        else if (row.data.get_kind_value() == business_kind::uid_transfer) //uid transfer\n        {\n            auto issue_info = boost::get<uid_detail>(row.data.get_data());\n            detail.detail = issue_info;\n        }\n\n        detail.address = address; // wallet address\n        detail.status = status;   // 0 -- unspent  1 -- confirmed\n        unspent.emplace_back(detail);\n    }\n    return unspent;\n}\n\n// get all kinds of uid in the database(blockchain)\nbusiness_address_uid::list address_uid_database::get_uids(const std::string &address,\n                                                          size_t from_height, size_t to_height) const\n{\n    data_chunk data(address.begin(), address.end());\n    auto key = ripemd160_hash(data);\n    business_history::list result = get_business_history(key, from_height);\n    business_address_uid::list unspent;\n    for (const auto &row : result)\n    {\n        if ((row.data.get_kind_value() != business_kind::uid_register)     // uid_detail\n            && (row.data.get_kind_value() != business_kind::uid_transfer)) // uid_transfer\n            continue;\n\n        if (address != bc::wallet::payment_address::blackhole_address)\n        {\n            if (row.output_height > to_height)\n            {\n                continue;\n            }\n        }\n\n        uint8_t status = 0xff;\n        if (row.spend.hash == null_hash)\n            status = 0; // 0 -- unspent  1 -- confirmed\n\n        if (row.output_height != 0 &&\n            (row.spend.hash == null_hash || row.spend_height == 0))\n            status = 1;\n\n        business_address_uid detail;\n        if (row.data.get_kind_value() == business_kind::uid_register) // uid register\n        {\n            auto issue_info = boost::get<uid_detail>(row.data.get_data());\n            detail.detail = issue_info;\n        }\n        else if (row.data.get_kind_value() == business_kind::uid_transfer) //uid transfer\n        {\n            auto transfer_info = boost::get<uid_detail>(row.data.get_data());\n            detail.detail = transfer_info;\n        }\n\n        detail.address = address; // wallet address\n        detail.status = status;   // 0 -- unspent  1 -- confirmed\n        unspent.emplace_back(detail);\n    }\n    return unspent;\n}\n\nbusiness_address_message::list address_uid_database::get_messages(const std::string &address,\n                                                                  size_t from_height) const\n{\n    data_chunk data(address.begin(), address.end());\n    auto key = ripemd160_hash(data);\n    business_history::list result = get_business_history(key, from_height);\n    business_address_message::list unspent;\n    for (const auto &row : result)\n    {\n        if ((row.data.get_kind_value() != business_kind::message)) // uid_detail\n            continue;\n\n        uint8_t status = 0xff;\n        if (row.spend.hash == null_hash)\n            status = 0; // 0 -- unspent  1 -- confirmed\n\n        if (row.output_height != 0 &&\n            (row.spend.hash == null_hash || row.spend_height == 0))\n            status = 1;\n\n        business_address_message detail;\n        auto issue_info = boost::get<chain::blockchain_message>(row.data.get_data());\n        detail.msg = issue_info;\n\n        detail.address = address; // wallet address\n        detail.status = status;   // 0 -- unspent  1 -- confirmed\n        unspent.emplace_back(detail);\n    }\n    return unspent;\n}\nvoid address_uid_database::sync()\n{\n    lookup_manager_.sync();\n    rows_manager_.sync();\n}\n\naddress_uid_statinfo address_uid_database::statinfo() const\n{\n    return {\n        lookup_header_.size(),\n        lookup_manager_.count(),\n        rows_manager_.count()};\n}\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/data/database/blockchain_candidate_db.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/data/databases/blockchain_candidate_db.hpp>\n\n#include <cstddef>\n#include <cstdint>\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/memory/memory.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nusing namespace boost::filesystem;\n\nBC_CONSTEXPR size_t number_buckets = 9997; //999983;\nBC_CONSTEXPR size_t header_size = slab_hash_table_header_size(number_buckets);\nBC_CONSTEXPR size_t initial_map_file_size = header_size + minimum_slabs_size;\n\nblockchain_candidate_database::blockchain_candidate_database(const path &map_filename,\n                                                             std::shared_ptr<shared_mutex> mutex)\n    : lookup_file_(map_filename, mutex),\n      lookup_header_(lookup_file_, number_buckets),\n      lookup_manager_(lookup_file_, header_size),\n      lookup_map_(lookup_header_, lookup_manager_)\n{\n}\n\n// Close does not call stop because there is no way to detect thread join.\nblockchain_candidate_database::~blockchain_candidate_database()\n{\n    close();\n}\n\n// Create.\n// ----------------------------------------------------------------------------\n\n// Initialize files and start.\nbool blockchain_candidate_database::create()\n{\n    // Resize and create require a started file.\n    if (!lookup_file_.start())\n        return false;\n\n    // This will throw if insufficient disk space.\n    lookup_file_.resize(initial_map_file_size);\n\n    if (!lookup_header_.create() ||\n        !lookup_manager_.create())\n        return false;\n\n    // Should not call start after create, already started.\n    return lookup_header_.start() &&\n           lookup_manager_.start();\n}\n\n// Startup and shutdown.\n// ----------------------------------------------------------------------------\n\n// Start files and primitives.\nbool blockchain_candidate_database::start()\n{\n    return lookup_file_.start() &&\n           lookup_header_.start() &&\n           lookup_manager_.start();\n}\n\n// Stop files.\nbool blockchain_candidate_database::stop()\n{\n    return lookup_file_.stop();\n}\n\n// Close files.\nbool blockchain_candidate_database::close()\n{\n    return lookup_file_.close();\n}\n\n// ----------------------------------------------------------------------------\n\nvoid blockchain_candidate_database::remove(const hash_digest &hash)\n{\n    DEBUG_ONLY(bool success =)\n    lookup_map_.unlink(hash);\n    BITCOIN_ASSERT(success);\n}\n\nvoid blockchain_candidate_database::sync()\n{\n    lookup_manager_.sync();\n}\n\nstd::shared_ptr<candidate_info> blockchain_candidate_database::get(const hash_digest &hash) const\n{\n    std::shared_ptr<candidate_info> detail(nullptr);\n\n    const auto raw_memory = lookup_map_.find(hash);\n    if (raw_memory)\n    {\n        const auto memory = REMAP_ADDRESS(raw_memory);\n        detail = std::make_shared<candidate_info>();\n        auto deserial = make_deserializer_unsafe(memory);\n        *detail = candidate_info::factory_from_data(deserial);\n    }\n\n    return detail;\n}\n\nstd::shared_ptr<candidate_info::list> blockchain_candidate_database::get_blockchain_candidates() const\n{\n    auto vec_acc = std::make_shared<std::vector<candidate_info>>();\n    for (uint64_t i = 0; i < number_buckets; i++)\n    {\n        auto memo = lookup_map_.find(i);\n        if (memo->size())\n        {\n            const auto action = [&vec_acc](memory_ptr elem) {\n                const auto memory = REMAP_ADDRESS(elem);\n                auto deserial = make_deserializer_unsafe(memory);\n                vec_acc->push_back(candidate_info::factory_from_data(deserial));\n            };\n            std::for_each(memo->begin(), memo->end(), action);\n        }\n    }\n    return vec_acc;\n}\n\n///\nstd::shared_ptr<candidate_info> blockchain_candidate_database::get_register_history(const std::string &candidate_symbol) const\n{\n    std::shared_ptr<candidate_info> candidate_ = nullptr;\n    data_chunk data(candidate_symbol.begin(), candidate_symbol.end());\n    auto key = sha256_hash(data);\n\n    auto memo = lookup_map_.rfind(key);\n    if (memo)\n    {\n        candidate_ = std::make_shared<candidate_info>();\n        const auto memory = REMAP_ADDRESS(memo);\n        auto deserial = make_deserializer_unsafe(memory);\n        *candidate_ = candidate_info::factory_from_data(deserial);\n    }\n\n    return candidate_;\n}\n\n///\nuint64_t blockchain_candidate_database::get_register_height(const std::string &candidate_symbol) const\n{\n    std::shared_ptr<candidate_info> candidate_ = get_register_history(candidate_symbol);\n    if (candidate_)\n        return candidate_->output_height;\n\n    return max_uint64;\n}\n\nvoid blockchain_candidate_database::store(candidate_info &candidate_info)\n{\n    const auto &key_str = candidate_info.candidate.get_symbol();\n    const data_chunk &data = data_chunk(key_str.begin(), key_str.end());\n    const auto key = sha256_hash(data);\n    if (lookup_map_.find(key))\n        remove(key);\n#ifdef UC_DEBUG\n    log::debug(\"blockchain_candidate_database::store\") << candidate_info.candidate.to_string();\n#endif\n\n    // Write block data.\n    const auto sp_size = candidate_info.serialized_size();\n    BITCOIN_ASSERT(sp_size <= max_size_t);\n    const auto value_size = static_cast<size_t>(sp_size);\n\n    auto write = [&candidate_info](memory_ptr data) {\n        auto serial = make_serializer(REMAP_ADDRESS(data));\n        serial.write_data(candidate_info.to_data());\n    };\n    lookup_map_.store(key, write, value_size);\n}\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/data/database/blockchain_token_cert_db.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/data/databases/blockchain_token_cert_db.hpp>\n\n#include <cstddef>\n#include <cstdint>\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/memory/memory.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nusing namespace boost::filesystem;\n\n//BC_CONSTEXPR size_t number_buckets = 999997;\nBC_CONSTEXPR size_t number_buckets = 9997;\nBC_CONSTEXPR size_t header_size = slab_hash_table_header_size(number_buckets);\nBC_CONSTEXPR size_t initial_map_file_size = header_size + minimum_slabs_size;\n\nblockchain_token_cert_database::blockchain_token_cert_database(const path &map_filename,\n                                                               std::shared_ptr<shared_mutex> mutex)\n    : lookup_file_(map_filename, mutex),\n      lookup_header_(lookup_file_, number_buckets),\n      lookup_manager_(lookup_file_, header_size),\n      lookup_map_(lookup_header_, lookup_manager_)\n{\n}\n\n// Close does not call stop because there is no way to detect thread join.\nblockchain_token_cert_database::~blockchain_token_cert_database()\n{\n    close();\n}\n\n// Create.\n// ----------------------------------------------------------------------------\n\n// Initialize files and start.\nbool blockchain_token_cert_database::create()\n{\n    // Resize and create require a started file.\n    if (!lookup_file_.start())\n        return false;\n\n    // This will throw if insufficient disk space.\n    lookup_file_.resize(initial_map_file_size);\n\n    if (!lookup_header_.create() ||\n        !lookup_manager_.create())\n        return false;\n\n    // Should not call start after create, already started.\n    return lookup_header_.start() &&\n           lookup_manager_.start();\n}\n\n// Startup and shutdown.\n// ----------------------------------------------------------------------------\n\n// Start files and primitives.\nbool blockchain_token_cert_database::start()\n{\n    return lookup_file_.start() &&\n           lookup_header_.start() &&\n           lookup_manager_.start();\n}\n\n// Stop files.\nbool blockchain_token_cert_database::stop()\n{\n    return lookup_file_.stop();\n}\n\n// Close files.\nbool blockchain_token_cert_database::close()\n{\n    return lookup_file_.close();\n}\n\n// ----------------------------------------------------------------------------\n\nvoid blockchain_token_cert_database::remove(const hash_digest &hash)\n{\n    DEBUG_ONLY(bool success =)\n    lookup_map_.unlink(hash);\n    BITCOIN_ASSERT(success);\n}\n\nvoid blockchain_token_cert_database::sync()\n{\n    lookup_manager_.sync();\n}\n\nstd::shared_ptr<token_cert> blockchain_token_cert_database::get(const hash_digest &hash) const\n{\n    std::shared_ptr<token_cert> detail(nullptr);\n\n    const auto raw_memory = lookup_map_.find(hash);\n    if (raw_memory)\n    {\n        const auto memory = REMAP_ADDRESS(raw_memory);\n        detail = std::make_shared<token_cert>();\n        auto deserial = make_deserializer_unsafe(memory);\n        detail->from_data(deserial);\n    }\n\n    return detail;\n}\n\nstd::shared_ptr<std::vector<token_cert>> blockchain_token_cert_database::get_blockchain_token_certs() const\n{\n    auto vec_acc = std::make_shared<std::vector<token_cert>>();\n    for (uint64_t i = 0; i < number_buckets; i++)\n    {\n        auto memo = lookup_map_.find(i);\n        if (memo->size())\n        {\n            const auto action = [&](memory_ptr elem) {\n                const auto memory = REMAP_ADDRESS(elem);\n                auto deserial = make_deserializer_unsafe(memory);\n                vec_acc->push_back(token_cert::factory_from_data(deserial));\n            };\n            std::for_each(memo->begin(), memo->end(), action);\n        }\n    }\n    return vec_acc;\n}\n\nvoid blockchain_token_cert_database::store(const token_cert &sp_cert)\n{\n    auto &&key_str = sp_cert.get_key();\n    const data_chunk &data = data_chunk(key_str.begin(), key_str.end());\n    const auto key = sha256_hash(data);\n\n#ifdef UC_DEBUG\n    log::debug(\"blockchain_token_cert_database::store\") << sp_cert.to_string();\n#endif\n\n    // Write block data.\n    const auto sp_size = sp_cert.serialized_size();\n    BITCOIN_ASSERT(sp_size <= max_size_t);\n    const auto value_size = static_cast<size_t>(sp_size);\n\n    auto write = [sp_cert](memory_ptr data) {\n        auto serial = make_serializer(REMAP_ADDRESS(data));\n        serial.write_data(sp_cert.to_data());\n    };\n    lookup_map_.store(key, write, value_size);\n}\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/data/database/blockchain_token_db.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/data/databases/blockchain_token_db.hpp>\n\n#include <cstddef>\n#include <cstdint>\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/memory/memory.hpp>\n\nnamespace libbitcoin {\nnamespace database {\n\nusing namespace boost::filesystem;\n\n//BC_CONSTEXPR size_t number_buckets = 999997;\nBC_CONSTEXPR size_t number_buckets = 9997;\nBC_CONSTEXPR size_t header_size = slab_hash_table_header_size(number_buckets);\nBC_CONSTEXPR size_t initial_map_file_size = header_size + minimum_slabs_size;\n\nblockchain_token_database::blockchain_token_database(const path& map_filename,\n    std::shared_ptr<shared_mutex> mutex)\n  : lookup_file_(map_filename, mutex),\n    lookup_header_(lookup_file_, number_buckets),\n    lookup_manager_(lookup_file_, header_size),\n    lookup_map_(lookup_header_, lookup_manager_)\n{\n}\n\n// Close does not call stop because there is no way to detect thread join.\nblockchain_token_database::~blockchain_token_database()\n{\n    close();\n}\n\n// Create.\n// ----------------------------------------------------------------------------\n\n// Initialize files and start.\nbool blockchain_token_database::create()\n{\n    // Resize and create require a started file.\n    if (!lookup_file_.start())\n        return false;\n\n    // This will throw if insufficient disk space.\n    lookup_file_.resize(initial_map_file_size);\n\n    if (!lookup_header_.create() ||\n        !lookup_manager_.create())\n        return false;\n\n    // Should not call start after create, already started.\n    return\n        lookup_header_.start() &&\n        lookup_manager_.start();\n}\n\n// Startup and shutdown.\n// ----------------------------------------------------------------------------\n\n// Start files and primitives.\nbool blockchain_token_database::start()\n{\n    return\n        lookup_file_.start() &&\n        lookup_header_.start() &&\n        lookup_manager_.start();\n}\n\n// Stop files.\nbool blockchain_token_database::stop()\n{\n    return lookup_file_.stop();\n}\n\n// Close files.\nbool blockchain_token_database::close()\n{\n    return lookup_file_.close();\n}\n\n// ----------------------------------------------------------------------------\n\nvoid blockchain_token_database::remove(const hash_digest& hash)\n{\n    DEBUG_ONLY(bool success =) lookup_map_.unlink(hash);\n    BITCOIN_ASSERT(success);\n}\n\nvoid blockchain_token_database::sync()\n{\n    lookup_manager_.sync();\n}\n\nstd::shared_ptr<blockchain_token> blockchain_token_database::get(const hash_digest& hash) const\n{\n    std::shared_ptr<blockchain_token> detail(nullptr);\n\n    const auto raw_memory = lookup_map_.rfind(hash);\n    if(raw_memory) {\n        const auto memory = REMAP_ADDRESS(raw_memory);\n        detail = std::make_shared<blockchain_token>();\n        auto deserial = make_deserializer_unsafe(memory);\n        detail->from_data(deserial);\n    }\n\n    return detail;\n}\n\nuint64_t blockchain_token_database::get_token_volume(const std::string& name) const\n{\n    uint64_t volume = 0;\n    const auto hash = sha256_hash(data_chunk(name.begin(), name.end()));\n    auto memo = lookup_map_.finds(hash);\n    const auto action = [&](memory_ptr elem)\n    {\n        const auto memory = REMAP_ADDRESS(elem);\n        auto deserial = make_deserializer_unsafe(memory);\n        auto& token = blockchain_token::factory_from_data(deserial).get_token();\n        volume += token.get_maximum_supply();\n    };\n    std::for_each(memo.begin(), memo.end(), action);\n\n    return volume;\n}\n\n///\nstd::shared_ptr<std::vector<blockchain_token>> blockchain_token_database::get_blockchain_tokens(const std::string& token_symbol) const\n{\n    if (!token_symbol.empty()) {\n        return get_token_history(token_symbol);\n    }\n\n    auto vec_acc = std::make_shared<std::vector<blockchain_token>>();\n    uint64_t i = 0;\n    for( i = 0; i < number_buckets; i++ ) {\n        auto memo = lookup_map_.find(i);\n        //log::debug(\"get_wallets size=\")<<memo->size();\n        if (memo->size()) {\n            const auto action = [&](memory_ptr elem)\n            {\n                const auto memory = REMAP_ADDRESS(elem);\n                auto deserial = make_deserializer_unsafe(memory);\n                vec_acc->push_back(blockchain_token::factory_from_data(deserial));\n            };\n            std::for_each(memo->begin(), memo->end(), action);\n        }\n    }\n    return vec_acc;\n}\n\n/// \nstd::shared_ptr<blockchain_token::list> blockchain_token_database::get_token_history(const std::string & token_symbol) const\n{\n    std::shared_ptr<blockchain_token::list> blockchain_token_ = std::make_shared<blockchain_token::list>();\n    data_chunk data(token_symbol.begin(), token_symbol.end());\n    auto key = sha256_hash(data);\n\n    auto token_vec = lookup_map_.finds(key);\n    for(auto memo : token_vec){\n        if(memo)\n        {\n            const auto memory = REMAP_ADDRESS(memo);\n            auto deserial = make_deserializer_unsafe(memory);        \n            blockchain_token_->emplace_back(blockchain_token::factory_from_data(deserial));\n        }\n    }\n\n    return blockchain_token_;\n}\n\n/// \nstd::shared_ptr<blockchain_token> blockchain_token_database::get_register_history(const std::string & token_symbol) const\n{\n    std::shared_ptr<blockchain_token> blockchain_token_ = nullptr;\n    data_chunk data(token_symbol.begin(), token_symbol.end());\n    auto key = sha256_hash(data);\n\n    auto memo = lookup_map_.rfind(key);\n    if(memo)\n    {\n        blockchain_token_ = std::make_shared<blockchain_token>();\n        const auto memory = REMAP_ADDRESS(memo);\n        auto deserial = make_deserializer_unsafe(memory);\n        blockchain_token_->from_data(deserial);\n    }\n\n    return blockchain_token_;\n}\n\n///\nuint64_t blockchain_token_database::get_register_height(const std::string & token_symbol) const\n{\n    std::shared_ptr<blockchain_token> blockchain_token_ = get_register_history(token_symbol);\n    if(blockchain_token_)\n        return blockchain_token_->get_height();\n    return max_uint64;\n}\n\nvoid blockchain_token_database::store(const hash_digest& hash, const blockchain_token& sp_detail)\n{\n    // Write block data.\n    const auto key = hash;\n    const auto sp_size = sp_detail.serialized_size();\n#ifdef UC_DEBUG\n    log::debug(\"token_database::store\") << sp_detail.to_string();\n#endif\n    BITCOIN_ASSERT(sp_size <= max_size_t);\n    const auto value_size = static_cast<size_t>(sp_size);\n\n    auto write = [&sp_detail](memory_ptr data)\n    {\n        auto serial = make_serializer(REMAP_ADDRESS(data));\n        serial.write_data(sp_detail.to_data());\n    };\n    lookup_map_.store(key, write, value_size);\n}\n\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/data/database/blockchain_uid_db.cpp",
    "content": "/** \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/data/databases/blockchain_uid_db.hpp>\n\n#include <cstddef>\n#include <cstdint>\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/memory/memory.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nusing namespace boost::filesystem;\n\n//BC_CONSTEXPR size_t number_buckets = 999997;\nBC_CONSTEXPR size_t number_buckets = 9997;\nBC_CONSTEXPR size_t header_size = slab_hash_table_header_size(number_buckets);\nBC_CONSTEXPR size_t initial_map_file_size = header_size + minimum_slabs_size;\n\nblockchain_uid_database::blockchain_uid_database(const path &map_filename,\n                                                 std::shared_ptr<shared_mutex> mutex)\n    : lookup_file_(map_filename, mutex),\n      lookup_header_(lookup_file_, number_buckets),\n      lookup_manager_(lookup_file_, header_size),\n      lookup_map_(lookup_header_, lookup_manager_)\n{\n}\n\n// Close does not call stop because there is no way to detect thread join.\nblockchain_uid_database::~blockchain_uid_database()\n{\n    close();\n}\n\n// Create.\n// ----------------------------------------------------------------------------\n\n// Initialize files and start.\nbool blockchain_uid_database::create()\n{\n    // Resize and create require a started file.\n    if (!lookup_file_.start())\n        return false;\n\n    // This will throw if insufficient disk space.\n    lookup_file_.resize(initial_map_file_size);\n\n    if (!lookup_header_.create() ||\n        !lookup_manager_.create())\n        return false;\n\n    // Should not call start after create, already started.\n    return lookup_header_.start() &&\n           lookup_manager_.start();\n}\n\n// Startup and shutdown.\n// ----------------------------------------------------------------------------\n\n// Start files and primitives.\nbool blockchain_uid_database::start()\n{\n    return lookup_file_.start() &&\n           lookup_header_.start() &&\n           lookup_manager_.start();\n}\n\n// Stop files.\nbool blockchain_uid_database::stop()\n{\n    return lookup_file_.stop();\n}\n\n// Close files.\nbool blockchain_uid_database::close()\n{\n    return lookup_file_.close();\n}\n\n// ----------------------------------------------------------------------------\n\nvoid blockchain_uid_database::remove(const hash_digest &hash)\n{\n    DEBUG_ONLY(bool success =)\n    lookup_map_.unlink(hash);\n    BITCOIN_ASSERT(success);\n}\n\nvoid blockchain_uid_database::sync()\n{\n    lookup_manager_.sync();\n}\n\nstd::shared_ptr<blockchain_uid> blockchain_uid_database::get(const hash_digest &hash) const\n{\n    std::shared_ptr<blockchain_uid> detail(nullptr);\n\n    const auto raw_memory = lookup_map_.find(hash);\n    if (raw_memory)\n    {\n        const auto memory = REMAP_ADDRESS(raw_memory);\n        detail = std::make_shared<blockchain_uid>();\n        auto deserial = make_deserializer_unsafe(memory);\n        detail->from_data(deserial);\n    }\n\n    return detail;\n}\n\nstd::shared_ptr<std::vector<blockchain_uid>> blockchain_uid_database::get_history_uids(const hash_digest &hash) const\n{\n    auto uid_details = std::make_shared<std::vector<blockchain_uid>>();\n\n    const auto raw_memory_vec = lookup_map_.finds(hash);\n    for (const auto &raw_memory : raw_memory_vec)\n    {\n        if (raw_memory)\n        {\n            const auto memory = REMAP_ADDRESS(raw_memory);\n            auto deserial = make_deserializer_unsafe(memory);\n            uid_details->emplace_back(blockchain_uid::factory_from_data(deserial));\n        }\n    }\n\n    return uid_details;\n}\n\n///\nstd::shared_ptr<std::vector<blockchain_uid>> blockchain_uid_database::get_blockchain_uids() const\n{\n    auto vec_acc = std::make_shared<std::vector<blockchain_uid>>();\n    uint64_t i = 0;\n    for (i = 0; i < number_buckets; i++)\n    {\n        auto memo = lookup_map_.find(i);\n        //log::debug(\"get_wallets size=\")<<memo->size();\n        if (memo->size())\n        {\n            const auto action = [&](memory_ptr elem) {\n                const auto memory = REMAP_ADDRESS(elem);\n                auto deserial = make_deserializer_unsafe(memory);\n                vec_acc->push_back(blockchain_uid::factory_from_data(deserial));\n            };\n            std::for_each(memo->begin(), memo->end(), action);\n        }\n    }\n    return vec_acc;\n}\n\n///\nstd::shared_ptr<blockchain_uid> blockchain_uid_database::get_register_history(const std::string &uid_symbol) const\n{\n    std::shared_ptr<blockchain_uid> blockchain_uid_ = nullptr;\n    data_chunk data(uid_symbol.begin(), uid_symbol.end());\n    auto key = sha256_hash(data);\n\n    auto memo = lookup_map_.rfind(key);\n    if (memo)\n    {\n        blockchain_uid_ = std::make_shared<blockchain_uid>();\n        const auto memory = REMAP_ADDRESS(memo);\n        auto deserial = make_deserializer_unsafe(memory);\n        blockchain_uid_->from_data(deserial);\n    }\n\n    return blockchain_uid_;\n}\n\nuint64_t blockchain_uid_database::get_register_height(const std::string &uid_symbol) const\n{\n    std::shared_ptr<blockchain_uid> blockchain_uid_ = get_register_history(uid_symbol);\n    if (blockchain_uid_)\n        return blockchain_uid_->get_height();\n\n    return max_uint64;\n}\n\nvoid blockchain_uid_database::store(const hash_digest &hash, const blockchain_uid &sp_detail)\n{\n    // Write block data.\n    const auto key = hash;\n\n    //cannot remove old address,instead of update its status\n    update_address_status(key, blockchain_uid::address_history);\n\n    const auto sp_size = sp_detail.serialized_size();\n#ifdef UC_DEBUG\n    log::debug(\"uid_database::store\") << sp_detail.to_string();\n#endif\n    BITCOIN_ASSERT(sp_size <= max_size_t);\n    const auto value_size = static_cast<size_t>(sp_size);\n\n    auto write = [&sp_detail](memory_ptr data) {\n        auto serial = make_serializer(REMAP_ADDRESS(data));\n        serial.write_data(sp_detail.to_data());\n    };\n    lookup_map_.store(key, write, value_size);\n}\n\nstd::shared_ptr<blockchain_uid> blockchain_uid_database::update_address_status(const hash_digest &hash, uint32_t status)\n{\n    std::shared_ptr<blockchain_uid> detail = nullptr;\n\n    const auto raw_memory = lookup_map_.find(hash);\n    if (raw_memory)\n    {\n        detail = std::make_shared<blockchain_uid>();\n        if (detail)\n        {\n            const auto memory = REMAP_ADDRESS(raw_memory);\n            auto deserial = make_deserializer_unsafe(memory);\n            detail->from_data(deserial);\n            if (detail->get_status() != status)\n            {\n                //update status and serializer\n                detail->set_status(status);\n                auto serial = make_serializer(memory);\n                serial.write_data(detail->to_data());\n            }\n        }\n    }\n\n    return detail;\n}\n\nstd::shared_ptr<std::vector<blockchain_uid>> blockchain_uid_database::getuids_from_address_history(const std::string &address,\n                                                                                                   const uint64_t &fromheight, const uint64_t &toheight) const\n{\n    auto vec_acc = std::make_shared<std::vector<blockchain_uid>>();\n    uint64_t i = 0;\n    for (i = 0; i < number_buckets; i++)\n    {\n        auto sp_memo = lookup_map_.find(i);\n        for (auto &elem : *sp_memo)\n        {\n            const auto memory = REMAP_ADDRESS(elem);\n            auto deserial = make_deserializer_unsafe(memory);\n            blockchain_uid blockchain_uid_ = blockchain_uid::factory_from_data(deserial);\n\n            const auto height = blockchain_uid_.get_height();\n            const auto uid_address = blockchain_uid_.get_uid().get_address();\n\n            if (uid_address == address)\n            {\n                if ((height >= fromheight && height <= toheight) || (height == max_uint32 && address == bc::wallet::payment_address::blackhole_address))\n                {\n                    vec_acc->emplace_back(blockchain_uid_);\n                }\n            }\n        }\n    }\n\n    std::sort(vec_acc->begin(), vec_acc->end(), [](blockchain_uid &first, blockchain_uid &second) {\n        return first.get_height() < second.get_height();\n    });\n    return vec_acc;\n}\n\nstd::shared_ptr<blockchain_uid> blockchain_uid_database::pop_uid_transfer(const hash_digest &hash)\n{\n    lookup_map_.unlink(hash);\n    return update_address_status(hash, blockchain_uid::address_current);\n}\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/data/database/candidate_history_db.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of ucd.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/data/databases/candidate_history_db.hpp>\n\n#include <cstdint>\n#include <cstddef>\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/memory/memory.hpp>\n#include <UChain/database/primitives/record_multimap_iterable.hpp>\n#include <UChain/database/primitives/record_multimap_iterator.hpp>\n\n#define LOG_CANDIDATE_HISTORY_DATABASE \"candidate_history_database\"\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nusing namespace boost::filesystem;\nusing namespace bc::chain;\n\nnamespace\n{\n// Read the height value from the row.\nuint32_t read_height(uint8_t *data)\n{\n    return from_little_endian_unsafe<uint32_t>(data);\n};\n\n// Read the height value from the row.\nuint32_t read_time(uint8_t *data)\n{\n    return from_little_endian_unsafe<uint32_t>(data + 4);\n};\n\n// Read a row from the data for the history list.\ncandidate_info read_row(uint8_t *data)\n{\n    auto deserial = make_deserializer_unsafe(data);\n    return candidate_info::factory_from_data(deserial);\n};\n} // namespace\n\nBC_CONSTEXPR size_t number_buckets = 99999989;\nBC_CONSTEXPR size_t header_size = record_hash_table_header_size(number_buckets);\nBC_CONSTEXPR size_t initial_lookup_file_size = header_size + minimum_records_size;\n\nBC_CONSTEXPR size_t record_size = hash_table_multimap_record_size<short_hash>();\n\nBC_CONSTEXPR size_t candidate_transfer_record_size = TOKEN_CANDIDATE_INFO_FIX_SIZE;\nBC_CONSTEXPR size_t row_record_size = hash_table_record_size<hash_digest>(candidate_transfer_record_size);\n\ncandidate_history_database::candidate_history_database(const path &lookup_filename,\n                                                       const path &rows_filename, std::shared_ptr<shared_mutex> mutex)\n    : lookup_file_(lookup_filename, mutex),\n      lookup_header_(lookup_file_, number_buckets),\n      lookup_manager_(lookup_file_, header_size, record_size),\n      lookup_map_(lookup_header_, lookup_manager_),\n      rows_file_(rows_filename, mutex),\n      rows_manager_(rows_file_, 0, row_record_size),\n      rows_list_(rows_manager_),\n      rows_multimap_(lookup_map_, rows_list_)\n{\n}\n\n// Close does not call stop because there is no way to detect thread join.\ncandidate_history_database::~candidate_history_database()\n{\n    close();\n}\n\n// Create.\n// ----------------------------------------------------------------------------\n\n// Initialize files and start.\nbool candidate_history_database::create()\n{\n    // Resize and create require a started file.\n    if (!lookup_file_.start() ||\n        !rows_file_.start())\n        return false;\n\n    // These will throw if insufficient disk space.\n    lookup_file_.resize(initial_lookup_file_size);\n    rows_file_.resize(minimum_records_size);\n\n    if (!lookup_header_.create() ||\n        !lookup_manager_.create() ||\n        !rows_manager_.create())\n        return false;\n\n    // Should not call start after create, already started.\n    return lookup_header_.start() &&\n           lookup_manager_.start() &&\n           rows_manager_.start();\n}\n\n// Startup and shutdown.\n// ----------------------------------------------------------------------------\n\nbool candidate_history_database::start()\n{\n    return lookup_file_.start() &&\n           rows_file_.start() &&\n           lookup_header_.start() &&\n           lookup_manager_.start() &&\n           rows_manager_.start();\n}\n\nbool candidate_history_database::stop()\n{\n    return lookup_file_.stop() &&\n           rows_file_.stop();\n}\n\nbool candidate_history_database::close()\n{\n    return lookup_file_.close() &&\n           rows_file_.close();\n}\n\nvoid candidate_history_database::sync()\n{\n    lookup_manager_.sync();\n    rows_manager_.sync();\n}\n\ncandidate_history_statinfo candidate_history_database::statinfo() const\n{\n    return {\n        lookup_header_.size(),\n        lookup_manager_.count(),\n        rows_manager_.count()};\n}\n\n// ----------------------------------------------------------------------------\nvoid candidate_history_database::store(const candidate_info &candidate_info)\n{\n    const auto &key_str = candidate_info.candidate.get_symbol();\n    const data_chunk &data = data_chunk(key_str.begin(), key_str.end());\n    const auto key = ripemd160_hash(data);\n\n    auto write = [&candidate_info](memory_ptr data) {\n        auto serial = make_serializer(REMAP_ADDRESS(data));\n        serial.write_data(candidate_info.to_short_data());\n    };\n    rows_multimap_.add_row(key, write);\n}\n\nvoid candidate_history_database::delete_last_row(const short_hash &key)\n{\n    rows_multimap_.delete_last_row(key);\n}\n\nstd::shared_ptr<candidate_info> candidate_history_database::get(const short_hash &key) const\n{\n    const auto start = rows_multimap_.lookup(key);\n    const auto records = record_multimap_iterable(rows_list_, start);\n\n    for (const auto index : records)\n    {\n        // This obtains a remap safe address pointer against the rows file.\n        const auto record = rows_list_.get(index);\n        const auto address = REMAP_ADDRESS(record);\n\n        return std::make_shared<candidate_info>(read_row(address));\n    }\n\n    return nullptr;\n}\n\nstd::shared_ptr<candidate_info::list> candidate_history_database::get_history_candidates_by_height(\n    const short_hash &key, uint32_t start_height, uint32_t end_height,\n    uint64_t limit, uint64_t page_number) const\n{\n    // use map to sort by height, decreasely\n    std::map<uint32_t, candidate_info, std::greater<uint32_t>> height_candidate_map;\n\n    const auto start = rows_multimap_.lookup(key);\n    const auto records = record_multimap_iterable(rows_list_, start);\n\n    uint64_t cnt = 0;\n    for (const auto index : records)\n    {\n        // Stop once we reach the limit (if specified).\n        if ((limit > 0) && (height_candidate_map.size() >= limit))\n        {\n            break;\n        }\n\n        // This obtains a remap safe address pointer against the rows file.\n        const auto record = rows_list_.get(index);\n        const auto address = REMAP_ADDRESS(record);\n\n        const auto height = read_height(address);\n\n        // Stop once we reach the end (if specified).\n        if ((end_height > 0) && (height > end_height))\n        {\n            break;\n        }\n\n        // Skip rows below from_height.\n        if (height < start_height)\n        {\n            continue;\n        }\n\n        cnt++;\n        if ((limit > 0) && (page_number > 0) && ((cnt - 1) / limit) < (page_number - 1))\n        {\n            continue; // skip previous page record\n        }\n\n        auto row = read_row(address);\n        height_candidate_map[height] = row;\n    }\n\n    auto result = std::make_shared<candidate_info::list>();\n    for (const auto &pair : height_candidate_map)\n    {\n        result->emplace_back(std::move(pair.second));\n    }\n    return result;\n}\n\nstd::shared_ptr<candidate_info::list> candidate_history_database::get_history_candidates_by_time(\n    const short_hash &key, uint32_t time_begin, uint32_t time_end,\n    uint64_t limit, uint64_t page_number) const\n{\n    // use map to sort by time, decreasely\n    std::map<uint32_t, candidate_info, std::greater<uint32_t>> time_candidate_map;\n\n    const auto start = rows_multimap_.lookup(key);\n    const auto records = record_multimap_iterable(rows_list_, start);\n\n    uint64_t cnt = 0;\n    for (const auto index : records)\n    {\n        // Stop once we reach the limit (if specified).\n        if ((limit > 0) && (time_candidate_map.size() >= limit))\n        {\n            break;\n        }\n\n        // This obtains a remap safe address pointer against the rows file.\n        const auto record = rows_list_.get(index);\n        const auto address = REMAP_ADDRESS(record);\n\n        const auto time = read_time(address);\n\n        // Stop once we reach the end (if specified).\n        if ((time_end > 0) && (time > time_end))\n        {\n            break;\n        }\n\n        // Skip rows below from_height.\n        if (time < time_begin)\n        {\n            continue;\n        }\n\n        cnt++;\n        if ((limit > 0) && (page_number > 0) && ((cnt - 1) / limit) < (page_number - 1))\n        {\n            continue; // skip previous page record\n        }\n\n        auto row = read_row(address);\n        time_candidate_map[time] = row;\n    }\n\n    auto result = std::make_shared<candidate_info::list>();\n    for (const auto &pair : time_candidate_map)\n    {\n        result->emplace_back(std::move(pair.second));\n    }\n    return result;\n}\n\nbool candidate_history_database::update_address_status(const candidate_info &candidate_info, uint8_t status)\n{\n    const auto &key_str = candidate_info.candidate.get_symbol();\n    const data_chunk &data = data_chunk(key_str.begin(), key_str.end());\n    const auto key = ripemd160_hash(data);\n\n    const auto start = rows_multimap_.lookup(key);\n    const auto records = record_multimap_iterable(rows_list_, start);\n    const auto record = rows_list_.get(start);\n\n    if (record)\n    {\n        const auto address = REMAP_ADDRESS(record);\n        auto row = read_row(address);\n        if (row.candidate.get_status() != status)\n        {\n            //update status and serializer\n            row.candidate.set_status(status);\n            auto serial = make_serializer(address);\n            serial.write_data(row.to_data());\n        }\n        return true;\n    }\n\n    return false;\n}\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/data/database/token_db.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS) \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/data/databases/token_db.hpp>\n\n#include <cstddef>\n#include <cstdint>\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/memory/memory.hpp>\n//#include <UChain/database/result/token_result.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nusing namespace boost::filesystem;\n\ntoken_database::token_database(const path &map_filename,\n                               std::shared_ptr<shared_mutex> mutex)\n    : base_database(map_filename, mutex)\n{\n}\n\n// Close does not call stop because there is no way to detect thread join.\ntoken_database::~token_database()\n{\n    close();\n}\n\ntoken_result token_database::get_token_result(const hash_digest &hash) const\n{\n    const auto memory = get(hash);\n    return token_result(memory);\n}\n///\nstd::shared_ptr<std::vector<token_detail>> token_database::get_token_details() const\n{\n    auto vec_acc = std::make_shared<std::vector<token_detail>>();\n    uint64_t i = 0;\n    for (i = 0; i < get_bucket_count(); i++)\n    {\n        auto memo = lookup_map_.find(i);\n        if (memo->size())\n        {\n            const auto action = [&](memory_ptr elem) {\n                const auto memory = REMAP_ADDRESS(elem);\n                auto deserial = make_deserializer_unsafe(memory);\n                vec_acc->push_back(token_detail::factory_from_data(deserial));\n            };\n            std::for_each(memo->begin(), memo->end(), action);\n        }\n    }\n    return vec_acc;\n}\n\nvoid token_database::store(const hash_digest &hash, const token_detail &sp_detail)\n{\n    // Write block data.\n    const auto key = hash;\n    const auto sp_size = sp_detail.serialized_size();\n#ifdef UC_DEBUG\n    log::debug(\"token_database::store\") << sp_detail.to_string();\n#endif\n    BITCOIN_ASSERT(sp_size <= max_size_t);\n    const auto value_size = static_cast<size_t>(sp_size);\n\n    auto write = [&sp_detail](memory_ptr data) {\n        auto serial = make_serializer(REMAP_ADDRESS(data));\n        serial.write_data(sp_detail.to_data());\n    };\n    //get_lookup_map().store(key, write, value_size);\n    lookup_map_.store(key, write, value_size);\n}\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/data/database/wallet_address_db.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS) \n *\n * This file is part of ucd.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/data/databases/wallet_address_db.hpp>\n#include <UChainService/txs/wallet/wallet_address.hpp>\n\n#include <cstdint>\n#include <cstddef>\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/memory/memory.hpp>\n#include <UChain/database/primitives/record_multimap_iterable.hpp>\n#include <UChain/database/primitives/record_multimap_iterator.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nusing namespace boost::filesystem;\nusing namespace bc::chain;\n\nBC_CONSTEXPR size_t number_buckets = 9997;\nBC_CONSTEXPR size_t header_size = record_hash_table_header_size(number_buckets);\nBC_CONSTEXPR size_t initial_lookup_file_size = header_size + minimum_records_size;\n\nBC_CONSTEXPR size_t record_size = hash_table_multimap_record_size<short_hash>();\n\nBC_CONSTEXPR size_t address_db_size = ADDRESS_NAME_FIX_SIZE + ADDRESS_PRV_KEY_FIX_SIZE + ADDRESS_PUB_KEY_FIX_SIZE + ADDRESS_HD_INDEX_FIX_SIZE + ADDRESS_BALANCE_FIX_SIZE + ADDRESS_ALIAS_FIX_SIZE + ADDRESS_ADDRESS_FIX_SIZE + ADDRESS_STATUS_FIX_SIZE; // 222 -- refer wallet_address.hpp\nBC_CONSTEXPR size_t row_record_size = hash_table_record_size<hash_digest>(address_db_size);\n\nwallet_address_database::wallet_address_database(const path &lookup_filename,\n                                                 const path &rows_filename, std::shared_ptr<shared_mutex> mutex)\n    : lookup_file_(lookup_filename, mutex),\n      lookup_header_(lookup_file_, number_buckets),\n      lookup_manager_(lookup_file_, header_size, record_size),\n      lookup_map_(lookup_header_, lookup_manager_),\n      rows_file_(rows_filename, mutex),\n      rows_manager_(rows_file_, 0, row_record_size),\n      rows_list_(rows_manager_),\n      rows_multimap_(lookup_map_, rows_list_)\n{\n}\n\n// Close does not call stop because there is no way to detect thread join.\nwallet_address_database::~wallet_address_database()\n{\n    close();\n}\n\n// Create.\n// ----------------------------------------------------------------------------\n\n// Initialize files and start.\nbool wallet_address_database::create()\n{\n    // Resize and create require a started file.\n    if (!lookup_file_.start() ||\n        !rows_file_.start())\n        return false;\n\n    // These will throw if insufficient disk space.\n    lookup_file_.resize(initial_lookup_file_size);\n    rows_file_.resize(minimum_records_size);\n\n    if (!lookup_header_.create() ||\n        !lookup_manager_.create() ||\n        !rows_manager_.create())\n        return false;\n\n    // Should not call start after create, already started.\n    return lookup_header_.start() &&\n           lookup_manager_.start() &&\n           rows_manager_.start();\n}\n\n// Startup and shutdown.\n// ----------------------------------------------------------------------------\n\nbool wallet_address_database::start()\n{\n    return lookup_file_.start() &&\n           rows_file_.start() &&\n           lookup_header_.start() &&\n           lookup_manager_.start() &&\n           rows_manager_.start();\n}\n\nbool wallet_address_database::stop()\n{\n    return lookup_file_.stop() &&\n           rows_file_.stop();\n}\n\nbool wallet_address_database::close()\n{\n    return lookup_file_.close() &&\n           rows_file_.close();\n}\n\n// ----------------------------------------------------------------------------\n\nvoid wallet_address_database::store(const short_hash &key, const wallet_address &address)\n{\n    const auto address_data = address.to_data();\n\n    const auto check_store = [this, &key, &address, &address_data]() {\n        auto address_vec = get(key);\n        auto pos = std::find_if(address_vec.begin(), address_vec.end(),\n                                [&address](const wallet_address &elem) {\n                                    return (elem.get_address() == address.get_address());\n                                });\n\n        if (pos == address_vec.end())\n        { // new item\n            return true;\n        }\n\n        if (pos->to_data() == address_data)\n        {\n            // don't store duplicate data\n            return false;\n        }\n\n        // remove old record\n        delete_last_row(key);\n        sync();\n        return true;\n    };\n\n    if (check_store())\n    {\n        // actually store address\n        auto write = [&address_data](memory_ptr data) {\n            auto serial = make_serializer(REMAP_ADDRESS(data));\n            serial.write_data(address_data);\n        };\n        rows_multimap_.add_row(key, write);\n    }\n}\n\nvoid wallet_address_database::safe_store(const short_hash &key, const wallet_address &address)\n{\n    // actually store\n    auto write = [&address](memory_ptr data) {\n        auto serial = make_serializer(REMAP_ADDRESS(data));\n        serial.write_data(address.to_data());\n    };\n    rows_multimap_.add_row(key, write);\n}\n\nvoid wallet_address_database::delete_last_row(const short_hash &key)\n{\n    rows_multimap_.delete_last_row(key);\n}\n\nwallet_address::list wallet_address_database::get(const short_hash &key) const\n{\n    // Read a row from the data for the wallet_address list.\n    const auto read_row = [](uint8_t *data) {\n        auto deserial = make_deserializer_unsafe(data);\n        return wallet_address::factory_from_data(deserial);\n    };\n\n    wallet_address::list result;\n    const auto start = rows_multimap_.lookup(key);\n    const auto records = record_multimap_iterable(rows_list_, start);\n\n    for (const auto index : records)\n    {\n        // This obtains a remap safe address pointer against the rows file.\n        const auto record = rows_list_.get(index);\n        const auto address = REMAP_ADDRESS(record);\n\n        result.emplace_back(read_row(address));\n    }\n\n    // TODO: we could sort result here.\n    return result;\n}\n\nstd::shared_ptr<wallet_address> wallet_address_database::get(const short_hash &key, const std::string &address) const\n{\n    std::shared_ptr<wallet_address> addr(nullptr);\n    wallet_address::list result = get(key);\n    for (auto element : result)\n    {\n        if (element.get_address() == address)\n        {\n            addr = std::make_shared<wallet_address>(element);\n            break;\n        }\n    }\n\n    return addr;\n}\nvoid wallet_address_database::sync()\n{\n    lookup_manager_.sync();\n    rows_manager_.sync();\n}\n\nwallet_address_statinfo wallet_address_database::statinfo() const\n{\n    return {\n        lookup_header_.size(),\n        lookup_manager_.count(),\n        rows_manager_.count()};\n}\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/data/database/wallet_db.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS) \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/data/databases/wallet_db.hpp>\n\n#include <cstddef>\n#include <cstdint>\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/memory/memory.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nusing namespace boost::filesystem;\n\nnamespace\n{\n// copy from block_chain_imp.cpp\nhash_digest get_hash(const std::string &str)\n{\n    data_chunk data(str.begin(), str.end());\n    return sha256_hash(data);\n}\n} // namespace\n\nwallet_database::wallet_database(const path &map_filename,\n                                 std::shared_ptr<shared_mutex> mutex)\n    : base_database(map_filename, mutex)\n{\n}\n\n// Close does not call stop because there is no way to detect thread join.\nwallet_database::~wallet_database()\n{\n    close();\n}\n\nvoid wallet_database::set_admin(const std::string &name, const std::string &passwd)\n{\n    // create admin wallet if not exists\n    const auto hash = get_hash(name);\n    if (nullptr == get(hash))\n    {\n        libbitcoin::chain::wallet acc;\n        acc.set_name(name);\n        acc.set_passwd(passwd);\n        acc.set_priority(wallet_priority::administrator);\n        store(acc);\n        sync();\n    }\n}\n\nvoid wallet_database::store(const libbitcoin::chain::wallet &wallet)\n{\n    const auto &name = wallet.get_name();\n    const auto hash = get_hash(name);\n    const auto wallet_data = wallet.to_data();\n\n    const auto check_store = [this, &name, &hash, &wallet_data]() {\n        auto &&result = get_wallet_result(hash);\n        if (!result)\n        {\n            return true;\n        }\n\n        auto detail = result.get_wallet_detail();\n        if (!detail)\n        {\n            return true;\n        }\n\n        // wallet exist -- check duplicate\n        if (detail->to_data() == wallet_data)\n        {\n            // if completely same, no need to store the same data.\n            return false;\n        }\n\n        // wallet exist -- check hash conflict\n        if (detail->get_name() != name)\n        {\n            log::error(\"wallet_database\")\n                << detail->get_name()\n                << \" is already exist and has same hash \"\n                << encode_hash(hash) << \" with this name \"\n                << name;\n            // for security reason, don't store wallet with hash conflict.\n            return false;\n        }\n\n        // wallet exist -- remove old value\n        remove(hash);\n        sync();\n        return true;\n    };\n\n    if (check_store())\n    {\n        // actually store wallet\n        const auto acc_size = wallet.serialized_size();\n        BITCOIN_ASSERT(acc_size <= max_size_t);\n        const auto value_size = static_cast<size_t>(acc_size);\n\n        auto write = [&wallet_data](memory_ptr data) {\n            auto serial = make_serializer(REMAP_ADDRESS(data));\n            serial.write_data(wallet_data);\n        };\n\n        lookup_map_.store(hash, write, value_size);\n    }\n}\n\nstd::shared_ptr<std::vector<libbitcoin::chain::wallet>> wallet_database::get_wallets() const\n{\n    auto vec_acc = std::make_shared<std::vector<libbitcoin::chain::wallet>>();\n    for (size_t i = 0; i < get_bucket_count(); i++)\n    {\n        auto memo = lookup_map_.find(i);\n        if (memo->size())\n        {\n            const auto action = [&vec_acc](memory_ptr elem) {\n                const auto memory = REMAP_ADDRESS(elem);\n                auto deserial = make_deserializer_unsafe(memory);\n                vec_acc->push_back(libbitcoin::chain::wallet::factory_from_data(deserial));\n            };\n            std::for_each(memo->begin(), memo->end(), action);\n        }\n    }\n    return vec_acc;\n}\n\nwallet_result wallet_database::get_wallet_result(const hash_digest &hash) const\n{\n    const auto memory = get(hash);\n    return wallet_result(memory);\n}\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/data/database/wallet_token_db.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS) \n *\n * This file is part of ucd.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/data/databases/wallet_token_db.hpp>\n//#include <UChainService/txs/wallet/wallet_token.hpp>\n\n#include <cstdint>\n#include <cstddef>\n#include <memory>\n#include <boost/filesystem.hpp>\n#include <UChain/coin.hpp>\n#include <UChain/database/memory/memory.hpp>\n#include <UChain/database/primitives/record_multimap_iterable.hpp>\n#include <UChain/database/primitives/record_multimap_iterator.hpp>\n\nnamespace libbitcoin\n{\nnamespace database\n{\n\nusing namespace boost::filesystem;\nusing namespace bc::chain;\n\nBC_CONSTEXPR size_t number_buckets = 9997;\nBC_CONSTEXPR size_t header_size = record_hash_table_header_size(number_buckets);\nBC_CONSTEXPR size_t initial_lookup_file_size = header_size + minimum_records_size;\n\nBC_CONSTEXPR size_t record_size = hash_table_multimap_record_size<short_hash>();\n\nBC_CONSTEXPR size_t token_transfer_record_size = 1 + 36 + 4 + 8 + 2 + TOKEN_DETAIL_FIX_SIZE; // TOKEN_DETAIL_FIX_SIZE is the biggest one\n//      + std::max({UCN_FIX_SIZE, TOKEN_DETAIL_FIX_SIZE, TOKEN_TRANSFER_FIX_SIZE});\nBC_CONSTEXPR size_t row_record_size = hash_table_record_size<short_hash>(token_transfer_record_size);\n\nwallet_token_database::wallet_token_database(const path &lookup_filename,\n                                             const path &rows_filename, std::shared_ptr<shared_mutex> mutex)\n    : lookup_file_(lookup_filename, mutex),\n      lookup_header_(lookup_file_, number_buckets),\n      lookup_manager_(lookup_file_, header_size, record_size),\n      lookup_map_(lookup_header_, lookup_manager_),\n      rows_file_(rows_filename, mutex),\n      rows_manager_(rows_file_, 0, row_record_size),\n      rows_list_(rows_manager_),\n      rows_multimap_(lookup_map_, rows_list_)\n{\n}\n\n// Close does not call stop because there is no way to detect thread join.\nwallet_token_database::~wallet_token_database()\n{\n    close();\n}\n\n// Create.\n// ----------------------------------------------------------------------------\n\n// Initialize files and start.\nbool wallet_token_database::create()\n{\n    // Resize and create require a started file.\n    if (!lookup_file_.start() ||\n        !rows_file_.start())\n        return false;\n\n    // These will throw if insufficient disk space.\n    lookup_file_.resize(initial_lookup_file_size);\n    rows_file_.resize(minimum_records_size);\n\n    if (!lookup_header_.create() ||\n        !lookup_manager_.create() ||\n        !rows_manager_.create())\n        return false;\n\n    // Should not call start after create, already started.\n    return lookup_header_.start() &&\n           lookup_manager_.start() &&\n           rows_manager_.start();\n}\n\n// Startup and shutdown.\n// ----------------------------------------------------------------------------\n\nbool wallet_token_database::start()\n{\n    return lookup_file_.start() &&\n           rows_file_.start() &&\n           lookup_header_.start() &&\n           lookup_manager_.start() &&\n           rows_manager_.start();\n}\n\nbool wallet_token_database::stop()\n{\n    return lookup_file_.stop() &&\n           rows_file_.stop();\n}\n\nbool wallet_token_database::close()\n{\n    return lookup_file_.close() &&\n           rows_file_.close();\n}\n\n// ----------------------------------------------------------------------------\n\nvoid wallet_token_database::store(const short_hash &key, const token_detail &detail)\n{\n    const auto detail_data = detail.to_data();\n\n    const auto check_store = [this, &key, &detail, &detail_data]() {\n        auto token_vec = get(key);\n        auto pos = std::find_if(token_vec.begin(), token_vec.end(),\n                                [&detail](const token_detail &elem) {\n                                    return (elem.get_symbol() == detail.get_symbol());\n                                });\n\n        if (pos == token_vec.end())\n        { // new item\n            return true;\n        }\n\n        if (pos->to_data() == detail_data)\n        {\n            // don't store duplicate data\n            return false;\n        }\n\n        // remove old record\n        delete_last_row(key);\n        sync();\n        return true;\n    };\n\n    if (check_store())\n    {\n        // actually store token\n        auto write = [&detail_data](memory_ptr data) {\n            auto serial = make_serializer(REMAP_ADDRESS(data));\n            serial.write_data(detail_data);\n        };\n        rows_multimap_.add_row(key, write);\n    }\n}\n\nvoid wallet_token_database::delete_last_row(const short_hash &key)\n{\n    rows_multimap_.delete_last_row(key);\n}\n\ntoken_detail::list wallet_token_database::get(const short_hash &key) const\n{\n    // Read a row from the data for the wallet_token list.\n    const auto read_row = [](uint8_t *data) {\n        auto deserial = make_deserializer_unsafe(data);\n        return token_detail::factory_from_data(deserial);\n    };\n\n    token_detail::list result;\n    const auto start = rows_multimap_.lookup(key);\n    const auto records = record_multimap_iterable(rows_list_, start);\n\n    for (const auto index : records)\n    {\n        // This obtains a remap safe address pointer against the rows file.\n        const auto record = rows_list_.get(index);\n        const auto address = REMAP_ADDRESS(record);\n\n        result.emplace_back(read_row(address));\n    }\n\n    // TODO: we could sort result here.\n    return result;\n}\n\nstd::shared_ptr<token_detail> wallet_token_database::get(const short_hash &key, const std::string &address) const\n{\n    std::shared_ptr<token_detail> addr(nullptr);\n    token_detail::list result = get(key);\n    for (auto element : result)\n    {\n        if (element.get_address() == address)\n        {\n            addr = std::make_shared<token_detail>(element);\n            break;\n        }\n    }\n\n    return addr;\n}\n/// get tokens whose status is not issued and stored in local database (not in blockchain)\nstd::shared_ptr<business_address_token::list> wallet_token_database::get_unissued_tokens(const short_hash &key) const\n{\n    auto result = get(key);\n    auto sp_token_vec = std::make_shared<business_address_token::list>();\n\n    // reconstruct business_address_token from token_detail and sotre them in sp_token_vec\n    const auto action = [&](const token_detail &elem) {\n        business_address_token busi_token;\n\n        busi_token.address = elem.get_address();\n        busi_token.status = 2; // 0 -- unspent  1 -- confirmed  2 -- local token not issued\n        busi_token.quantity = elem.get_maximum_supply();\n        busi_token.detail = elem;\n\n        sp_token_vec->emplace_back(std::move(busi_token));\n    };\n    std::for_each(result.begin(), result.end(), action);\n    return sp_token_vec;\n}\n\nvoid wallet_token_database::sync()\n{\n    lookup_manager_.sync();\n    rows_manager_.sync();\n}\n\nwallet_token_statinfo wallet_token_database::statinfo() const\n{\n    return {\n        lookup_header_.size(),\n        lookup_manager_.count(),\n        rows_manager_.count()};\n}\n\n} // namespace database\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/txs/CMakeLists.txt",
    "content": "# for C library\n#ADD_SUBDIRECTORY(math/external)\n\n#INCLUDE_DIRECTORIES(\"${PROJECT_SOURCE_DIR}/src/UChainService/consensus/clone\")\nFILE(GLOB_RECURSE txs_SOURCES \"*.cpp\")\n\nADD_DEFINITIONS(-DBC_STATIC=1)\n\n#ADD_LIBRARY(secp256k1_static STATIC IMPORTED)                                         \n#SET_TARGET_PROPERTIES(secp256k1_static PROPERTIES IMPORTED_LOCATION ${secp256k1_ROOT_DIR}/lib/libsecp256k1.a)\n\nADD_LIBRARY(txs_static STATIC ${txs_SOURCES})\nSET_TARGET_PROPERTIES(txs_static PROPERTIES OUTPUT_NAME uc_txs)\nTARGET_LINK_LIBRARIES(txs_static ${Boost_LIBRARIES})\nINSTALL(TARGETS txs_static DESTINATION lib)\n\nIF(ENABLE_SHARED_LIBS)\n    ADD_DEFINITIONS(-DBC_DLL=1)\n  ADD_LIBRARY(txs_shared SHARED ${txs_SOURCES})\n  SET_TARGET_PROPERTIES(txs_shared PROPERTIES OUTPUT_NAME uc_txs)\n  TARGET_LINK_LIBRARIES(txs_shared ${Boost_LIBRARIES})\n  INSTALL(TARGETS txs_shared DESTINATION lib)\nENDIF()\n"
  },
  {
    "path": "src/UChainService/txs/asset.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/txs/asset.hpp>\n#include <UChainService/txs/variant.hpp>\n#include <sstream>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nasset::asset()\n{\n    reset();\n}\n\nasset::asset(const std::string &from_uid, const std::string &to_uid)\n    : version(UID_ASSET_VERIFY_VERSION), type(0) //asset_type::attach_none;\n      ,\n      touid(to_uid), fromuid(from_uid)\n{\n    auto visitor = reset_visitor();\n    boost::apply_visitor(visitor, attach);\n}\n\nasset asset::factory_from_data(const data_chunk &data)\n{\n    asset instance;\n    instance.from_data(data);\n    return instance;\n}\n\nasset asset::factory_from_data(std::istream &stream)\n{\n    asset instance;\n    instance.from_data(stream);\n    return instance;\n}\n\nasset asset::factory_from_data(reader &source)\n{\n    asset instance;\n    instance.from_data(source);\n    return instance;\n}\n\nvoid asset::reset()\n{\n    version = 0;\n    type = 0; //asset_type::attach_none;\n    auto visitor = reset_visitor();\n    boost::apply_visitor(visitor, attach);\n    touid = \"\";\n    fromuid = \"\";\n}\n\nbool asset::is_valid() const\n{\n    if (!is_valid_type())\n    {\n        return false;\n    }\n    auto visitor = is_valid_visitor();\n    return boost::apply_visitor(visitor, attach);\n}\n\nbool asset::is_valid_type() const\n{\n    return ((UCN_TYPE == type) || (UC_TOKEN_TYPE == type) || (TOKEN_CERT_TYPE == type) || (TOKEN_CANDIDATE_TYPE == type) || (MESSAGE_TYPE == type) || (UCN_AWARD_TYPE == type) || (UID_TYPE == type));\n}\n\nbool asset::from_data(const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(istream);\n}\n\nbool asset::from_data(std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(source);\n}\n\nbool asset::from_data(reader &source)\n{\n    reset();\n\n    version = source.read_4_bytes_little_endian();\n    auto result = static_cast<bool>(source);\n\n    if (result)\n        type = source.read_4_bytes_little_endian();\n\n    if (result && version == UID_ASSET_VERIFY_VERSION)\n    {\n        touid = source.read_string();\n        fromuid = source.read_string();\n    }\n\n    result = static_cast<bool>(source);\n    if (result && is_valid_type())\n    {\n        switch (type)\n        {\n        case UCN_TYPE:\n        {\n            attach = ucn();\n            break;\n        }\n        case UCN_AWARD_TYPE:\n        {\n            attach = ucn_award();\n            break;\n        }\n        case UC_TOKEN_TYPE:\n        {\n            attach = token();\n            break;\n        }\n        case TOKEN_CERT_TYPE:\n        {\n            attach = token_cert();\n            break;\n        }\n        case TOKEN_CANDIDATE_TYPE:\n        {\n            attach = candidate();\n            break;\n        }\n        case MESSAGE_TYPE:\n        {\n            attach = blockchain_message();\n            break;\n        }\n        case UID_TYPE:\n        {\n            attach = uid();\n            break;\n        }\n        }\n\n        auto visitor = from_data_visitor(source);\n        result = boost::apply_visitor(visitor, attach);\n    }\n    else\n    {\n        result = false;\n        reset();\n    }\n\n    return result;\n}\n\ndata_chunk asset::to_data() const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream);\n    ostream.flush();\n    //BITCOIN_ASSERT(data.size() == serialized_size());\n    return data;\n}\n\nvoid asset::to_data(std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(sink);\n}\n\nvoid asset::to_data(writer &sink) const\n{\n    sink.write_4_bytes_little_endian(version);\n    sink.write_4_bytes_little_endian(type);\n    if (version == UID_ASSET_VERIFY_VERSION)\n    {\n        sink.write_string(touid);\n        sink.write_string(fromuid);\n    }\n    auto visitor = to_data_visitor(sink);\n    boost::apply_visitor(visitor, attach);\n}\n\nuint64_t asset::serialized_size() const\n{\n    uint64_t size = 0;\n    if (version == UID_ASSET_VERIFY_VERSION)\n    {\n        size = 4 + 4 + (touid.size() + 1) + (fromuid.size() + 1);\n    }\n    else\n    {\n        size = 4 + 4;\n    }\n\n    auto visitor = serialized_size_visitor();\n    size += boost::apply_visitor(visitor, attach);\n\n    return size;\n}\n\nstd::string asset::to_string() const\n{\n    std::ostringstream ss;\n\n    ss << \"\\t version = \" << version << \"\\n\"\n       << \"\\t type = \" << type << \"\\n\";\n    if (version == UID_ASSET_VERIFY_VERSION)\n    {\n        ss << \"\\t fromuid = \" << fromuid << \"\\n\"\n           << \"\\t touid = \" << touid << \"\\n\";\n    }\n    auto visitor = to_string_visitor();\n    ss << boost::apply_visitor(visitor, attach);\n\n    return ss.str();\n}\n\nuint32_t asset::get_version() const\n{\n    return version;\n}\nvoid asset::set_version(uint32_t version)\n{\n    this->version = version;\n}\n\nuint32_t asset::get_type() const\n{\n    return type;\n}\nvoid asset::set_type(uint32_t type)\n{\n    this->type = type;\n}\n\nstd::string asset::get_to_uid() const\n{\n    return touid;\n}\nvoid asset::set_to_uid(const std::string &uid)\n{\n    this->touid = uid;\n}\n\nstd::string asset::get_from_uid() const\n{\n    return fromuid;\n}\nvoid asset::set_from_uid(const std::string &uid)\n{\n    this->fromuid = uid;\n}\n\nasset::asset_data_type &asset::get_attach()\n{\n    return this->attach;\n}\nconst asset::asset_data_type &asset::get_attach() const\n{\n    return this->attach;\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/txs/asset_data.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/txs/asset_data.hpp>\n#include <UChainService/txs/variant.hpp>\n#include <sstream>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\n#define UCN_TYPE KIND2UINT16(business_kind::ucn)\n#define UCN_AWARD_TYPE KIND2UINT16(business_kind::ucn_award)\n#define TOKEN_ISSUE_TYPE KIND2UINT16(business_kind::token_issue)\n#define TOKEN_TRANSFER_TYPE KIND2UINT16(business_kind::token_transfer)\n#define TOKEN_CERT_TYPE KIND2UINT16(business_kind::token_cert)\n#define TOKEN_CANDIDATE_TYPE KIND2UINT16(business_kind::candidate)\n#define MESSAGE_TYPE KIND2UINT16(business_kind::message)\n#define UID_REGISTER_TYPE KIND2UINT16(business_kind::uid_register)\n#define UID_TRANSFER_TYPE KIND2UINT16(business_kind::uid_transfer)\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nasset_data asset_data::factory_from_data(const data_chunk &data)\n{\n    asset_data instance;\n    instance.from_data(data);\n    return instance;\n}\n\nasset_data asset_data::factory_from_data(std::istream &stream)\n{\n    asset_data instance;\n    instance.from_data(stream);\n    return instance;\n}\n\nasset_data asset_data::factory_from_data(reader &source)\n{\n    asset_data instance;\n    instance.from_data(source);\n    return instance;\n}\n\nvoid asset_data::reset()\n{\n    kind = business_kind::ucn;\n    timestamp = 0;\n    auto visitor = reset_visitor();\n    boost::apply_visitor(visitor, data);\n}\nbool asset_data::is_valid() const\n{\n    return true;\n}\n\nbool asset_data::is_valid_type() const\n{\n    return ((UCN_TYPE == KIND2UINT16(kind)) || (TOKEN_ISSUE_TYPE == KIND2UINT16(kind)) || (TOKEN_TRANSFER_TYPE == KIND2UINT16(kind)) || (TOKEN_CERT_TYPE == KIND2UINT16(kind)) || (TOKEN_CANDIDATE_TYPE == KIND2UINT16(kind))) || (UCN_AWARD_TYPE == KIND2UINT16(kind)) || (MESSAGE_TYPE == KIND2UINT16(kind)) || (UID_REGISTER_TYPE == KIND2UINT16(kind)) || (UID_TRANSFER_TYPE == KIND2UINT16(kind));\n}\n\nbool asset_data::from_data(const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(istream);\n}\n\nbool asset_data::from_data(std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(source);\n}\n\nbool asset_data::from_data(reader &source)\n{\n    reset();\n    kind = static_cast<business_kind>(source.read_2_bytes_little_endian());\n    timestamp = source.read_4_bytes_little_endian();\n    auto result = static_cast<bool>(source);\n\n    if (result && is_valid_type())\n    {\n        switch (KIND2UINT16(kind))\n        {\n        case UCN_TYPE:\n        {\n            data = ucn();\n            break;\n        }\n        case UCN_AWARD_TYPE:\n        {\n            data = ucn_award();\n            break;\n        }\n        case TOKEN_ISSUE_TYPE:\n        {\n            data = token_detail();\n            break;\n        }\n        case TOKEN_TRANSFER_TYPE:\n        {\n            data = token_transfer();\n            break;\n        }\n        case TOKEN_CERT_TYPE:\n        {\n            data = token_cert();\n            break;\n        }\n        case TOKEN_CANDIDATE_TYPE:\n        {\n            data = candidate();\n            break;\n        }\n        case MESSAGE_TYPE:\n        {\n            data = blockchain_message();\n            break;\n        }\n        case UID_REGISTER_TYPE:\n        {\n            data = uid_detail();\n            break;\n        }\n        case UID_TRANSFER_TYPE:\n        {\n            data = uid_detail();\n            break;\n        }\n        }\n        auto visitor = from_data_visitor(source);\n        result = boost::apply_visitor(visitor, data);\n    }\n    else\n    {\n        result = false;\n        reset();\n    }\n\n    return result;\n}\n\ndata_chunk asset_data::to_data()\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream);\n    ostream.flush();\n    return data;\n}\n\nvoid asset_data::to_data(std::ostream &stream)\n{\n    ostream_writer sink(stream);\n    to_data(sink);\n}\n\nvoid asset_data::to_data(writer &sink)\n{\n    sink.write_2_bytes_little_endian(KIND2UINT16(kind));\n    sink.write_4_bytes_little_endian(timestamp);\n    auto visitor = to_data_visitor(sink);\n    boost::apply_visitor(visitor, data);\n}\n\nuint64_t asset_data::serialized_size()\n{\n    uint64_t size = 2 + 4; // kind and timestamp\n    auto visitor = serialized_size_visitor();\n    size += boost::apply_visitor(visitor, data);\n\n    return size;\n}\n\n#ifdef UC_DEBUG\nstd::string asset_data::to_string()\n{\n    std::ostringstream ss;\n\n    ss << \"\\t kind = \" << KIND2UINT16(kind) << \"\\n\";\n    ss << \"\\t timestamp = \" << timestamp << \"\\n\";\n    auto visitor = to_string_visitor();\n    ss << boost::apply_visitor(visitor, data);\n\n    return ss.str();\n}\n#endif\n\nbusiness_kind asset_data::get_kind_value() const\n{\n    //return KIND2UINT16(kind);\n    return kind;\n}\n\nconst asset_data::asset_data_type &asset_data::get_data() const\n{\n    return data;\n}\n\nuint32_t asset_data::get_timestamp() const\n{\n    return timestamp;\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/txs/message/message.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/txs/message/message.hpp>\n#include <sstream>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nblockchain_message::blockchain_message() : content_(\"\")\n{\n}\nblockchain_message::blockchain_message(std::string content) : content_(content)\n{\n}\n\nblockchain_message blockchain_message::factory_from_data(const data_chunk &data)\n{\n    blockchain_message instance;\n    instance.from_data(data);\n    return instance;\n}\n\nblockchain_message blockchain_message::factory_from_data(std::istream &stream)\n{\n    blockchain_message instance;\n    instance.from_data(stream);\n    return instance;\n}\n\nblockchain_message blockchain_message::factory_from_data(reader &source)\n{\n    blockchain_message instance;\n    instance.from_data(source);\n    return instance;\n}\n\nvoid blockchain_message::reset()\n{\n    content_ = \"\";\n}\n\nbool blockchain_message::is_valid() const\n{\n    return !(content_.empty()\n             // add 1 here to prevent content_'s size == 253\n             || variable_string_size(content_) + 1 > BLOCKCHAIN_MESSAGE_FIX_SIZE);\n}\n\nbool blockchain_message::from_data(const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(istream);\n}\n\nbool blockchain_message::from_data(std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(source);\n}\n\nbool blockchain_message::from_data(reader &source)\n{\n    reset();\n    content_ = source.read_string();\n    auto result = static_cast<bool>(source);\n\n    return result;\n}\n\ndata_chunk blockchain_message::to_data() const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream);\n    ostream.flush();\n    BITCOIN_ASSERT(data.size() == serialized_size());\n    return data;\n}\n\nvoid blockchain_message::to_data(std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(sink);\n}\n\nvoid blockchain_message::to_data(writer &sink) const\n{\n    sink.write_string(content_);\n}\n\nuint64_t blockchain_message::serialized_size() const\n{\n    size_t len = variable_string_size(content_);\n    return std::min(len, BLOCKCHAIN_MESSAGE_FIX_SIZE);\n}\n\nstd::string blockchain_message::to_string() const\n{\n    std::ostringstream ss;\n    ss << \"\\t content = \" << content_ << \"\\n\";\n\n    return ss.str();\n}\nconst std::string &blockchain_message::get_content() const\n{\n    return content_;\n}\n\nvoid blockchain_message::set_content(const std::string &content)\n{\n    content_ = limit_size_string(content, BLOCKCHAIN_MESSAGE_FIX_SIZE);\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/txs/token/attenuation_model.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <UChainService/txs/token/attenuation_model.hpp>\n#include <UChain/coin/utility/string.hpp>\n#include <UChain/blockchain/block_chain_impl.hpp>\n#include <UChain/blockchain/validate_tx_engine.hpp>\n#include <unordered_map>\n#include <memory>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nstatic BC_CONSTEXPR uint64_t max_inflation_rate = 100000;\nstatic BC_CONSTEXPR uint64_t max_unlock_number = 100;\n\nnamespace\n{\nconst char *LOG_HEADER{\"attenuation_model\"};\n\nstd::string chunk_to_string(const data_chunk &chunk)\n{\n    return std::string(chunk.begin(), chunk.end());\n}\n\nstd::vector<std::pair<std::string, std::string>> key_name_pairs{\n    {\"PN\", \"current_period_nbr\"},\n    {\"LH\", \"next_interval\"},\n    {\"TYPE\", \"type\"},\n    {\"LQ\", \"lock_quantity\"},\n    {\"LP\", \"lock_period\"},\n    {\"UN\", \"total_period_nbr\"},\n    {\"IR\", \"inflation_rate\"},\n    {\"UC\", \"custom_lock_number_array\"},\n    {\"UQ\", \"custom_lock_quantity_array\"}};\n\nstd::map<attenuation_model::model_type, std::vector<std::string>> model_keys_map{\n    {attenuation_model::model_type::fixed_quantity, {\"PN\", \"LH\", \"TYPE\", \"LQ\", \"LP\", \"UN\"}},\n    {attenuation_model::model_type::custom, {\"PN\", \"LH\", \"TYPE\", \"LQ\", \"LP\", \"UN\", \"UC\", \"UQ\"}},\n    {attenuation_model::model_type::fixed_inflation, {\"PN\", \"LH\", \"TYPE\", \"LQ\", \"LP\", \"UN\", \"IR\", \"UC\", \"UQ\"}}};\n\nstd::vector<std::string> inflation_model_initial_keys{\"PN\", \"LH\", \"TYPE\", \"LQ\", \"LP\", \"UN\", \"IR\"};\n\nbool is_positive_number(uint64_t num)\n{\n    return num > 0;\n};\n\ntemplate <typename T>\nuint64_t sum_and_check_numbers(const std::vector<T> &container,\n                               std::function<bool(uint64_t)> predicate)\n{\n    uint64_t sum = 0;\n    for (const auto &num : container)\n    {\n        if (!predicate(num))\n        {\n            return 0;\n        }\n        sum += num;\n    }\n    return sum;\n}\n\ntemplate <typename ForwardIterator>\nForwardIterator find_nth_element(\n    ForwardIterator first,\n    ForwardIterator last,\n    size_t nth,\n    uint8_t elem)\n{\n    if (nth == 0)\n    {\n        return last;\n    }\n\n    typedef typename std::iterator_traits<ForwardIterator>::reference Tref;\n    return std::find_if(first, last, [&](Tref x) {\n        return (x == elem) && (--nth == 0);\n    });\n}\n\n} // end of anonymous namespace\n\nclass attenuation_model::impl\n{\n  public:\n    impl(const std::string &param, bool is_init)\n        : model_param_(param)\n    {\n        if (!parse_param(is_init))\n        {\n            map_.clear();\n        }\n    }\n\n    const std::string &get_model_param() const\n    {\n        return model_param_;\n    }\n\n    // TYPE model type\n    model_type get_model_type() const\n    {\n        return from_index(getnumber<uint8_t>(\"TYPE\"));\n    }\n\n    // PN  current period number\n    uint64_t get_current_period_number() const\n    {\n        return getnumber(\"PN\");\n    }\n\n    // LH  latest lock height\n    uint64_t get_latest_lock_height() const\n    {\n        return getnumber(\"LH\");\n    }\n\n    // LQ  total locked quantity\n    uint64_t get_locked_quantity() const\n    {\n        return getnumber(\"LQ\");\n    }\n\n    // LP  total locked period\n    uint64_t get_locked_period() const\n    {\n        return getnumber(\"LP\");\n    }\n\n    // UN  total unlock numbers\n    uint64_t get_unlock_number() const\n    {\n        return getnumber(\"UN\");\n    }\n\n    // IR  inflation rate\n    uint64_t get_inflation_rate() const\n    {\n        return getnumber(\"IR\");\n    }\n\n    // UCt size()==1 means fixed cycle\n    const std::vector<uint64_t> &get_unlock_cycles() const\n    {\n        return get_numbers(\"UC\");\n    }\n\n    // UQt size()==1 means fixed quantity\n    const std::vector<uint64_t> &get_unlocked_quantities() const\n    {\n        return get_numbers(\"UQ\");\n    }\n\n    data_chunk get_new_model_param(uint64_t PN, uint64_t LH) const\n    {\n        auto iter = find_nth_element(model_param_.begin(), model_param_.end(), 2, ';');\n        if (iter == model_param_.end())\n        {\n            return data_chunk();\n        }\n        auto prefix = \"PN=\" + std::to_string(PN) + \";LH=\" + std::to_string(LH);\n        auto suffix = model_param_.substr(iter - model_param_.begin());\n        return to_chunk(prefix + suffix);\n    }\n\n  private:\n    bool validate_keys(model_type model, const std::vector<std::string> &keys)\n    {\n        if (map_.size() != keys.size())\n        {\n            log::debug(LOG_HEADER) << \"The size of keys \" << map_.size()\n                                   << \" for model type \" << std::to_string(to_index(model))\n                                   << \" does not equal \" << keys.size();\n            return false;\n        }\n\n        for (size_t i = 0; i < keys.size(); ++i)\n        {\n            if (map_.find(keys[i]) == map_.end())\n            {\n                log::debug(LOG_HEADER) << \"model type \" << std::to_string(to_index(model))\n                                       << \" needs key \" << keys[i] << \" but missed.\";\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    bool check_keys(bool is_init)\n    {\n        auto model = get_model_type();\n        if (model == model_type::none)\n        {\n            return true;\n        }\n\n        if (is_init && model == model_type::fixed_inflation)\n        {\n            return validate_keys(model, inflation_model_initial_keys);\n        }\n        else\n        {\n            return validate_keys(model, model_keys_map[model]);\n        }\n    }\n\n    bool parse_uint64(const std::string &param, uint64_t &value)\n    {\n        for (auto &i : param)\n        {\n            if (!std::isalnum(i))\n            {\n                return false;\n            }\n        }\n\n        value = std::stoull(param);\n        return true;\n    }\n\n    bool parse_param(bool is_init = false)\n    {\n        if (model_param_.empty())\n        {\n            return true;\n        }\n        auto is_illegal_char = [](auto c) { return !(std::isalnum(c) || (c == ',') || (c == ';') || (c == '=')); };\n        auto iter = std::find_if(model_param_.begin(), model_param_.end(), is_illegal_char);\n        if (iter != model_param_.end())\n        {\n            log::debug(LOG_HEADER) << \"illegal char found at pos \"\n                                   << std::distance(model_param_.begin(), iter) << \" : \" << *iter;\n            return false;\n        }\n\n        if (model_param_.find(\",,\") != std::string::npos)\n        {\n            log::debug(LOG_HEADER) << \"',,' is not allowed.\";\n            return false;\n        }\n\n        const auto &kv_vec = bc::split(model_param_, \";\", true);\n        if (kv_vec.size() < 6)\n        {\n            log::debug(LOG_HEADER) << \"model param is \" << model_param_\n                                   << \", the model param should at least contain keys of PN, LH, TYPE, LQ, LP, UN\";\n            return false;\n        }\n        if (kv_vec[0].find(\"PN=\") != 0)\n        {\n            log::debug(LOG_HEADER) << \"the model param first key must be PN\";\n            return false;\n        }\n        if (kv_vec[1].find(\"LH=\") != 0)\n        {\n            log::debug(LOG_HEADER) << \"the model param second key must be LH\";\n            return false;\n        }\n\n        for (const auto &kv : kv_vec)\n        {\n            auto vec = bc::split(kv, \"=\", true);\n            if (vec.size() == 2)\n            {\n                auto key = vec[0];\n                auto values = vec[1];\n                if (key.empty())\n                {\n                    log::debug(LOG_HEADER) << \"key-value format is wrong, key is empty in \" << kv;\n                    return false;\n                }\n\n                if (map_.find(key) != map_.end())\n                {\n                    log::debug(LOG_HEADER) << \"key-value format is wrong, duplicate key : \" << key;\n                    return false;\n                }\n\n                if (values.empty())\n                {\n                    continue; // empty value as unset.\n                }\n\n                try\n                {\n                    std::vector<uint64_t> num_vec;\n                    uint64_t num = 0;\n                    if (attenuation_model::is_multi_value_key(key))\n                    {\n                        auto str_vec = bc::split(values, \",\", true);\n                        for (const auto &item : str_vec)\n                        {\n                            if (parse_uint64(item, num))\n                            {\n                                num_vec.emplace_back(num);\n                            }\n                            else\n                            {\n                                log::debug(LOG_HEADER) << \"value is not a number: \" << item;\n                                return false;\n                            }\n                        }\n                    }\n                    else\n                    {\n                        if (parse_uint64(values, num))\n                        {\n                            num_vec.emplace_back(num);\n                        }\n                        else\n                        {\n                            log::debug(LOG_HEADER) << \"value is not a number: \" << values;\n                            return false;\n                        }\n                    }\n\n                    map_[key] = std::move(num_vec);\n                }\n                catch (const std::exception &e)\n                {\n                    log::debug(LOG_HEADER) << \"exception caught: \" << e.what();\n                    return false;\n                }\n            }\n            else\n            {\n                log::debug(LOG_HEADER) << \"key-value format is wrong, should be key=value format. \" << model_param_;\n                return false;\n            }\n        }\n\n        // check keys after map is constructed\n        if (!check_keys(is_init))\n        {\n            log::debug(LOG_HEADER) << \"check keys of model param failed \";\n            return false;\n        }\n        return true;\n    }\n\n    template <typename T = uint64_t>\n    T getnumber(const std::string &key) const\n    {\n        BITCOIN_ASSERT(!attenuation_model::is_multi_value_key(key));\n        auto iter = map_.find(key);\n        if (iter == map_.end())\n        {\n            return 0;\n        }\n        return iter->second[0];\n    }\n\n    const std::vector<uint64_t> &get_numbers(const std::string &key) const\n    {\n        BITCOIN_ASSERT(attenuation_model::is_multi_value_key(key));\n        auto iter = map_.find(key);\n        if (iter == map_.end())\n        {\n            return empty_num_vec;\n        }\n        return iter->second;\n    }\n\n  private:\n    // semicolon separates outer key-value entries.\n    // comma separates inner container items of value.\n    // empty value or non-exist entry means the key is unset.\n    // PN, LH is mutable and generated by program.\n    // * example of fixed quantity model param:\n    // \"PN=0;LH=20000;TYPE=1;LQ=9000;LP=60000;UN=3\"\n    // * example of custom model param:\n    // \"PN=0;LH=20000;TYPE=2;LQ=9000;LP=60000;UN=3;UC=20000,20000,20000;UQ=3000,3000,3000\"\n    // * example of fixed inflation reate model param\n    // \"PN=0;LH=1000;TYPE=3;LQ=20000000;LP=12000;UN=12;IR=8\"\n    std::string model_param_;\n\n    // auxilary data\n    std::unordered_map<std::string, std::vector<uint64_t>> map_;\n    static const std::vector<uint64_t> empty_num_vec;\n};\n\nconst std::vector<uint64_t> attenuation_model::impl::empty_num_vec;\n\nattenuation_model::attenuation_model(const std::string &param, bool is_init)\n    : pimpl(std::make_unique<impl>(param, is_init))\n{\n}\n\nattenuation_model::model_type attenuation_model::get_model_type() const\n{\n    return pimpl->get_model_type();\n}\n\nconst std::string &attenuation_model::get_model_param() const\n{\n    return pimpl->get_model_param();\n}\n\ndata_chunk attenuation_model::get_new_model_param(uint64_t PN, uint64_t LH) const\n{\n    return pimpl->get_new_model_param(PN, LH);\n}\n\nuint64_t attenuation_model::get_current_period_number() const\n{\n    return pimpl->get_current_period_number();\n}\n\nuint64_t attenuation_model::get_latest_lock_height() const\n{\n    return pimpl->get_latest_lock_height();\n}\n\nuint64_t attenuation_model::get_locked_quantity() const\n{\n    return pimpl->get_locked_quantity();\n}\n\nuint64_t attenuation_model::get_locked_period() const\n{\n    return pimpl->get_locked_period();\n}\n\nuint64_t attenuation_model::get_unlock_number() const\n{\n    return pimpl->get_unlock_number();\n}\n\nuint64_t attenuation_model::get_inflation_rate() const\n{\n    return pimpl->get_inflation_rate();\n}\n\nconst std::vector<uint64_t> &attenuation_model::get_unlock_cycles() const\n{\n    return pimpl->get_unlock_cycles();\n}\n\nconst std::vector<uint64_t> &attenuation_model::get_unlocked_quantities() const\n{\n    return pimpl->get_unlocked_quantities();\n}\n\nbool attenuation_model::is_multi_value_key(const std::string &key)\n{\n    return key == \"UC\" || key == \"UQ\";\n}\n\nstd::string attenuation_model::get_name_of_key(const std::string &key)\n{\n    for (const auto &pair : key_name_pairs)\n    {\n        if (key == pair.first)\n        {\n            return pair.second;\n        }\n    }\n    BITCOIN_ASSERT(false);\n    return \"\";\n}\n\nstd::string attenuation_model::get_key_of_name(const std::string &name)\n{\n    const std::string prefix = \"model_\";\n    if (name.find(prefix) != 0)\n    {\n        return \"\";\n    }\n    auto compare_name = name.substr(prefix.size());\n    for (const auto &pair : key_name_pairs)\n    {\n        if (compare_name == pair.second)\n        {\n            return pair.first;\n        }\n    }\n    return \"\";\n}\n\nuint8_t attenuation_model::get_first_unused_index()\n{\n    return to_index(model_type::unused1);\n}\n\nuint8_t attenuation_model::to_index(attenuation_model::model_type model)\n{\n    return static_cast<typename std::underlying_type<model_type>::type>(model);\n}\n\nattenuation_model::model_type attenuation_model::from_index(uint32_t index)\n{\n    if (!check_model_index(index))\n    {\n        log::debug(LOG_HEADER) << \"model index is wrong: index = \" << index;\n        return model_type::none;\n    }\n    return (model_type)index;\n}\n\nbool attenuation_model::check_model_index(uint32_t index)\n{\n    return index < get_first_unused_index();\n}\n\nbool attenuation_model::check_model_param_immutable(const data_chunk &previous, const data_chunk &current)\n{\n    if (previous.empty() || current.empty())\n    {\n        return false;\n    }\n\n    auto iter1 = find_nth_element(previous.begin(), previous.end(), 2, ';');\n    auto iter2 = find_nth_element(current.begin(), current.end(), 2, ';');\n\n    return std::equal(iter1, previous.end(), iter2);\n}\n\nbool attenuation_model::check_model_param_format(const data_chunk &param)\n{\n    attenuation_model parser(std::string(param.begin(), param.end()));\n\n    const auto model = parser.get_model_type();\n\n    // model_type::none is equivalent to\n    // the scrpit pattern is not pay_key_hash_with_attenuation_model\n    if (model == model_type::none)\n    {\n        if (!param.empty())\n        {\n            log::debug(LOG_HEADER)\n                << \"check_model_param, wrong model param format : \"\n                << parser.get_model_param();\n        }\n        return false;\n    }\n\n    return true;\n}\n\nbool attenuation_model::check_model_param(const data_chunk &param, uint64_t total_amount)\n{\n    std::string model_param(param.begin(), param.end());\n    return check_model_param_initial(model_param, total_amount, false);\n}\n\nbool attenuation_model::check_model_param_initial(std::string &param, uint64_t total_amount, bool is_init)\n{\n    bool has_prefix = param.find(\"PN=\") == 0;\n\n    attenuation_model parser(has_prefix ? param : (\"PN=0;LH=0;\" + param), is_init);\n\n    const auto model = parser.get_model_type();\n\n    // model_type::none is equivalent to\n    // the scrpit pattern is not pay_key_hash_with_attenuation_model\n    if (model == model_type::none)\n    {\n        if (!param.empty())\n        {\n            log::debug(LOG_HEADER)\n                << \"check_model_param, wrong model param in intial : \"\n                << parser.get_model_param();\n        }\n        return false;\n    }\n\n    auto PN = parser.get_current_period_number();\n    auto LH = parser.get_latest_lock_height();\n    auto LQ = parser.get_locked_quantity();\n    auto LP = parser.get_locked_period();\n    auto UN = parser.get_unlock_number();\n    const auto &UCs = parser.get_unlock_cycles();\n\n    // common condition : initial PN = 0\n    if (PN != 0)\n    {\n        log::debug(LOG_HEADER) << \"common initial param error: PN != 0\";\n        return false;\n    }\n\n    // common condition : LQ <= IQ (utxo's token amount)\n    if (LQ > total_amount)\n    {\n        log::debug(LOG_HEADER) << \"common initial param error: LQ > IQ\";\n        return false;\n    }\n\n    if (!check_model_param_common(parser))\n    {\n        return false;\n    }\n\n    if (model == model_type::fixed_quantity || model == model_type::custom)\n    {\n        // add prefix of PN,LH, check after ensured UN > 0\n        auto initial_lock_height = (!UCs.empty()) ? UCs[0] : (LP / UN);\n        if (!has_prefix)\n        {\n            LH = initial_lock_height;\n            if (is_init)\n            {\n                param = \"PN=0;LH=\" + std::to_string(LH) + \";\" + param;\n            }\n        }\n        else if (LH != initial_lock_height)\n        {\n            log::debug(LOG_HEADER) << \"common initial param error: LH != \" << initial_lock_height;\n            return false;\n        }\n    }\n\n    if (model == model_type::fixed_quantity)\n    {\n        return check_model_param_un(parser);\n    }\n    else if (model == model_type::fixed_inflation)\n    {\n        return check_model_param_initial_fixed_inflation(param, total_amount, parser, is_init);\n    }\n    else if (model == model_type::custom)\n    {\n        return check_model_param_uc_uq(parser);\n    }\n\n    log::debug(LOG_HEADER) << \"check_model_param_initial, Unsupported attenuation model: \"\n                           << std::to_string(to_index(model));\n    return false;\n}\n\nbool attenuation_model::check_model_param_common(attenuation_model &parser)\n{\n    auto LQ = parser.get_locked_quantity();\n    auto LP = parser.get_locked_period();\n    auto UN = parser.get_unlock_number();\n    auto PN = parser.get_current_period_number();\n\n    // common condition : PN < UN\n    if (PN >= UN)\n    {\n        log::debug(LOG_HEADER) << \"common param error: PN >= UN\";\n        return false;\n    }\n\n    // common condition : LQ > 0\n    if (!is_positive_number(LQ))\n    {\n        log::debug(LOG_HEADER) << \"attenuation param error: LQ <= 0\";\n        return false;\n    }\n\n    // common condition : LP > 0\n    if (!is_positive_number(LP))\n    {\n        log::debug(LOG_HEADER) << \"attenuation param error: LP <= 0\";\n        return false;\n    }\n\n    // UN > 0\n    if (!is_positive_number(UN))\n    {\n        log::debug(LOG_HEADER) << \"attenuation param error: UN <= 0\";\n        return false;\n    }\n\n    return true;\n}\n\nbool attenuation_model::check_model_param_un(attenuation_model &parser)\n{\n    auto LQ = parser.get_locked_quantity();\n    auto LP = parser.get_locked_period();\n    auto UN = parser.get_unlock_number();\n\n    // given LQ, LP, UN, then\n    // LP >= UN and LQ >= UN\n    if (LP < UN)\n    {\n        log::debug(LOG_HEADER) << \"attenuation param error: LP < UN\";\n        return false;\n    }\n    if (LQ < UN)\n    {\n        log::debug(LOG_HEADER) << \"attenuation param error: LQ < UN\";\n        return false;\n    }\n\n    return true;\n}\n\nbool attenuation_model::check_model_param_uc_uq(attenuation_model &parser)\n{\n    auto LQ = parser.get_locked_quantity();\n    auto LP = parser.get_locked_period();\n    auto UN = parser.get_unlock_number();\n\n    if (UN > max_unlock_number)\n    {\n        log::debug(LOG_HEADER) << \"attenuation param error: UN > 100, at most 100 cycles is supported.\";\n        return false;\n    }\n\n    // given LQ, LP, UN, UC, UQ, then\n    // LQ = sum(UQ) and all UQ > 0 and UQ.size == UN\n    // LP = sum(UC) and all UC > 0 and UC.size == UN\n    const auto &UCs = parser.get_unlock_cycles();\n    const auto &UQs = parser.get_unlocked_quantities();\n    if (UCs.size() != UN)\n    {\n        log::debug(LOG_HEADER) << \"attenuation param error: UC.size() != UN\";\n        return false;\n    }\n    if (UQs.size() != UN)\n    {\n        log::debug(LOG_HEADER) << \"attenuation param error: UQ.size() != UN\";\n        return false;\n    }\n    auto value = sum_and_check_numbers(UCs, is_positive_number);\n    if (value != LP)\n    {\n        log::debug(LOG_HEADER) << \"attenuation param error: LP(\"\n                               << std::to_string(LP) << \") != sum(UC)(\" << std::to_string(value) << \") or exist UC <= 0\";\n        return false;\n    }\n    value = sum_and_check_numbers(UQs, is_positive_number);\n    if (value != LQ)\n    {\n        log::debug(LOG_HEADER) << \"attenuation param error: LQ(\"\n                               << std::to_string(LQ) << \") != sum(UQ)(\" << std::to_string(value) << \") or exist UQ <= 0\";\n        return false;\n    }\n    return true;\n}\n\nbool attenuation_model::check_model_param_inflation(attenuation_model &parser, uint64_t total_amount)\n{\n    if (!check_model_param_un(parser))\n    {\n        return false;\n    }\n\n    auto LQ = parser.get_locked_quantity();\n    auto UN = parser.get_unlock_number();\n    auto IR = parser.get_inflation_rate();\n\n    if (LQ != total_amount)\n    {\n        log::debug(LOG_HEADER) << \"fixed inflation param error: partial lock is not supported!\";\n        return false;\n    }\n\n    if (UN > max_unlock_number)\n    {\n        log::debug(LOG_HEADER) << \"fixed inflation param error: UN > 100, at most 100 cycles is supported.\";\n        return false;\n    }\n\n    // IR > 0\n    if (IR <= 0 || IR > max_inflation_rate)\n    {\n        log::debug(LOG_HEADER) << \"fixed inflation param error: IR not in [1, \" << max_inflation_rate << \"]\";\n        return false;\n    }\n\n    return true;\n}\n\nbool attenuation_model::check_model_param_initial_fixed_inflation(\n    std::string &param, uint64_t total_amount, attenuation_model &parser, bool is_init)\n{\n    if (!check_model_param_inflation(parser, total_amount))\n    {\n        return false;\n    }\n\n    auto PN = parser.get_current_period_number();\n    auto LH = parser.get_latest_lock_height();\n    auto LQ = parser.get_locked_quantity();\n    auto LP = parser.get_locked_period();\n    auto UN = parser.get_unlock_number();\n    auto IR = parser.get_inflation_rate();\n\n    if (LQ == total_amount)\n    {\n        uint64_t IP = LP / UN;\n\n        // check LH after ensured UN > 0\n        bool has_prefix = param.find(\"PN=\") == 0;\n        if (!has_prefix)\n        {\n            LH = IP;\n        }\n        else if (LH != IP)\n        {\n            log::debug(LOG_HEADER) << \"fixed inflation param error: LH != \" << IP;\n            return false;\n        }\n\n        if (!is_init)\n        {\n            return check_model_param_uc_uq(parser);\n        }\n\n        // compute UC and UQ array\n        double rate = IR / 100.0;\n        double UP1 = std::pow(1 + rate, int64_t(1 - UN));\n        uint64_t UQ1 = LQ * UP1;\n        UQ1 = std::min(UQ1, LQ);\n        BITCOIN_ASSERT(UQ1 > 0);\n\n        std::vector<uint64_t> uc_vec, uq_vec;\n        uc_vec.push_back(IP);\n        uq_vec.push_back(UQ1);\n\n        uint64_t total_uc = IP;\n        uint64_t total_uq = UQ1;\n        uint64_t current_uc, current_uq;\n        for (uint64_t i = 1; i < UN; ++i)\n        {\n            current_uq = total_uq * rate;\n            current_uc = IP;\n\n            if (i == UN - 1)\n            {\n                current_uc = LP - total_uc;\n                current_uq = LQ - total_uq;\n            }\n\n            uc_vec.push_back(current_uc);\n            uq_vec.push_back(current_uq);\n            total_uc += current_uc;\n            total_uq += current_uq;\n        }\n\n        BITCOIN_ASSERT(total_uc == LP);\n        BITCOIN_ASSERT(total_uq == LQ);\n\n        // rebuild parameter string\n        // sample: PN=0;LH=2000;TYPE=3;LQ=9001;LP=6000;UN=3;IR=8\n        std::stringstream ss;\n        ss << \"PN=0;LH=\";\n        ss << std::to_string(LH);\n        ss << \";TYPE=3;LQ=\";\n        ss << std::to_string(LQ);\n        ss << \";LP=\";\n        ss << std::to_string(LP);\n        ss << \";UN=\";\n        ss << std::to_string(UN);\n        ss << \";IR=\";\n        ss << std::to_string(IR);\n        ss << \";UC=\";\n        for (auto it = uc_vec.begin(); it != uc_vec.end(); ++it)\n        {\n            if (it != uc_vec.begin())\n            {\n                ss << \",\";\n            }\n            ss << std::to_string(*it);\n        }\n\n        ss << \";UQ=\";\n        for (auto it = uq_vec.begin(); it != uq_vec.end(); ++it)\n        {\n            if (it != uq_vec.begin())\n            {\n                ss << \",\";\n            }\n            ss << std::to_string(*it);\n        }\n\n        // update param\n        ss >> param;\n\n        return true;\n    }\n\n    else\n    {\n        log::error(LOG_HEADER) << \"fixed inflation param error: partial lock is not supported!\";\n    }\n\n    return false;\n}\n\nbool attenuation_model::validate_model_param(const data_chunk &param, uint64_t total_amount)\n{\n    attenuation_model parser(std::string(param.begin(), param.end()));\n\n    const auto model = parser.get_model_type();\n\n    // model_type::none is equivalent to\n    // the scrpit pattern is not pay_key_hash_with_attenuation_model\n    if (model == model_type::none)\n    {\n        if (!param.empty())\n        {\n            log::debug(LOG_HEADER)\n                << \"check_model_param, wrong model param : \"\n                << parser.get_model_param();\n        }\n        return false;\n    }\n\n    auto PN = parser.get_current_period_number();\n    auto LH = parser.get_latest_lock_height();\n    auto LQ = parser.get_locked_quantity();\n    auto LP = parser.get_locked_period();\n    auto UN = parser.get_unlock_number();\n\n    if (!check_model_param_common(parser))\n    {\n        return false;\n    }\n\n    // common condition : LH > 0\n    if (!is_positive_number(LH))\n    {\n        log::debug(LOG_HEADER) << \"common param error: LH <= 0\";\n        return false;\n    }\n\n    if (model == model_type::fixed_quantity)\n    {\n        uint64_t UC = LP / UN;\n        if (PN + 1 == UN)\n        { // last cycle\n            if (PN * UC + LH > LP)\n            {\n                log::debug(LOG_HEADER) << \"fixed cycle param error: last cycle PN * UC + LH > LP\";\n                return false;\n            }\n        }\n        else\n        {\n            if (LH > UC)\n            {\n                log::debug(LOG_HEADER) << \"fixed cycle param error: LH > UC\";\n                return false;\n            }\n        }\n    }\n\n    else if (model == model_type::custom)\n    {\n        const auto &UCs = parser.get_unlock_cycles();\n        if (LH > UCs[PN])\n        {\n            log::debug(LOG_HEADER) << \"custom param error: LH > UC\";\n            return false;\n        }\n    }\n\n    else if (model == model_type::fixed_inflation)\n    {\n        if (!check_model_param_inflation(parser, total_amount))\n        {\n            return false;\n        }\n\n        if (!check_model_param_uc_uq(parser))\n        {\n            return false;\n        }\n\n        const auto &UCs = parser.get_unlock_cycles();\n        if (LH > UCs[PN])\n        {\n            log::debug(LOG_HEADER) << \"fixed inflation param error: LH > UC\";\n            return false;\n        }\n    }\n\n    return true;\n}\n\ncode attenuation_model::check_model_param(const blockchain::validate_tx_engine &validate_tx)\n{\n    const transaction &tx = validate_tx.get_tx();\n    const blockchain::block_chain_impl &chain = validate_tx.get_blockchain();\n\n    if (tx.version < transaction_version::check_uid_feature)\n    {\n        return error::success;\n    }\n\n    struct ext_input_point\n    {\n        chain::input_point input_point_;\n        chain::output prev_output_;\n        uint64_t prev_blockheight_;\n    };\n\n    std::vector<ext_input_point> vec_prev_input;\n\n    for (const auto &input : tx.inputs)\n    {\n        if (input.previous_output.is_null())\n        {\n            return error::previous_output_null;\n        }\n\n        chain::transaction prev_tx;\n        uint64_t prev_height = 0;\n        if (!validate_tx.get_previous_tx(prev_tx, prev_height, input))\n        {\n            return error::input_not_found;\n        }\n\n        const auto &prev_output = prev_tx.outputs.at(input.previous_output.index);\n        if (!operation::is_pay_key_hash_with_attenuation_model_pattern(prev_output.script.operations))\n        {\n            continue;\n        }\n\n        ext_input_point prev{input.previous_output, prev_output, prev_height};\n        vec_prev_input.emplace_back(prev);\n    }\n\n    if (vec_prev_input.empty())\n    {\n        return error::success;\n    }\n\n    uint64_t current_blockheight = 0;\n    chain.get_last_height(current_blockheight);\n\n    for (auto &output : tx.outputs)\n    {\n        if (!operation::is_pay_key_hash_with_attenuation_model_pattern(output.script.operations))\n        {\n            continue;\n        }\n\n        const auto &model_param = output.get_attenuation_model_param();\n        if (!attenuation_model::validate_model_param(model_param, output.get_token_amount()))\n        {\n            log::debug(LOG_HEADER) << \"check param failed, \" << chunk_to_string(model_param);\n            return error::attenuation_model_param_error;\n        }\n\n        const auto &input_point_data = operation::\n            get_input_point_from_pay_key_hash_with_attenuation_model(output.script.operations);\n        chain::input_point input_point = chain::point::factory_from_data(input_point_data);\n        if (input_point.is_null())\n        {\n            if (!check_model_param(model_param, output.get_token_amount()))\n            {\n                log::debug(LOG_HEADER) << \"input is null, \" << chunk_to_string(model_param);\n                return error::attenuation_model_param_error;\n            }\n            continue;\n        }\n\n        auto iter = std::find_if(vec_prev_input.begin(), vec_prev_input.end(),\n                                 [&input_point](const ext_input_point &elem) {\n                                     return elem.input_point_ == input_point;\n                                 });\n\n        if (iter == vec_prev_input.end())\n        {\n            log::debug(LOG_HEADER) << \"input not found for \" << input_point.to_string();\n            return error::attenuation_model_param_error;\n        }\n\n        const auto &prev_model_param = iter->prev_output_.get_attenuation_model_param();\n\n        if (!check_model_param_immutable(prev_model_param, model_param))\n        {\n            log::debug(LOG_HEADER) << \"check immutable failed, \"\n                                   << \"prev is \" << chunk_to_string(prev_model_param)\n                                   << \", new is \" << chunk_to_string(model_param);\n            return error::attenuation_model_param_error;\n        }\n\n        auto curr_diff_height = current_blockheight - iter->prev_blockheight_;\n        auto real_diff_height = get_diff_height(prev_model_param, model_param);\n\n        if (real_diff_height > curr_diff_height)\n        {\n            log::debug(LOG_HEADER) << \"check diff height failed, \"\n                                   << real_diff_height << \", curr diff is \" << curr_diff_height;\n            return error::attenuation_model_param_error;\n        }\n\n        auto token_total_amount = iter->prev_output_.get_token_amount();\n        auto new_model_param_ptr = std::make_shared<data_chunk>();\n        auto token_amount = attenuation_model::get_available_token_amount(\n            token_total_amount, real_diff_height,\n            prev_model_param, new_model_param_ptr);\n\n        if (token_total_amount != (token_amount + output.get_token_amount()))\n        {\n            log::debug(LOG_HEADER) << \"check amount failed, \"\n                                   << \"locked shoule be \" << token_total_amount - token_amount\n                                   << \", but real locked is \" << output.get_token_amount();\n            return error::attenuation_model_param_error;\n        }\n\n        if (!new_model_param_ptr || (*new_model_param_ptr != model_param))\n        {\n            log::debug(LOG_HEADER) << \"check model new param failed, \"\n                                   << \"prev is \" << chunk_to_string(model_param) << \", new is \"\n                                   << (new_model_param_ptr ? chunk_to_string(*new_model_param_ptr) : std::string(\"empty\"));\n            return error::attenuation_model_param_error;\n        }\n\n        // prevent multiple locked outputs connect to the same input\n        vec_prev_input.erase(iter);\n    }\n\n    // check the left is all spendable\n    for (const auto &ext_input : vec_prev_input)\n    {\n        const auto &prev_model_param = ext_input.prev_output_.get_attenuation_model_param();\n        auto curr_diff_height = current_blockheight - ext_input.prev_blockheight_;\n        auto real_diff_height = get_diff_height(prev_model_param, data_chunk());\n        if (real_diff_height > curr_diff_height)\n        {\n            log::debug(LOG_HEADER) << \"check diff height failed for all spendable, \"\n                                   << real_diff_height << \", curr diff is \" << curr_diff_height;\n            return error::attenuation_model_param_error;\n        }\n    }\n\n    return error::success;\n}\n\nuint64_t attenuation_model::get_diff_height(const data_chunk &prev_param, const data_chunk &param)\n{\n    attenuation_model parser(std::string(prev_param.begin(), prev_param.end()));\n    auto model = parser.get_model_type();\n    if (model == model_type::none)\n    {\n        return max_uint64;\n    }\n\n    auto PN = parser.get_current_period_number();\n    auto LH = parser.get_latest_lock_height();\n    auto LP = parser.get_locked_period();\n    auto UN = parser.get_unlock_number();\n\n    uint64_t PN2 = 0;\n    uint64_t LH2 = 0;\n    if (!param.empty())\n    {\n        attenuation_model parser2(std::string(param.begin(), param.end()));\n        PN2 = parser2.get_current_period_number();\n        LH2 = parser2.get_latest_lock_height();\n    }\n    else\n    {\n        PN2 = UN - 1;\n        LH2 = 0;\n    }\n\n    if (PN > PN2)\n    {\n        return max_uint64;\n    }\n\n    if (PN == PN2)\n    {\n        if (LH < LH2)\n        {\n            return max_uint64;\n        }\n        return LH - LH2;\n    }\n\n    if (model == model_type::fixed_quantity)\n    {\n        auto UC = LP / UN;\n        if (PN2 + 1 == UN)\n        {\n            return LP - LH2 - ((PN + 1) * UC) + LH;\n        }\n        return LH + ((PN2 - PN) * UC) - LH2;\n    }\n\n    else if (model == model_type::custom || model == model_type::fixed_inflation)\n    {\n        const auto &UCs = parser.get_unlock_cycles();\n        auto diff_height = LH;\n        for (auto i = PN + 1; i <= PN2; ++i)\n        {\n            diff_height += UCs[i];\n        }\n        diff_height -= LH2;\n        return diff_height;\n    }\n\n    return 0;\n}\n\nuint64_t attenuation_model::get_available_token_amount(\n    uint64_t token_amount, uint64_t diff_height,\n    const data_chunk &param, std::shared_ptr<data_chunk> new_param_ptr)\n{\n    if (token_amount == 0)\n    {\n        return 0;\n    }\n\n    attenuation_model parser(std::string(param.begin(), param.end()));\n\n    const auto model = parser.get_model_type();\n\n    // model_type::none is equivalent to\n    // the scrpit pattern is not pay_key_hash_with_attenuation_model\n    if (model == model_type::none)\n    {\n        if (!param.empty())\n        {\n            log::debug(LOG_HEADER)\n                << \"get_available_token_amount, wrong model param : \"\n                << parser.get_model_param();\n        }\n        return token_amount;\n    }\n\n    auto PN = parser.get_current_period_number();\n    auto LH = parser.get_latest_lock_height();\n    auto LQ = parser.get_locked_quantity();\n    auto LP = parser.get_locked_period();\n    auto UN = parser.get_unlock_number();\n    const auto &UCs = parser.get_unlock_cycles();\n    const auto &UQs = parser.get_unlocked_quantities();\n\n    auto available = (token_amount > LQ) ? (token_amount - LQ) : 0;\n\n    if (diff_height < LH)\n    { // no maturity, still all locked\n        if (new_param_ptr)\n        {\n            // update PN, LH\n            LH -= diff_height;\n            *new_param_ptr = parser.get_new_model_param(PN, LH);\n        }\n        return available;\n    }\n\n    if (model == model_type::fixed_quantity)\n    {\n        uint64_t UC = LP / UN;\n        auto elapsed_height = (diff_height - LH) + ((PN + 1) * UC);\n        if (elapsed_height >= LP)\n        { // include the last unlock cycle, release all\n            return token_amount;\n        }\n        auto new_cycles = std::min((elapsed_height / UC - PN), (LP - PN - 1));\n        if (new_param_ptr)\n        {\n            // update PN, LH\n            PN = PN + new_cycles;\n            if ((PN + 1) == UN)\n            { // last cycle\n                LH = LP - elapsed_height;\n            }\n            else\n            {\n                LH = (PN + 1) * UC - elapsed_height;\n            }\n            *new_param_ptr = parser.get_new_model_param(PN, LH);\n        }\n        auto UQ = LQ / UN;\n        available += new_cycles * UQ;\n        return available;\n    }\n\n    if (model == model_type::custom || model == model_type::fixed_inflation)\n    {\n        available += UQs[PN];\n        diff_height -= LH;\n        ++PN;\n        while ((PN < UN) && (diff_height >= UCs[PN]))\n        {\n            available += UQs[PN];\n            diff_height -= UCs[PN];\n            ++PN;\n        }\n        if (PN == UN)\n        { // include the last unlock cycle, release all\n            return token_amount;\n        }\n        if (new_param_ptr)\n        {\n            // update PN, LH\n            LH = UCs[PN] - diff_height;\n            *new_param_ptr = parser.get_new_model_param(PN, LH);\n        }\n        return available;\n    }\n\n    log::debug(LOG_HEADER) << \"get_available_token_amount, Unsupported attenuation model: \"\n                           << std::to_string(to_index(model));\n    return token_amount;\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/txs/token/blockchain_token.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/txs/token/blockchain_token.hpp>\n\n#include <sstream>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nblockchain_token::blockchain_token()\n{\n    reset();\n}\nblockchain_token::blockchain_token(uint32_t version, const output_point &tx_point,\n                                   uint64_t height, const token_detail &token) : version_(version), tx_point_(tx_point), height_(height), token_(token)\n{\n}\n\nblockchain_token blockchain_token::factory_from_data(const data_chunk &data)\n{\n    blockchain_token instance;\n    instance.from_data(data);\n    return instance;\n}\n\nblockchain_token blockchain_token::factory_from_data(std::istream &stream)\n{\n    blockchain_token instance;\n    instance.from_data(stream);\n    return instance;\n}\n\nblockchain_token blockchain_token::factory_from_data(reader &source)\n{\n    blockchain_token instance;\n    instance.from_data(source);\n    return instance;\n}\nbool blockchain_token::is_valid() const\n{\n    return true;\n}\n\nvoid blockchain_token::reset()\n{\n    version_ = 0;\n    tx_point_ = output_point();\n    height_ = 0;\n    token_ = token_detail();\n}\n\nbool blockchain_token::from_data(const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(istream);\n}\n\nbool blockchain_token::from_data(std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(source);\n}\n\nbool blockchain_token::from_data(reader &source)\n{\n    reset();\n\n    version_ = source.read_4_bytes_little_endian();\n    tx_point_.from_data(source);\n    height_ = source.read_8_bytes_little_endian();\n    token_.from_data(source);\n\n    return true;\n}\n\ndata_chunk blockchain_token::to_data() const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream);\n    ostream.flush();\n    //BITCOIN_ASSERT(data.size() == serialized_size());\n    return data;\n}\n\nvoid blockchain_token::to_data(std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(sink);\n}\n\nvoid blockchain_token::to_data(writer &sink) const\n{\n    sink.write_4_bytes_little_endian(version_);\n    tx_point_.to_data(sink);\n    sink.write_8_bytes_little_endian(height_);\n    token_.to_data(sink);\n}\n\nuint64_t blockchain_token::serialized_size() const\n{\n    return 4 + tx_point_.serialized_size() + 8 + token_.serialized_size();\n}\n\n#ifdef UC_DEBUG\nstd::string blockchain_token::to_string() const\n{\n    std::ostringstream ss;\n\n    ss << \"\\t version = \" << version_ << \"\\n\"\n       << \"\\t tx_point = \" << tx_point_.to_string() << \"\\n\"\n       << \"\\t height = \" << height_ << \"\\n\"\n       << \"\\t token = \" << token_.to_string() << \"\\n\";\n\n    return ss.str();\n}\n\n#endif\nconst uint32_t &blockchain_token::get_version() const\n{\n    return version_;\n}\nvoid blockchain_token::set_version(const uint32_t &version_)\n{\n    this->version_ = version_;\n}\n\nconst output_point &blockchain_token::get_tx_point() const\n{\n    return tx_point_;\n}\nvoid blockchain_token::set_tx_point(const output_point &tx_point_)\n{\n    this->tx_point_ = tx_point_;\n}\n\nconst uint64_t &blockchain_token::get_height() const\n{\n    return height_;\n}\nvoid blockchain_token::set_height(const uint64_t &height_)\n{\n    this->height_ = height_;\n}\n\nconst token_detail &blockchain_token::get_token() const\n{\n    return token_;\n}\nvoid blockchain_token::set_token(const token_detail &token_)\n{\n    this->token_ = token_;\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/txs/token/candidate.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/txs/token/candidate.hpp>\n#include <sstream>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n#include <UChain/blockchain/block_chain_impl.hpp>\n#include <UChain/blockchain/validate_tx_engine.hpp>\n#include <UChainService/api/restful/utility/Compare.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\n// use 1~127 to represent normal candidate status type\n// add plus 128 to them to make their status type in tracing state.\n// status >128 means no content should be store\nconstexpr uint8_t CANDIDATE_STATUS_MASK = 0x7f;\nconstexpr uint8_t CANDIDATE_STATUS_SHORT_OFFSET = 0x80;\n\ncandidate::candidate()\n{\n    reset();\n}\n\ncandidate::candidate(const std::string &symbol,\n                     const std::string &address, const std::string &content, uint8_t status)\n    : symbol_(symbol), address_(address), content_(content), status_(status)\n{\n}\n\nvoid candidate::reset()\n{\n    symbol_ = \"\";\n    address_ = \"\";\n    content_ = \"\";\n    status_ = CANDIDATE_STATUS_NONE;\n}\n\nbool candidate::is_valid() const\n{\n    return !(symbol_.empty() || address_.empty() || is_invalid_status() || (calc_size() > get_max_serialized_size()));\n}\n\nbool candidate::operator<(const candidate &other) const\n{\n    return symbol_.compare(other.symbol_) < 0;\n}\n\ncandidate candidate::factory_from_data(const data_chunk &data)\n{\n    candidate instance;\n    instance.from_data(data);\n    return instance;\n}\n\ncandidate candidate::factory_from_data(std::istream &stream)\n{\n    candidate instance;\n    instance.from_data(stream);\n    return instance;\n}\n\ncandidate candidate::factory_from_data(reader &source)\n{\n    candidate instance;\n    instance.from_data(source);\n    return instance;\n}\n\nbool candidate::from_data(const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(istream);\n}\n\nbool candidate::from_data(std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(source);\n}\n\nbool candidate::from_data(reader &source)\n{\n    reset();\n\n    status_ = source.read_byte();\n    symbol_ = source.read_string();\n    address_ = source.read_string();\n    if (is_register_status())\n    {\n        content_ = source.read_string();\n    }\n\n    auto result = static_cast<bool>(source);\n    if (!result)\n        reset();\n\n    return result;\n}\n\ndata_chunk candidate::to_short_data() const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    ostream_writer sink(ostream);\n    // store status with offset, specify to store no content.\n    sink.write_byte(get_status() + CANDIDATE_STATUS_SHORT_OFFSET);\n    sink.write_string(symbol_);\n    sink.write_string(address_);\n    ostream.flush();\n    return data;\n}\n\ndata_chunk candidate::to_data() const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream);\n    ostream.flush();\n    return data;\n}\n\nvoid candidate::to_data(std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(sink);\n}\n\nvoid candidate::to_data(writer &sink) const\n{\n    sink.write_byte(status_);\n    sink.write_string(symbol_);\n    sink.write_string(address_);\n    if (is_register_status())\n    {\n        sink.write_string(content_);\n    }\n}\n\nuint64_t candidate::get_max_serialized_size() const\n{\n    return is_register_status() ? TOKEN_CANDIDATE_FIX_SIZE : TOKEN_CANDIDATE_TRANSFER_FIX_SIZE;\n}\n\nuint64_t candidate::calc_size() const\n{\n    uint64_t len = (symbol_.size() + 1) + (address_.size() + 1) + TOKEN_CANDIDATE_STATUS_FIX_SIZE;\n    if (is_register_status())\n    {\n        len += variable_string_size(content_);\n    }\n    return len;\n}\n\nuint64_t candidate::serialized_size() const\n{\n    return std::min(calc_size(), get_max_serialized_size());\n}\n\nstd::string candidate::to_string() const\n{\n    std::ostringstream ss;\n    ss << \"\\t status = \" << get_status_name() << \"\\n\";\n    ss << \"\\t symbol = \" << symbol_ << \"\\n\";\n    ss << \"\\t address = \" << address_ << \"\\n\";\n    if (is_register_status())\n    {\n        ss << \"\\t content = \" << content_ << \"\\n\";\n    }\n    return ss.str();\n}\n\nconst std::string &candidate::get_symbol() const\n{\n    return symbol_;\n}\n\nvoid candidate::set_symbol(const std::string &symbol)\n{\n    symbol_ = limit_size_string(symbol, TOKEN_CANDIDATE_SYMBOL_FIX_SIZE);\n}\n\nconst std::string &candidate::get_address() const\n{\n    return address_;\n}\n\nvoid candidate::set_address(const std::string &address)\n{\n    address_ = limit_size_string(address, TOKEN_CANDIDATE_ADDRESS_FIX_SIZE);\n}\n\nconst std::string &candidate::get_content() const\n{\n    return content_;\n}\n\nvoid candidate::set_content(const std::string &content)\n{\n    content_ = limit_size_string(content, TOKEN_CANDIDATE_CONTENT_FIX_SIZE);\n}\n\nuint8_t candidate::get_status() const\n{\n    return status_ & CANDIDATE_STATUS_MASK;\n}\n\nvoid candidate::set_status(uint8_t status)\n{\n    status_ = status & CANDIDATE_STATUS_MASK;\n}\n\nstd::string candidate::status_to_string(uint8_t status)\n{\n    if (status == CANDIDATE_STATUS_REGISTER)\n    {\n        return \"registered\";\n    }\n    else if (status == CANDIDATE_STATUS_TRANSFER)\n    {\n        return \"transfered\";\n    }\n    else if (status == CANDIDATE_STATUS_HISTORY)\n    {\n        return \"history\";\n    }\n    else if (status == CANDIDATE_STATUS_CURRENT)\n    {\n        return \"current\";\n    }\n    else\n    {\n        return \"none\";\n    }\n}\n\nstd::string candidate::get_status_name() const\n{\n    return status_to_string(get_status());\n}\n\nbool candidate::is_register_status() const\n{\n    return status_ == CANDIDATE_STATUS_REGISTER;\n}\n\nbool candidate::is_transfer_status() const\n{\n    return status_ == CANDIDATE_STATUS_TRANSFER;\n}\n\nbool candidate::is_invalid_status() const\n{\n    return status_ <= CANDIDATE_STATUS_NONE || status_ >= CANDIDATE_STATUS_MAX;\n}\n\n///////////////////////////////////////////////////\n///////////// candidate_info //////////////////////\n///////////////////////////////////////////////////\nvoid candidate_info::reset()\n{\n    output_height = 0;\n    timestamp = 0;\n    vote = 0;\n    //status = 0;\n    to_uid = \"\";\n    candidate.reset();\n}\n\nbool candidate_info::operator<(const candidate_info &other) const\n{\n    return candidate < other.candidate;\n}\n\nuint64_t candidate_info::serialized_size() const\n{\n    // output_height; timestamp; to_uid; candidate;\n    return 4 + 4 + (to_uid.size() + 1) + candidate.serialized_size();\n}\n\ncandidate_info candidate_info::factory_from_data(reader &source)\n{\n    candidate_info instance;\n    instance.reset();\n\n    instance.output_height = source.read_4_bytes_little_endian();\n    instance.timestamp = source.read_4_bytes_little_endian();\n    //instance.status = source.read_byte();\n    instance.to_uid = source.read_string();\n    instance.candidate = candidate::factory_from_data(source);\n\n    auto result = static_cast<bool>(source);\n    if (!result)\n    {\n        instance.reset();\n    }\n\n    return instance;\n}\n\ndata_chunk candidate_info::to_data() const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    ostream_writer sink(ostream);\n\n    sink.write_4_bytes_little_endian(output_height);\n    sink.write_4_bytes_little_endian(timestamp);\n    sink.write_string(to_uid);\n    sink.write_data(candidate.to_data());\n\n    ostream.flush();\n    return data;\n}\n\ndata_chunk candidate_info::to_short_data() const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    ostream_writer sink(ostream);\n\n    sink.write_4_bytes_little_endian(output_height);\n    sink.write_4_bytes_little_endian(timestamp);\n    sink.write_string(to_uid);\n    sink.write_data(candidate.to_short_data());\n\n    ostream.flush();\n    return data;\n}\n\n// const uint8_t& candidate_info::get_status()\n// {\n//     return this->status;\n// }\n// void candidate_info::set_status(const uint8_t &status)\n// {\n//     this->status = status;\n// }\n\n} // namespace chain\n} // namespace libbitcoin"
  },
  {
    "path": "src/UChainService/txs/token/token.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/txs/token/token.hpp>\n#include <UChainService/txs/variant.hpp>\n#include <UChainService/txs/token/token_detail.hpp>\n#include <UChainService/txs/token/token_transfer.hpp>\n#include <sstream>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\ntoken::token()\n{\n    reset();\n}\ntoken::token(uint32_t status, const token_detail &detail) : status(status), data(detail)\n{\n}\ntoken::token(uint32_t status, const token_transfer &detail) : status(status), data(detail)\n{\n}\ntoken token::factory_from_data(const data_chunk &data)\n{\n    token instance;\n    instance.from_data(data);\n    return instance;\n}\n\ntoken token::factory_from_data(std::istream &stream)\n{\n    token instance;\n    instance.from_data(stream);\n    return instance;\n}\n\ntoken token::factory_from_data(reader &source)\n{\n    token instance;\n    instance.from_data(source);\n    return instance;\n}\n\nvoid token::reset()\n{\n    status = 0; //token_status::token_none;\n    auto visitor = reset_visitor();\n    boost::apply_visitor(visitor, data);\n}\n\nbool token::is_valid() const\n{\n    auto visitor = is_valid_visitor();\n    return boost::apply_visitor(visitor, data);\n}\n\nbool token::is_valid_type() const\n{\n    return ((TOKEN_DETAIL_TYPE == status) || (TOKEN_TRANSFERABLE_TYPE == status));\n}\n\nbool token::from_data(const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(istream);\n}\n\nbool token::from_data(std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(source);\n}\n\nbool token::from_data(reader &source)\n{\n    reset();\n\n    status = source.read_4_bytes_little_endian();\n    auto result = static_cast<bool>(source);\n\n    if (result && is_valid_type())\n    {\n        switch (status)\n        {\n        case TOKEN_DETAIL_TYPE:\n        {\n            data = token_detail();\n            break;\n        }\n        case TOKEN_TRANSFERABLE_TYPE:\n        {\n            data = token_transfer();\n            break;\n        }\n        }\n        auto visitor = from_data_visitor(source);\n        result = boost::apply_visitor(visitor, data);\n    }\n    else\n    {\n        result = false;\n        reset();\n    }\n\n    return result;\n}\n\ndata_chunk token::to_data() const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream);\n    ostream.flush();\n    //BITCOIN_ASSERT(data.size() == serialized_size());\n    return data;\n}\n\nvoid token::to_data(std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(sink);\n}\n\nvoid token::to_data(writer &sink) const\n{\n    sink.write_4_bytes_little_endian(status);\n\n    auto visitor = to_data_visitor(sink);\n    boost::apply_visitor(visitor, data);\n}\n\nuint64_t token::serialized_size() const\n{\n    uint64_t size = 0;\n\n    auto visitor = serialized_size_visitor();\n    size += boost::apply_visitor(visitor, data);\n    return 4 + size;\n}\n\nstd::string token::to_string() const\n{\n    std::ostringstream ss;\n    ss << \"\\t status = \" << status << \"\\n\";\n    auto visitor = to_string_visitor();\n    ss << boost::apply_visitor(visitor, data);\n    return ss.str();\n}\n\nuint32_t token::get_status() const\n{\n    return status;\n}\nvoid token::set_status(uint32_t status)\n{\n    this->status = status;\n}\nvoid token::set_data(const token_detail &detail)\n{\n    this->data = detail;\n}\nvoid token::set_data(const token_transfer &detail)\n{\n    this->data = detail;\n}\ntoken::token_data_type &token::get_data()\n{\n    return this->data;\n}\nconst token::token_data_type &token::get_data() const\n{\n    return this->data;\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/txs/token/token_cert.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/txs/token/token_cert.hpp>\n#include <sstream>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n#include <UChain/blockchain/block_chain_impl.hpp>\n#include <UChain/blockchain/validate_tx_engine.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\n#define TOKEN_SYMBOL_DELIMITER \".\"\n\ntoken_cert::token_cert()\n{\n    reset();\n}\n\ntoken_cert::token_cert(const std::string &symbol, const std::string &owner,\n                       const std::string &address, token_cert_type cert_type)\n    : symbol_(symbol), owner_(owner), address_(address), cert_type_(cert_type), status_(TOKEN_CERT_NORMAL_TYPE)\n{\n}\n\nvoid token_cert::reset()\n{\n    symbol_ = \"\";\n    owner_ = \"\";\n    address_ = \"\";\n    cert_type_ = token_cert_ns::none;\n    status_ = TOKEN_CERT_NORMAL_TYPE;\n}\n\nbool token_cert::is_valid() const\n{\n    return !(symbol_.empty() || owner_.empty() || (cert_type_ == token_cert_ns::none) || (calc_size() > TOKEN_CERT_FIX_SIZE));\n}\n\nbool token_cert::operator<(const token_cert &other) const\n{\n    typedef std::tuple<std::string, token_cert_type> cmp_tuple;\n    return cmp_tuple(symbol_, cert_type_) < cmp_tuple(other.symbol_, other.cert_type_);\n}\n\nstd::string token_cert::get_domain(const std::string &symbol)\n{\n    std::string domain(\"\");\n    auto &&tokens = bc::split(symbol, TOKEN_SYMBOL_DELIMITER, true);\n    if (tokens.size() > 0)\n    {\n        domain = tokens[0];\n    }\n    return domain;\n}\n\nbool token_cert::is_valid_domain(const std::string &domain)\n{\n    return !domain.empty();\n}\n\nstd::string token_cert::get_key(const std::string &symbol, const token_cert_type &bit)\n{\n    return std::string(symbol + \":^#`@:\" + std::to_string(bit));\n}\n\nstd::string token_cert::token_cert::get_key() const\n{\n    return get_key(symbol_, cert_type_);\n}\n\ntoken_cert token_cert::factory_from_data(const data_chunk &data)\n{\n    token_cert instance;\n    instance.from_data(data);\n    return instance;\n}\n\ntoken_cert token_cert::factory_from_data(std::istream &stream)\n{\n    token_cert instance;\n    instance.from_data(stream);\n    return instance;\n}\n\ntoken_cert token_cert::factory_from_data(reader &source)\n{\n    token_cert instance;\n    instance.from_data(source);\n    return instance;\n}\n\nbool token_cert::from_data(const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(istream);\n}\n\nbool token_cert::from_data(std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(source);\n}\n\nbool token_cert::from_data(reader &source)\n{\n    reset();\n    symbol_ = source.read_string();\n    owner_ = source.read_string();\n    address_ = source.read_string();\n    cert_type_ = source.read_4_bytes_little_endian();\n    status_ = source.read_byte();\n\n    auto result = static_cast<bool>(source);\n    if (!result)\n        reset();\n\n    return result;\n}\n\ndata_chunk token_cert::to_data() const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream);\n    ostream.flush();\n    return data;\n}\n\nvoid token_cert::to_data(std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(sink);\n}\n\nvoid token_cert::to_data(writer &sink) const\n{\n    sink.write_string(symbol_);\n    sink.write_string(owner_);\n    sink.write_string(address_);\n    sink.write_4_bytes_little_endian(cert_type_);\n    sink.write_byte(status_);\n}\n\nuint64_t token_cert::calc_size() const\n{\n    return (symbol_.size() + 1) + (owner_.size() + 1) + (address_.size() + 1) + TOKEN_CERT_TYPE_FIX_SIZE + TOKEN_CERT_STATUS_FIX_SIZE;\n}\n\nuint64_t token_cert::serialized_size() const\n{\n    return std::min<uint64_t>(calc_size(), TOKEN_CERT_FIX_SIZE);\n}\n\nstd::string token_cert::to_string() const\n{\n    std::ostringstream ss;\n    ss << \"\\t symbol = \" << symbol_ << \"\\n\";\n    ss << \"\\t owner = \" << owner_ << \"\\n\";\n    ss << \"\\t address = \" << address_ << \"\\n\";\n    ss << \"\\t cert = \" << get_type_name() << \"\\n\";\n    ss << \"\\t status = \" << std::to_string(status_) << \"\\n\";\n    return ss.str();\n}\n\nconst std::string &token_cert::get_symbol() const\n{\n    return symbol_;\n}\n\nvoid token_cert::set_symbol(const std::string &symbol)\n{\n    size_t len = std::min((symbol.size() + 1), TOKEN_CERT_SYMBOL_FIX_SIZE);\n    symbol_ = symbol.substr(0, len);\n}\n\nuint8_t token_cert::get_status() const\n{\n    return status_;\n}\n\nvoid token_cert::set_status(uint8_t status)\n{\n    status_ = status;\n}\n\nbool token_cert::is_newly_generated() const\n{\n    return (status_ == TOKEN_CERT_ISSUE_TYPE) || (status_ == TOKEN_CERT_AUTOISSUE_TYPE);\n}\n\nconst std::string &token_cert::get_owner() const\n{\n    return owner_;\n}\n\nvoid token_cert::set_owner(const std::string &owner)\n{\n    size_t len = std::min((owner.size() + 1), TOKEN_CERT_OWNER_FIX_SIZE);\n    owner_ = owner.substr(0, len);\n}\n\nconst std::string &token_cert::get_address() const\n{\n    return address_;\n}\n\nvoid token_cert::set_address(const std::string &address)\n{\n    size_t len = std::min((address.size() + 1), TOKEN_CERT_ADDRESS_FIX_SIZE);\n    address_ = address.substr(0, len);\n}\n\ntoken_cert_type token_cert::get_type() const\n{\n    return cert_type_;\n}\n\nvoid token_cert::set_type(token_cert_type cert_type)\n{\n    cert_type_ = cert_type;\n}\n\ntoken_cert_type token_cert::get_certs() const\n{\n    return cert_type_;\n}\n\nvoid token_cert::set_certs(token_cert_type cert_type)\n{\n    cert_type_ = cert_type;\n}\n\nstd::string token_cert::get_type_name() const\n{\n    return get_type_name(cert_type_);\n}\n\nconst std::map<token_cert_type, std::string> &token_cert::get_type_name_map()\n{\n    static std::map<token_cert_type, std::string> static_type_name_map = {\n        {token_cert_ns::issue, \"issue\"},\n        {token_cert_ns::domain, \"domain\"},\n        {token_cert_ns::naming, \"naming\"},\n\n        {token_cert_ns::marriage, \"marriage\"},\n        {token_cert_ns::kyc, \"KYC\"},\n    };\n    return static_type_name_map;\n}\n\nstd::string token_cert::get_type_name(token_cert_type cert_type)\n{\n    BITCOIN_ASSERT(cert_type != token_cert_ns::none);\n\n    const auto &type_name_map = get_type_name_map();\n    auto iter = type_name_map.find(cert_type);\n    if (iter != type_name_map.end())\n    {\n        return iter->second;\n    }\n\n    std::stringstream sstream;\n    sstream << \"0x\" << std::hex << cert_type;\n    std::string result = sstream.str();\n    return result;\n}\n\nbool token_cert::test_certs(const std::vector<token_cert_type> &cert_vec, token_cert_type cert_type)\n{\n    BITCOIN_ASSERT(cert_type != token_cert_ns::none);\n\n    auto iter = std::find(cert_vec.begin(), cert_vec.end(), cert_type);\n    return iter != cert_vec.end();\n}\n\nbool token_cert::test_certs(const std::vector<token_cert_type> &total, const std::vector<token_cert_type> &parts)\n{\n    if (total.size() < parts.size())\n    {\n        return false;\n    }\n\n    for (auto &cert_type : parts)\n    {\n        if (!test_certs(total, cert_type))\n        {\n            return false;\n        }\n    }\n\n    return true;\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/txs/token/token_detail.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/txs/token/token_detail.hpp>\n\n#include <sstream>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n#include <UChain/coin/utility/string.hpp>\n#include <json/minijson_writer.hpp>\n\n#define TOKEN_SYMBOL_DELIMITER \".\"\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\ntoken_detail::token_detail()\n{\n    reset();\n}\n\ntoken_detail::token_detail(\n    const std::string &symbol, uint64_t maximum_supply,\n    uint8_t decimal_number, uint8_t threshold, const std::string &issuer,\n    const std::string &address, const std::string &description) : symbol(symbol), maximum_supply(maximum_supply),\n                                                                  decimal_number(decimal_number),\n                                                                  secondaryissue_threshold(threshold),\n                                                                  unused2(0), unused3(0),\n                                                                  issuer(issuer), address(address), description(description)\n{\n}\n\ntoken_detail token_detail::factory_from_data(const data_chunk &data)\n{\n    token_detail instance;\n    instance.from_data(data);\n    return instance;\n}\n\ntoken_detail token_detail::factory_from_data(std::istream &stream)\n{\n    token_detail instance;\n    instance.from_data(stream);\n    return instance;\n}\n\ntoken_detail token_detail::factory_from_data(reader &source)\n{\n    token_detail instance;\n    instance.from_data(source);\n    return instance;\n}\n\nbool token_detail::is_valid() const\n{\n    return !(symbol.empty() || (maximum_supply == 0 && !is_token_secondaryissue()) || (symbol.size() + 8 + 4 + issuer.size() + address.size() + description.size() + 4) > TOKEN_DETAIL_FIX_SIZE);\n}\n\nvoid token_detail::reset()\n{\n    symbol = \"\";\n    maximum_supply = 0;\n    decimal_number = 0;\n    secondaryissue_threshold = 0;\n    unused2 = 0;\n    unused3 = 0;\n    issuer = \"\";\n    address = \"\";\n    description = \"\";\n}\n\nbool token_detail::from_data(const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(istream);\n}\n\nbool token_detail::from_data(std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(source);\n}\n\nbool token_detail::from_data(reader &source)\n{\n    reset();\n\n    symbol = source.read_string();\n    maximum_supply = source.read_8_bytes_little_endian();\n    decimal_number = source.read_byte();\n    secondaryissue_threshold = source.read_byte();\n    unused2 = source.read_byte();\n    unused3 = source.read_byte();\n    issuer = source.read_string();\n    address = source.read_string();\n    description = source.read_string();\n\n    auto result = static_cast<bool>(source);\n    if (!result)\n        reset();\n\n    return result;\n}\n\ndata_chunk token_detail::to_data() const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream);\n    ostream.flush();\n    return data;\n}\n\nvoid token_detail::to_data(std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(sink);\n}\n\nvoid token_detail::to_data(writer &sink) const\n{\n    sink.write_string(symbol);\n    sink.write_8_bytes_little_endian(maximum_supply);\n    sink.write_byte(decimal_number);\n    sink.write_byte(secondaryissue_threshold);\n    sink.write_byte(unused2);\n    sink.write_byte(unused3);\n    sink.write_string(issuer);\n    sink.write_string(address);\n    sink.write_string(description);\n}\n\nuint64_t token_detail::serialized_size() const\n{\n    size_t len = symbol.size() + 8 + 4 + issuer.size() + address.size() + description.size() + 4;\n    return std::min(TOKEN_DETAIL_FIX_SIZE, len);\n}\n\nstd::string token_detail::to_string() const\n{\n    std::ostringstream ss;\n\n    ss << \"\\t symbol = \" << symbol << \"\\n\"\n       << \"\\t maximum_supply = \" << std::to_string(maximum_supply) << \"\\n\"\n       << \"\\t decimal_number = \" << std::to_string(decimal_number) << \"\\n\"\n       << \"\\t is_token_secondaryissue = \" << (is_token_secondaryissue() ? \"true\" : \"false\") << \"\\n\"\n       << \"\\t secondaryissue_threshold = \" << std::to_string(get_secondaryissue_threshold()) << \"\\n\"\n       << \"\\t issuer = \" << issuer << \"\\n\"\n       << \"\\t address = \" << address << \"\\n\"\n       << \"\\t description = \" << description << \"\\n\";\n\n    return ss.str();\n}\n\nbool token_detail::operator<(const token_detail &other) const\n{\n    typedef std::tuple<std::string, std::string> cmp_tuple;\n    return cmp_tuple(symbol, issuer) < cmp_tuple(other.symbol, other.issuer);\n}\n\nconst std::string &token_detail::get_symbol() const\n{\n    return symbol;\n}\nvoid token_detail::set_symbol(const std::string &symbol)\n{\n    size_t len = symbol.size() + 1 < (TOKEN_DETAIL_SYMBOL_FIX_SIZE) ? symbol.size() + 1 : TOKEN_DETAIL_SYMBOL_FIX_SIZE;\n    this->symbol = symbol.substr(0, len);\n}\n\nuint64_t token_detail::get_maximum_supply() const\n{\n    return maximum_supply;\n}\nvoid token_detail::set_maximum_supply(uint64_t maximum_supply)\n{\n    this->maximum_supply = maximum_supply;\n}\n\nuint8_t token_detail::get_decimal_number() const\n{\n    return decimal_number;\n}\nvoid token_detail::set_decimal_number(uint8_t decimal_number)\n{\n    this->decimal_number = decimal_number;\n}\n\nconst std::string &token_detail::get_issuer() const\n{\n    return issuer;\n}\nvoid token_detail::set_issuer(const std::string &issuer)\n{\n    size_t len = issuer.size() + 1 < (TOKEN_DETAIL_ISSUER_FIX_SIZE) ? issuer.size() + 1 : TOKEN_DETAIL_ISSUER_FIX_SIZE;\n    this->issuer = issuer.substr(0, len);\n}\n\nconst std::string &token_detail::get_address() const\n{\n    return address;\n}\nvoid token_detail::set_address(const std::string &address)\n{\n    size_t len = address.size() + 1 < (TOKEN_DETAIL_ADDRESS_FIX_SIZE) ? address.size() + 1 : TOKEN_DETAIL_ADDRESS_FIX_SIZE;\n    this->address = address.substr(0, len);\n}\n\nconst std::string &token_detail::get_description() const\n{\n    return description;\n}\nvoid token_detail::set_description(const std::string &description)\n{\n    size_t len = description.size() + 1 < (TOKEN_DETAIL_DESCRIPTION_FIX_SIZE) ? description.size() + 1 : TOKEN_DETAIL_DESCRIPTION_FIX_SIZE;\n    this->description = description.substr(0, len);\n}\n\nstd::vector<token_cert_type> token_detail::get_token_cert_mask() const\n{\n    std::vector<token_cert_type> certs;\n    if (is_secondaryissue_legal())\n    {\n        certs.push_back(token_cert_ns::issue);\n    }\n\n    return certs;\n}\n\nbool token_detail::is_token_secondaryissue() const\n{\n    return secondaryissue_threshold >= 128;\n}\n\nvoid token_detail::set_token_secondaryissue()\n{\n    if (!is_token_secondaryissue())\n    {\n        secondaryissue_threshold += 128;\n    }\n}\n\nuint8_t token_detail::get_secondaryissue_threshold() const\n{\n    if (is_token_secondaryissue())\n        return secondaryissue_threshold - 128;\n    else\n        return secondaryissue_threshold;\n}\n\nvoid token_detail::set_secondaryissue_threshold(uint8_t share)\n{\n    BITCOIN_ASSERT(share < 128);\n    secondaryissue_threshold = share;\n}\n\nbool token_detail::is_secondaryissue_threshold_value_ok() const\n{\n    return is_secondaryissue_threshold_value_ok(get_secondaryissue_threshold());\n}\n\nbool token_detail::is_secondaryissue_legal() const\n{\n    return is_secondaryissue_legal(get_secondaryissue_threshold());\n}\n\nbool token_detail::is_secondaryissue_forbidden(uint8_t threshold)\n{\n    return threshold == forbidden_secondaryissue_threshold;\n}\n\nbool token_detail::is_secondaryissue_freely(uint8_t threshold)\n{\n    return threshold == freely_secondaryissue_threshold;\n}\n\nbool token_detail::is_secondaryissue_threshold_value_ok(uint8_t threshold)\n{\n    return is_secondaryissue_forbidden(threshold) || is_secondaryissue_legal(threshold);\n}\n\nbool token_detail::is_secondaryissue_legal(uint8_t threshold)\n{\n    return is_secondaryissue_freely(threshold) || ((threshold >= 1) && (threshold <= 100));\n}\n\nbool token_detail::is_secondaryissue_owns_enough(uint64_t own, uint64_t total, uint8_t threshold)\n{\n    if (is_secondaryissue_freely(threshold))\n        return true;\n    if (!is_secondaryissue_legal(threshold))\n        return false;\n    uint64_t value_needed = (uint64_t)(((double)total) / 100 * threshold);\n    return (value_needed == 0) || (own >= value_needed - 1); // allow 1 inaccurate\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/txs/token/token_transfer.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/txs/token/token_transfer.hpp>\n\n#include <sstream>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n#include <json/minijson_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nbool token_balances::operator<(const token_balances &other) const\n{\n    typedef std::tuple<std::string, std::string, uint64_t, uint64_t> cmp_tuple;\n    return cmp_tuple(symbol, address, unspent_token, locked_token) < cmp_tuple(other.symbol, other.address, other.unspent_token, other.locked_token);\n}\n\ntoken_transfer::token_transfer()\n{\n    reset();\n}\ntoken_transfer::token_transfer(const std::string &symbol, uint64_t quantity) : symbol(symbol), quantity(quantity)\n{\n}\ntoken_transfer token_transfer::factory_from_data(const data_chunk &data)\n{\n    token_transfer instance;\n    instance.from_data(data);\n    return instance;\n}\n\ntoken_transfer token_transfer::factory_from_data(std::istream &stream)\n{\n    token_transfer instance;\n    instance.from_data(stream);\n    return instance;\n}\n\ntoken_transfer token_transfer::factory_from_data(reader &source)\n{\n    token_transfer instance;\n    instance.from_data(source);\n    return instance;\n}\n\nbool token_transfer::is_valid() const\n{\n    return !(symbol.empty() || quantity == 0 || symbol.size() + 1 > TOKEN_TRANSFER_SYMBOL_FIX_SIZE);\n}\n\nvoid token_transfer::reset()\n{\n    symbol = \"\";\n    quantity = 0;\n}\n\nbool token_transfer::from_data(const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(istream);\n}\n\nbool token_transfer::from_data(std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(source);\n}\n\nbool token_transfer::from_data(reader &source)\n{\n    reset();\n    symbol = source.read_string();\n    quantity = source.read_8_bytes_little_endian();\n\n    auto result = static_cast<bool>(source);\n    if (!result)\n        reset();\n\n    return result;\n}\n\ndata_chunk token_transfer::to_data() const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream);\n    ostream.flush();\n    //BITCOIN_ASSERT(data.size() == serialized_size());\n    return data;\n}\n\nvoid token_transfer::to_data(std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(sink);\n}\n\nvoid token_transfer::to_data(writer &sink) const\n{\n    sink.write_string(symbol);\n    sink.write_8_bytes_little_endian(quantity);\n}\n\nuint64_t token_transfer::serialized_size() const\n{\n    size_t len = symbol.size() + 8 + 1;\n    return std::min(len, TOKEN_TRANSFER_FIX_SIZE);\n}\n\nstd::string token_transfer::to_string() const\n{\n    std::ostringstream ss;\n\n    ss << \"\\t symbol = \" << symbol << \"\\n\"\n       << \"\\t quantity = \" << quantity << \"\\n\";\n\n    return ss.str();\n}\n\nconst std::string &token_transfer::get_symbol() const\n{\n    return symbol;\n}\nvoid token_transfer::set_symbol(const std::string &symbol)\n{\n    size_t len = std::min(symbol.size() + 1, TOKEN_TRANSFER_SYMBOL_FIX_SIZE);\n    this->symbol = symbol.substr(0, len);\n}\n\nuint64_t token_transfer::get_quantity() const\n{\n    return quantity;\n}\nvoid token_transfer::set_quantity(uint64_t quantity)\n{\n    this->quantity = quantity;\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/txs/ucn/ucn.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/txs/ucn/ucn.hpp>\n#include <sstream>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin {\nnamespace chain {\n\nucn::ucn()\n{\n    value = 0;\n}\nucn::ucn(uint64_t value):\n    value(value)\n{\n\n}\n\nucn ucn::factory_from_data(const data_chunk& data)\n{\n    ucn instance;\n    instance.from_data(data);\n    return instance;\n}\n\nucn ucn::factory_from_data(std::istream& stream)\n{\n    ucn instance;\n    instance.from_data(stream);\n    return instance;\n}\n\nucn ucn::factory_from_data(reader& source)\n{\n    ucn instance;\n    instance.from_data(source);\n    return instance;\n}\n\nvoid ucn::reset()\n{\n    value= 0;\n}\nbool ucn::is_valid() const\n{\n    return true;\n}\n\nbool ucn::from_data(const data_chunk& data)\n{\n    data_source istream(data);\n    return from_data(istream);\n}\n\nbool ucn::from_data(std::istream& stream)\n{\n    istream_reader source(stream);\n    return from_data(source);\n}\n\nbool ucn::from_data(reader& source)\n{\n    /*\n    reset();\n    value = source.read_8_bytes_little_endian();\n    auto result = static_cast<bool>(source);\n\n    return result;\n    */\n    return true;\n}\n\ndata_chunk ucn::to_data() const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream);\n    ostream.flush();\n    //BITCOIN_ASSERT(data.size() == serialized_size());\n    return data;\n}\n\nvoid ucn::to_data(std::ostream& stream) const\n{\n    ostream_writer sink(stream);\n    to_data(sink);\n}\n\nvoid ucn::to_data(writer& sink) const\n{\n    //sink.write_8_bytes_little_endian(value); // not use ucn now\n}\n\nuint64_t ucn::serialized_size() const\n{\n    //uint64_t size = 8;\n    //return size;\n    return 0; // not insert ept into transaction\n}\n\nstd::string ucn::to_string() const\n{\n    std::ostringstream ss;\n    ss << \"\\t value = \" << value << \"\\n\";\n\n    return ss.str();\n}\nuint64_t ucn::get_value() const\n{\n    return value;\n}\n\nvoid ucn::set_value(uint64_t value)\n{\n    this->value = value;\n}\n\n} // namspace chain\n} // namspace libbitcoin\n"
  },
  {
    "path": "src/UChainService/txs/ucn/ucn_award.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/txs/ucn/ucn_award.hpp>\n#include <sstream>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nucn_award::ucn_award()\n{\n    height = 0;\n}\nucn_award::ucn_award(uint64_t height) : height(height)\n{\n}\n\nucn_award ucn_award::factory_from_data(const data_chunk &data)\n{\n    ucn_award instance;\n    instance.from_data(data);\n    return instance;\n}\n\nucn_award ucn_award::factory_from_data(std::istream &stream)\n{\n    ucn_award instance;\n    instance.from_data(stream);\n    return instance;\n}\n\nucn_award ucn_award::factory_from_data(reader &source)\n{\n    ucn_award instance;\n    instance.from_data(source);\n    return instance;\n}\n\nvoid ucn_award::reset()\n{\n    height = 0;\n}\nbool ucn_award::is_valid() const\n{\n    return true;\n}\n\nbool ucn_award::from_data(const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(istream);\n}\n\nbool ucn_award::from_data(std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(source);\n}\n\nbool ucn_award::from_data(reader &source)\n{\n    reset();\n    height = source.read_8_bytes_little_endian();\n    auto result = static_cast<bool>(source);\n\n    return result;\n}\n\ndata_chunk ucn_award::to_data() const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream);\n    ostream.flush();\n    //BITCOIN_ASSERT(data.size() == serialized_size());\n    return data;\n}\n\nvoid ucn_award::to_data(std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(sink);\n}\n\nvoid ucn_award::to_data(writer &sink) const\n{\n    sink.write_8_bytes_little_endian(height);\n}\n\nuint64_t ucn_award::serialized_size() const\n{\n    //uint64_t size = 8;\n    return 8;\n}\n\nstd::string ucn_award::to_string() const\n{\n    std::ostringstream ss;\n    ss << \"\\t height = \" << height << \"\\n\";\n\n    return ss.str();\n}\nuint64_t ucn_award::get_height() const\n{\n    return height;\n}\n\nvoid ucn_award::set_height(uint64_t height)\n{\n    this->height = height;\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/txs/uid/blockchain_uid.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/txs/uid/blockchain_uid.hpp>\n\n#include <sstream>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nblockchain_uid::blockchain_uid()\n{\n    reset();\n}\nblockchain_uid::blockchain_uid(uint32_t version, const output_point &tx_point,\n                               uint64_t height, uint32_t status, const uid_detail &uid) : version_(version), tx_point_(tx_point), height_(height), status_(status), uid_(uid)\n{\n}\n\nblockchain_uid blockchain_uid::factory_from_data(const data_chunk &data)\n{\n    blockchain_uid instance;\n    instance.from_data(data);\n    return instance;\n}\n\nblockchain_uid blockchain_uid::factory_from_data(std::istream &stream)\n{\n    blockchain_uid instance;\n    instance.from_data(stream);\n    return instance;\n}\n\nblockchain_uid blockchain_uid::factory_from_data(reader &source)\n{\n    blockchain_uid instance;\n    instance.from_data(source);\n    return instance;\n}\nbool blockchain_uid::is_valid() const\n{\n    return true;\n}\n\nvoid blockchain_uid::reset()\n{\n    version_ = 0;\n    tx_point_ = output_point();\n    height_ = 0;\n    status_ = address_invalid;\n    uid_ = uid_detail();\n}\n\nbool blockchain_uid::from_data(const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(istream);\n}\n\nbool blockchain_uid::from_data(std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(source);\n}\n\nbool blockchain_uid::from_data(reader &source)\n{\n    reset();\n\n    version_ = source.read_4_bytes_little_endian();\n    tx_point_.from_data(source);\n    height_ = source.read_8_bytes_little_endian();\n    status_ = source.read_4_bytes_little_endian();\n    uid_.from_data(source);\n\n    return true;\n}\n\ndata_chunk blockchain_uid::to_data() const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream);\n    ostream.flush();\n    //BITCOIN_ASSERT(data.size() == serialized_size());\n    return data;\n}\n\nvoid blockchain_uid::to_data(std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(sink);\n}\n\nvoid blockchain_uid::to_data(writer &sink) const\n{\n    sink.write_4_bytes_little_endian(version_);\n    tx_point_.to_data(sink);\n    sink.write_8_bytes_little_endian(height_);\n    sink.write_4_bytes_little_endian(status_);\n    uid_.to_data(sink);\n}\n\nuint64_t blockchain_uid::serialized_size() const\n{\n    return 4 + tx_point_.serialized_size() + 8 + 4 + uid_.serialized_size();\n}\n\n#ifdef UC_DEBUG\nstd::string blockchain_uid::to_string() const\n{\n    std::ostringstream ss;\n\n    ss << \"\\t version = \" << version_ << \"\\n\"\n       << \"\\t tx_point = \" << tx_point_.to_string() << \"\\n\"\n       << \"\\t height = \" << height_ << \"\\n\"\n       << \"\\t status = \" << get_status_string().c_str() << \"\\n\"\n       << \"\\t uid = \" << uid_.to_string() << \"\\n\";\n\n    return ss.str();\n}\n\n#endif\nconst uint32_t &blockchain_uid::get_version() const\n{\n    return version_;\n}\nvoid blockchain_uid::set_version(const uint32_t &version_)\n{\n    this->version_ = version_;\n}\n\nconst output_point &blockchain_uid::get_tx_point() const\n{\n    return tx_point_;\n}\nvoid blockchain_uid::set_tx_point(const output_point &tx_point_)\n{\n    this->tx_point_ = tx_point_;\n}\n\nconst uint64_t &blockchain_uid::get_height() const\n{\n    return height_;\n}\nvoid blockchain_uid::set_height(const uint64_t &height_)\n{\n    this->height_ = height_;\n}\n\nconst uid_detail &blockchain_uid::get_uid() const\n{\n    return uid_;\n}\nvoid blockchain_uid::set_uid(const uid_detail &uid_)\n{\n    this->uid_ = uid_;\n}\n\nvoid blockchain_uid::set_status(const uint32_t &status)\n{\n    this->status_ = status;\n}\nconst uint32_t &blockchain_uid::get_status() const\n{\n    return this->status_;\n}\n\nstd::string blockchain_uid::get_status_string() const\n{\n    std::string strStatus;\n    switch (this->status_)\n    {\n    case address_invalid:\n        strStatus = \"invalid\";\n        break;\n    case address_current:\n        strStatus = \"current\";\n        break;\n    case address_history:\n        strStatus = \"history\";\n        break;\n    }\n\n    return strStatus;\n}\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/txs/uid/uid.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/txs/uid/uid.hpp>\n#include <UChainService/txs/variant.hpp>\n#include <UChainService/txs/uid/uid_detail.hpp>\n#include <sstream>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nuid::uid()\n{\n    reset();\n}\nuid::uid(uint32_t status, const uid_detail &detail) : status(status), data(detail)\n{\n}\n\nuid uid::factory_from_data(const data_chunk &data)\n{\n    uid instance;\n    instance.from_data(data);\n    return instance;\n}\n\nuid uid::factory_from_data(std::istream &stream)\n{\n    uid instance;\n    instance.from_data(stream);\n    return instance;\n}\n\nuid uid::factory_from_data(reader &source)\n{\n    uid instance;\n    instance.from_data(source);\n    return instance;\n}\n\nvoid uid::reset()\n{\n    status = 0; //uid_status::uid_none;\n    data.reset();\n}\n\nbool uid::is_valid() const\n{\n    return data.is_valid();\n}\n\nbool uid::is_valid_type() const\n{\n    return ((UID_DETAIL_TYPE == status) || (UID_TRANSFERABLE_TYPE == status));\n}\n\nbool uid::from_data(const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(istream);\n}\n\nbool uid::from_data(std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(source);\n}\n\nbool uid::from_data(reader &source)\n{\n    reset();\n\n    status = source.read_4_bytes_little_endian();\n    auto result = static_cast<bool>(source);\n\n    if (result && is_valid_type())\n    {\n        result = data.from_data(source);\n    }\n    else\n    {\n        result = false;\n        reset();\n    }\n\n    return result;\n}\n\ndata_chunk uid::to_data() const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream);\n    ostream.flush();\n    //BITCOIN_ASSERT(data.size() == serialized_size());\n    return data;\n}\n\nvoid uid::to_data(std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(sink);\n}\n\nvoid uid::to_data(writer &sink) const\n{\n    sink.write_4_bytes_little_endian(status);\n    data.to_data(sink);\n}\n\nuint64_t uid::serialized_size() const\n{\n    return 4 + data.serialized_size();\n}\n\nstd::string uid::to_string() const\n{\n    std::ostringstream ss;\n    ss << \"\\t status = \" << status << \"\\n\";\n    ss << data.to_string();\n    return ss.str();\n}\n\nuint32_t uid::get_status() const\n{\n    return status;\n}\nvoid uid::set_status(uint32_t status)\n{\n    this->status = status;\n}\nvoid uid::set_data(const uid_detail &detail)\n{\n    this->data = detail;\n}\n\nconst uid_detail &uid::get_data() const\n{\n    return this->data;\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/txs/uid/uid_detail.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/txs/uid/uid_detail.hpp>\n\n#include <sstream>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n#include <json/minijson_writer.hpp>\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nuid_detail::uid_detail()\n{\n    reset();\n}\n\nuid_detail::uid_detail(\n    const std::string &symbol, const std::string &address)\n    : symbol(symbol), address(address)\n{\n}\n\nuid_detail uid_detail::factory_from_data(const data_chunk &data)\n{\n    uid_detail instance;\n    instance.from_data(data);\n    return instance;\n}\n\nuid_detail uid_detail::factory_from_data(std::istream &stream)\n{\n    uid_detail instance;\n    instance.from_data(stream);\n    return instance;\n}\n\nuid_detail uid_detail::factory_from_data(reader &source)\n{\n    uid_detail instance;\n    instance.from_data(source);\n    return instance;\n}\nbool uid_detail::is_valid() const\n{\n    return !(symbol.empty() || count_size() > UID_DETAIL_FIX_SIZE);\n}\n\nvoid uid_detail::reset()\n{\n    symbol = \"\";\n    address = \"\";\n}\n\nbool uid_detail::from_data(const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(istream);\n}\n\nbool uid_detail::from_data(std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(source);\n}\n\nbool uid_detail::from_data(reader &source)\n{\n    reset();\n\n    symbol = source.read_string();\n    address = source.read_string();\n\n    auto result = static_cast<bool>(source);\n    if (!result)\n        reset();\n\n    return result;\n}\n\ndata_chunk uid_detail::to_data() const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream);\n    ostream.flush();\n    //BITCOIN_ASSERT(data.size() == serialized_size());\n    return data;\n}\n\nvoid uid_detail::to_data(std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(sink);\n}\n\nvoid uid_detail::to_data(writer &sink) const\n{\n    sink.write_string(symbol);\n    sink.write_string(address);\n}\n\nuint64_t uid_detail::serialized_size() const\n{\n    size_t len = count_size();\n    return std::min(UID_DETAIL_FIX_SIZE, len);\n}\n\nuint32_t uid_detail::count_size() const\n{\n    return symbol.size() + address.size() + 2;\n}\n\nbool uid_detail::operator<(const uid_detail &other) const\n{\n    auto ret = 0;\n    if ((ret = symbol.compare(other.symbol)) < 0 || (ret == 0 && address.compare(other.address) < 0))\n    {\n        return true;\n    }\n\n    return false;\n}\n\nstd::string uid_detail::to_string() const\n{\n    std::ostringstream ss;\n\n    ss << \"\\t symbol = \" << symbol << \"\\n\"\n       << \"\\t address = \" << address << \"\\n\";\n\n    return ss.str();\n}\n\nvoid uid_detail::to_json(std::ostream &output)\n{\n    minijson::object_writer json_writer(output);\n    json_writer.write(\"symbol\", symbol);\n    json_writer.write(\"address\", address);\n    json_writer.close();\n}\n\nconst std::string &uid_detail::get_symbol() const\n{\n    return symbol;\n}\n\nvoid uid_detail::set_symbol(const std::string &symbol)\n{\n    size_t len = std::min(symbol.size() + 1, UID_DETAIL_SYMBOL_FIX_SIZE);\n    this->symbol = symbol.substr(0, len);\n}\n\nconst std::string &uid_detail::get_address() const\n{\n    return address;\n}\n\nvoid uid_detail::set_address(const std::string &address)\n{\n    size_t len = std::min(address.size() + 1, UID_DETAIL_ADDRESS_FIX_SIZE);\n    this->address = address.substr(0, len);\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/txs/utility/callstack.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/txs/utility/callstack.hpp>\n#include <boost/format.hpp>\n#include <fstream>\n#ifndef _WIN32\n#ifndef __ANDROID__\n#include <execinfo.h>\n#endif\n#endif\n\nnamespace libbitcoin\n{\nvoid call_stack(std::ostream &os)\n{\n#ifndef _WIN32\n#ifndef __ANDROID__\n    int size = 1024;\n    int j = 0, nptrs = 0;\n\n    void *buffer[1024];\n    char **strings;\n\n    nptrs = backtrace(buffer, size);\n    os << \"backtrace() returned \" << nptrs << \" addresses\\n\";\n\n    strings = backtrace_symbols(buffer, nptrs);\n    if (strings == nullptr)\n    {\n        os << \"backtrace_symbols failed\" << '\\n';\n        exit(EXIT_FAILURE);\n    }\n\n    for (j = 0; j < nptrs; j++)\n    {\n        os << strings[j] << '\\n';\n    }\n\n    free(strings);\n#endif\n#endif\n}\n\nvoid do_callstack(const std::string &name)\n{\n    std::fstream fout;\n    fout.open(name, std::ios_base::ate | std::ios_base::out);\n    if (!fout.good())\n    {\n        boost::format fmt{\"open file %s failed\"};\n        auto msg = fmt % name;\n        throw std::runtime_error{msg.str()};\n    }\n    call_stack(fout);\n}\n\n} //namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/txs/utility/daemon.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/txs/utility/daemon.hpp>\n\n#ifndef _WIN32\n\n#include <cerrno>\n#include <cstdlib>  // quick_exit()\n#include <fcntl.h>  // open()\n#include <unistd.h> // fork()\n#include <stdexcept>\n#include <signal.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n\n#endif\n\nnamespace libbitcoin\n{\nvoid daemon()\n{\n#ifndef _WIN32\n    pid_t pid{fork()};\n    if (pid < 0)\n    {\n        throw std::runtime_error{\"fork() failed\"};\n    }\n\n    if (pid != 0)\n    {\n        // Exit parent process using system version of exit() to avoid flushing standard streams.\n        // FIXME: use quick_exit() when available on OSX.\n        _exit(0);\n    }\n\n    // Detach from controlling terminal by making process a session leader.\n    if (setsid() < 0)\n    {\n        throw std::runtime_error{\"setsid() failed\"};\n    }\n\n    // Forking again ensures that the daemon process is not a session leader, and therefore cannot\n    // regain access to a controlling terminal.\n    pid = fork();\n    if (pid < 0)\n    {\n        throw std::runtime_error{\"fork() failed\"};\n    }\n\n    if (pid != 0)\n    {\n        // FIXME: use quick_exit() when available on OSX.\n        _exit(0);\n    }\n\n    // Re-open standard input.\n    close(STDIN_FILENO);\n    if (open(\"/dev/null\", O_RDONLY) < 0)\n    {\n        throw std::runtime_error{\"open() failed\"};\n    }\n\n    // Close all non-standard file handles.\n    const long fds{sysconf(_SC_OPEN_MAX)};\n    for (long fd{STDERR_FILENO + 1}; fd < fds; ++fd)\n    {\n        close(fd);\n    }\n\n    // Note that the standard output handles are unchanged.\n#endif\n}\n\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/txs/utility/path.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/txs/utility/path.hpp>\n#include <boost/thread/once.hpp>\n\n#ifdef _WIN32\n#include <Shlobj.h>\n#endif\n\nnamespace libbitcoin\n{\n\nconst boost::filesystem::path &default_data_path()\n{\n    static boost::filesystem::path default_path(\"\");\n    static boost::once_flag once = BOOST_ONCE_INIT;\n    auto path_init = []() {\n        namespace fs = boost::filesystem;\n        // Windows < Vista: C:\\Documents and Settings\\Username\\Application Data\\UChain\n        // Windows >= Vista: C:\\Users\\Username\\AppData\\Roaming\\UChain\n        // Mac: ~/Library/Application Support/UChain\n        // Unix: ~/.UChain\n#ifdef _WIN32\n        // Windows\n#ifdef UNICODE\n        wchar_t file_path[MAX_PATH] = {0};\n#else\n        char file_path[MAX_PATH] = {0};\n#endif\n        SHGetSpecialFolderPath(NULL, file_path, CSIDL_APPDATA, true);\n        fs::path pathRet = boost::filesystem::path(file_path) / \"UChain\";\n        fs::create_directories(pathRet);\n        default_path = pathRet;\n#else\n        fs::path pathRet;\n        char *pszHome = getenv(\"HOME\");\n        if (pszHome == nullptr || strlen(pszHome) == 0)\n            pathRet = fs::path(\"/\");\n        else\n            pathRet = fs::path(pszHome);\n#ifdef MAC_OSX\n        // Mac\n        pathRet /= \"Library/Application Support\";\n        fs::create_directories(pathRet / \"UChain\");\n        default_path = pathRet / \"UChain\";\n#else\n        // Unix\n        fs::create_directories(pathRet / \".UChain\");\n        default_path = pathRet / \".UChain\";\n#endif\n#endif\n    };\n    boost::call_once(path_init, once);\n    return default_path;\n}\n\nboost::filesystem::path webpage_path()\n{\n#ifdef _MSC_VER\n#ifdef UNICODE\n    wchar_t tmp[MAX_PATH * 2] = {0};\n#else\n    char tmp[MAX_PATH * 2] = {0};\n#endif\n    GetModuleFileName(NULL, tmp, MAX_PATH * 2);\n    return boost::filesystem::path(tmp).parent_path() / \"uc-htmls\";\n#else\n    return default_data_path() / \"uc-htmls\";\n#endif\n}\n\n} //namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/txs/wallet/wallet.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/txs/wallet/wallet.hpp>\n\n#include <sstream>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\n#ifdef UC_DEBUG\n#include <json/minijson_writer.hpp>\n#endif\n\n#include <UChain/coin/math/crypto.hpp>\n#include <UChain/coin.hpp>\nusing namespace libbitcoin::wallet;\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nwallet_multisig::wallet_multisig()\n    : hd_index_(0), m_(0), n_(0)\n{\n}\n\nwallet_multisig::wallet_multisig(\n    uint32_t hd_index, uint8_t m, uint8_t n,\n    std::vector<std::string> &&cosigner_pubkeys, std::string &pubkey)\n    : hd_index_(hd_index), m_(m), n_(n), cosigner_pubkeys_(std::move(cosigner_pubkeys)), pubkey_(pubkey)\n{\n}\n\nvoid wallet_multisig::set_hd_index(uint32_t hd_index)\n{\n    hd_index_ = hd_index;\n}\n\nuint32_t wallet_multisig::get_hd_index() const\n{\n    return hd_index_;\n}\n\nvoid wallet_multisig::set_index(uint32_t index)\n{\n    index_ = index;\n}\n\nuint32_t wallet_multisig::get_index() const\n{\n    return index_;\n}\n\nvoid wallet_multisig::set_m(uint8_t m)\n{\n    m_ = m;\n}\n\nuint8_t wallet_multisig::get_m() const\n{\n    return m_;\n}\n\nvoid wallet_multisig::set_n(uint8_t n)\n{\n    n_ = n;\n}\n\nuint8_t wallet_multisig::get_n() const\n{\n    return n_;\n}\n\nconst std::vector<std::string> &wallet_multisig::get_cosigner_pubkeys() const\n{\n    return cosigner_pubkeys_;\n}\n\nvoid wallet_multisig::set_cosigner_pubkeys(std::vector<std::string> &&cosigner_pubkeys)\n{\n    cosigner_pubkeys_ = std::move(cosigner_pubkeys);\n    std::sort(cosigner_pubkeys_.begin(), cosigner_pubkeys_.end());\n}\n\nstd::string wallet_multisig::get_pub_key() const\n{\n    return pubkey_;\n}\n\nvoid wallet_multisig::set_pub_key(std::string &pubkey)\n{\n    pubkey_ = pubkey;\n}\n\nstd::string wallet_multisig::get_description() const\n{\n    return description_;\n}\n\nvoid wallet_multisig::set_description(std::string &description)\n{\n    description_ = description;\n}\n\nstd::string wallet_multisig::get_address() const\n{\n    return address_;\n}\n\nvoid wallet_multisig::set_address(std::string &address)\n{\n    address_ = address;\n}\n\nbool wallet_multisig::from_data(reader &source)\n{\n    hd_index_ = source.read_4_bytes_little_endian();\n    index_ = source.read_4_bytes_little_endian();\n    m_ = source.read_byte();\n    n_ = source.read_byte();\n    pubkey_ = source.read_string();\n    // read consigner pubkeys\n    uint8_t size = source.read_byte();\n    while (size--)\n        cosigner_pubkeys_.push_back(source.read_string());\n\n    description_ = source.read_string();\n    address_ = source.read_string();\n\n    return true;\n}\n\nvoid wallet_multisig::to_data(writer &sink) const\n{\n    sink.write_4_bytes_little_endian(hd_index_);\n    sink.write_4_bytes_little_endian(index_);\n    sink.write_byte(m_);\n    sink.write_byte(n_);\n    sink.write_string(pubkey_);\n    sink.write_byte(cosigner_pubkeys_.size());\n\n    for (auto &each : cosigner_pubkeys_)\n    {\n        sink.write_string(each);\n    }\n\n    //sink.write_string(std::string(\"02b66fcb1064d827094685264aaa90d0126861688932eafbd1d1a4ba149de3308b\"));\n    sink.write_string(description_);\n    sink.write_string(address_);\n}\n\nuint64_t wallet_multisig::serialized_size() const\n{\n    uint64_t size = 4 + 4 + 1 + 1 + (pubkey_.size() + 9) + 1; // hd_index,index,m,n,pubkey,pubkey number\n\n    for (auto &each : cosigner_pubkeys_)\n    {\n        size += (each.size() + 9);\n    }\n    size += (description_.size() + 9);\n    size += (address_.size() + 9);\n    return size;\n}\n\nbool wallet_multisig::operator==(const wallet_multisig &other) const\n{\n    if (hd_index_ != other.hd_index_ || m_ != other.m_ || n_ != other.n_ || pubkey_ != other.pubkey_)\n    {\n        return false;\n    }\n\n    auto &other_pubkeys = other.cosigner_pubkeys_;\n    if (cosigner_pubkeys_.size() != other_pubkeys.size())\n    {\n        return false;\n    }\n\n    for (const auto &pubkey : cosigner_pubkeys_)\n    {\n        auto iter = std::find(other_pubkeys.begin(), other_pubkeys.end(), pubkey);\n        if (iter == other_pubkeys.end())\n        {\n            return false;\n        }\n    }\n\n    return true;\n}\n\nvoid wallet_multisig::reset()\n{\n    hd_index_ = 0;\n    index_ = 0;\n    m_ = 0;\n    n_ = 0;\n    pubkey_ = \"\";\n    cosigner_pubkeys_.clear();\n    description_ = \"\";\n    address_ = \"\";\n}\n\n#ifdef UC_DEBUG\nstd::string wallet_multisig::to_string()\n{\n    std::ostringstream ss;\n\n    ss << \"\\t hd_index = \" << hd_index_ << \"\\n\"\n       << \"\\t index = \" << index_ << \"\\n\"\n       << \"\\t m = \" << m_ << \"\\n\"\n       << \"\\t n = \" << n_ << \"\\n\"\n       << \"\\t pubkey = \" << pubkey_ << \"\\n\"\n       << \"\\t description = \" << description_ << \"\\n\";\n    for (auto &each : cosigner_pubkeys_)\n        ss << \"\\t cosigner-pubkey = \" << each << std::endl;\n    return ss.str();\n}\n#endif\n\nstd::string wallet_multisig::get_multisig_script() const\n{\n    if (m_ == 0 && n_ == 0)\n    {\n        // not initialized\n        return \"\";\n    }\n\n    std::ostringstream ss;\n    ss << std::to_string(m_);\n    for (auto &each : cosigner_pubkeys_)\n        ss << \" [ \" << each << \" ] \";\n    ss << std::to_string(n_) << \" checkmultisig\";\n    return ss.str();\n}\n\nwallet::wallet()\n{\n    reset();\n}\n\nwallet::wallet(\n    const std::string &name, const std::string &mnemonic, const hash_digest &passwd,\n    uint32_t hd_index, uint8_t priority, uint8_t status, uint8_t type)\n    : name(name), mnemonic(mnemonic), passwd(passwd), hd_index(hd_index), priority(priority), status(status), type(type)\n{\n}\n\nwallet wallet::factory_from_data(const data_chunk &data)\n{\n    wallet instance;\n    instance.from_data(data);\n    return instance;\n}\n\nwallet wallet::factory_from_data(std::istream &stream)\n{\n    wallet instance;\n    instance.from_data(stream);\n    return instance;\n}\n\nwallet wallet::factory_from_data(reader &source)\n{\n    wallet instance;\n    instance.from_data(source);\n    return instance;\n}\n\nbool wallet::is_valid() const\n{\n    return true;\n}\n\nvoid wallet::reset()\n{\n    this->name = \"\";\n    this->mnemonic = \"\";\n    //this->passwd = \"\";\n    this->hd_index = 0;\n    this->priority = wallet_priority::common_user; // 0 -- admin user  1 -- common user\n    this->type = wallet_type::common;\n    this->status = wallet_status::normal;\n}\n\nbool wallet::from_data(const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(istream);\n}\n\nbool wallet::from_data(std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(source);\n}\n\nbool wallet::from_data(reader &source)\n{\n    reset();\n    name = source.read_string();\n    //mnemonic = source.read_string();\n\n    // read encrypted mnemonic\n    auto size = source.read_variable_uint_little_endian();\n    data_chunk string_bytes = source.read_data(size);\n    std::string result(string_bytes.begin(), string_bytes.end());\n    mnemonic = result;\n\n    passwd = source.read_hash();\n    hd_index = source.read_4_bytes_little_endian();\n    priority = source.read_byte();\n    //status = source.read_2_bytes_little_endian();\n    type = source.read_byte();\n    status = source.read_byte();\n    if (type == wallet_type::multisignature)\n    {\n        //multisig.from_data(source);\n        wallet_multisig multisig;\n        uint32_t size = source.read_4_bytes_little_endian();\n        while (size--)\n        {\n            multisig.reset();\n            multisig.from_data(source);\n            multisig_vec.push_back(multisig);\n        }\n    }\n    return true;\n}\n\ndata_chunk wallet::to_data() const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream);\n    ostream.flush();\n    //BITCOIN_ASSERT(data.size() == serialized_size()); // serialized_size is not used\n    return data;\n}\n\nvoid wallet::to_data(std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(sink);\n}\n\nvoid wallet::to_data(writer &sink) const\n{\n    sink.write_string(name);\n    sink.write_string(mnemonic);\n    sink.write_hash(passwd);\n    sink.write_4_bytes_little_endian(hd_index);\n    sink.write_byte(priority);\n    //sink.write_2_bytes_little_endian(status);\n    sink.write_byte(type);\n    sink.write_byte(status);\n    if (type == wallet_type::multisignature)\n    {\n        //multisig.to_data(sink);\n        sink.write_4_bytes_little_endian(multisig_vec.size());\n        if (multisig_vec.size())\n        {\n            for (auto &each : multisig_vec)\n            {\n                each.to_data(sink);\n            }\n        }\n    }\n}\n\nuint64_t wallet::serialized_size() const\n{\n    uint64_t size = name.size() + mnemonic.size() + passwd.size() + 4 + 1 + 2 + 2 * 9; // 2 string len\n    if (type == wallet_type::multisignature)\n    {\n        //size += multisig.serialized_size();\n        size += 4; // vector size\n        for (auto &each : multisig_vec)\n            size += each.serialized_size();\n    }\n    return size;\n}\n\nwallet::operator bool() const\n{\n    return (name.empty() || mnemonic.empty());\n}\n\nbool wallet::operator==(const libbitcoin::chain::wallet &other) const\n{\n    return ((name == other.get_name()) && (passwd == other.get_passwd()) && (mnemonic == other.get_mnemonic()));\n}\n\n#ifdef UC_DEBUG\nstd::string wallet::to_string()\n{\n    std::ostringstream ss;\n\n    ss << \"\\t name = \" << name << \"\\n\"\n       << \"\\t mnemonic = \" << mnemonic << \"\\n\"\n       << \"\\t password = \" << passwd.data() << \"\\n\"\n       << \"\\t hd_index = \" << hd_index << \"\\n\"\n       << \"\\t priority = \" << priority << \"\\n\"\n       << \"\\t type = \" << type << \"\\n\"\n       << \"\\t status = \" << status << \"\\n\";\n    if (type == wallet_type::multisignature)\n    {\n        for (auto &each : multisig_vec)\n            ss << \"\\t\\t\" << each.to_string();\n    }\n    return ss.str();\n}\n#endif\n\nconst std::string &wallet::get_name() const\n{\n    return name;\n}\n\nvoid wallet::set_name(const std::string &name)\n{\n    this->name = name;\n}\n\nconst std::string &wallet::get_mnemonic() const\n{\n    return mnemonic; // for wallet == operator\n}\n\nconst std::string &wallet::get_mnemonic(std::string &passphrase, std::string &decry_output) const\n{\n    decrypt_string(mnemonic, passphrase, decry_output);\n    return decry_output;\n}\n\nvoid wallet::set_mnemonic(const std::string &mnemonic, std::string &passphrase)\n{\n    if (!mnemonic.size())\n        throw std::logic_error{\"mnemonic size is 0\"};\n    if (!passphrase.size())\n        throw std::logic_error{\"invalid password!\"};\n    std::string encry_output(\"\");\n\n    encrypt_string(mnemonic, passphrase, encry_output);\n    this->mnemonic = encry_output;\n}\n\nvoid wallet::set_mnemonic(const std::string &mnemonic)\n{\n    this->mnemonic = mnemonic;\n}\n\nconst hash_digest &wallet::get_passwd() const\n{\n    return passwd;\n}\n\nuint32_t wallet::get_hd_index() const\n{\n    return hd_index;\n}\n\nvoid wallet::set_hd_index(uint32_t hd_index)\n{\n    this->hd_index = hd_index;\n}\n\nuint8_t wallet::get_type() const\n{\n    return type;\n}\n\nvoid wallet::set_type(uint8_t type)\n{\n    this->type = type;\n}\n\nuint8_t wallet::get_status() const\n{\n    return status;\n}\n\nvoid wallet::set_status(uint8_t status)\n{\n    this->status = status;\n}\n\nuint8_t wallet::get_priority() const\n{\n    return priority;\n}\n\nvoid wallet::set_priority(uint8_t priority)\n{\n    this->priority = priority;\n}\n\nconst wallet_multisig::list &wallet::get_multisig_vec() const\n{\n    return multisig_vec;\n}\n\nvoid wallet::set_multisig_vec(wallet_multisig::list &&multisig_vec)\n{\n    this->multisig_vec = std::move(multisig_vec);\n}\n\nbool wallet::is_multisig_exist(const wallet_multisig &multisig)\n{\n    auto iter = std::find(multisig_vec.begin(), multisig_vec.end(), multisig);\n    return iter != multisig_vec.end();\n}\n\nvoid wallet::set_multisig(const wallet_multisig &multisig)\n{\n    if (!is_multisig_exist(multisig))\n    {\n        multisig_vec.push_back(multisig);\n    }\n}\n\nvoid wallet::remove_multisig(const wallet_multisig &multisig)\n{\n    for (auto it = multisig_vec.begin(); it != multisig_vec.end();)\n    {\n        if (*it == multisig)\n        {\n            it = multisig_vec.erase(it);\n            break;\n        }\n        else\n        {\n            ++it;\n        }\n    }\n}\n\nstd::shared_ptr<wallet_multisig::list> wallet::get_multisig(const std::string &addr)\n{\n    auto acc_vec = std::make_shared<wallet_multisig::list>();\n    for (auto &each : multisig_vec)\n    {\n        if (addr == each.get_address())\n        {\n            acc_vec->push_back(each);\n        }\n    }\n    return acc_vec;\n}\n\nvoid wallet::modify_multisig(const wallet_multisig &multisig)\n{\n    for (auto &each : multisig_vec)\n    {\n        if (each == multisig)\n        {\n            each = multisig;\n            break;\n        }\n    }\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "src/UChainService/txs/wallet/wallet_address.cpp",
    "content": "/**\n * Copyright (c) 2018-2020 UChain developers \n *\n * This file is part of uc-node.\n *\n * UChain is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n#include <UChainService/txs/wallet/wallet_address.hpp>\n\n#include <sstream>\n#include <boost/iostreams/stream.hpp>\n#include <UChain/coin/utility/container_sink.hpp>\n#include <UChain/coin/utility/container_source.hpp>\n#include <UChain/coin/utility/istream_reader.hpp>\n#include <UChain/coin/utility/ostream_writer.hpp>\n\n#ifdef UC_DEBUG\n#include <json/minijson_writer.hpp>\n#endif\n\n#include <UChain/coin.hpp>\nusing namespace libbitcoin::wallet;\n\nnamespace libbitcoin\n{\nnamespace chain\n{\n\nwallet_address::wallet_address()\n{\n    reset();\n}\n\nwallet_address::wallet_address(\n    const std::string &name, const std::string &prv_key,\n    const std::string &pub_key, uint32_t hd_index, uint64_t balance,\n    const std::string &alias, const std::string &address, uint8_t status) : name(name), prv_key(prv_key), pub_key(pub_key), hd_index(hd_index), balance(balance),\n                                                                            alias(alias), address(address), status_(status)\n{\n}\n\nwallet_address::wallet_address(const wallet_address &other)\n{\n    name = other.name;\n    prv_key = other.prv_key;\n    pub_key = other.pub_key;\n    hd_index = other.hd_index;\n    balance = other.balance;\n    alias = other.alias;\n    address = other.address;\n    status_ = other.status_;\n}\nwallet_address wallet_address::factory_from_data(const data_chunk &data)\n{\n    wallet_address instance;\n    instance.from_data(data);\n    return instance;\n}\n\nwallet_address wallet_address::factory_from_data(std::istream &stream)\n{\n    wallet_address instance;\n    instance.from_data(stream);\n    return instance;\n}\n\nwallet_address wallet_address::factory_from_data(reader &source)\n{\n    wallet_address instance;\n    instance.from_data(source);\n    return instance;\n}\n\nbool wallet_address::is_valid() const\n{\n    return true;\n}\n\nvoid wallet_address::reset()\n{\n    name = \"\";\n    prv_key = \"\";\n    pub_key = \"\";\n    hd_index = 0;\n    balance = 0;\n    alias = \"\";\n    address = \"\";\n    status_ = 0;\n}\n\nbool wallet_address::from_data(const data_chunk &data)\n{\n    data_source istream(data);\n    return from_data(istream);\n}\n\nbool wallet_address::from_data(std::istream &stream)\n{\n    istream_reader source(stream);\n    return from_data(source);\n}\n\nbool wallet_address::from_data(reader &source)\n{\n    reset();\n    name = source.read_fixed_string(ADDRESS_NAME_FIX_SIZE);\n    //prv_key = source.read_fixed_string(ADDRESS_PRV_KEY_FIX_SIZE);\n\n    // read encrypted private key\n    auto size = source.read_variable_uint_little_endian();\n    data_chunk string_bytes = source.read_data(size);\n    std::string result(string_bytes.begin(), string_bytes.end());\n    prv_key = result;\n    //log::trace(\"from_data prv\")<<prv_key;\n\n    pub_key = source.read_fixed_string(ADDRESS_PUB_KEY_FIX_SIZE);\n    hd_index = source.read_4_bytes_little_endian();\n    balance = source.read_8_bytes_little_endian();\n    alias = source.read_fixed_string(ADDRESS_ALIAS_FIX_SIZE);\n    address = source.read_fixed_string(ADDRESS_ADDRESS_FIX_SIZE);\n    status_ = source.read_byte();\n    return true;\n}\n\ndata_chunk wallet_address::to_data() const\n{\n    data_chunk data;\n    data_sink ostream(data);\n    to_data(ostream);\n    ostream.flush();\n    //BITCOIN_ASSERT(data.size() == serialized_size());\n    return data;\n}\n\nvoid wallet_address::to_data(std::ostream &stream) const\n{\n    ostream_writer sink(stream);\n    to_data(sink);\n}\n\nvoid wallet_address::to_data(writer &sink) const\n{\n    sink.write_fixed_string(name, ADDRESS_NAME_FIX_SIZE);\n    //sink.write_fixed_string(prv_key, ADDRESS_PRV_KEY_FIX_SIZE);\n    sink.write_string(prv_key);\n    sink.write_fixed_string(pub_key, ADDRESS_PUB_KEY_FIX_SIZE);\n    sink.write_4_bytes_little_endian(hd_index);\n    sink.write_8_bytes_little_endian(balance);\n    sink.write_fixed_string(alias, ADDRESS_ALIAS_FIX_SIZE);\n    sink.write_fixed_string(address, ADDRESS_ADDRESS_FIX_SIZE);\n    sink.write_byte(status_);\n}\n\nuint64_t wallet_address::serialized_size() const\n{\n    return name.size() + prv_key.size() + pub_key.size() + 4 + 8 + alias.size() + address.size() + 1 + 5; // 5 \"string length\" byte\n}\n\n#ifdef UC_DEBUG\nstd::string wallet_address::to_string()\n{\n    std::ostringstream ss;\n\n    ss << \"\\t name = \" << name << \"\\n\"\n       << \"\\t prv_key = \" << prv_key << \"\\n\"\n       << \"\\t pub_key = \" << pub_key << \"\\n\"\n       << \"\\t hd_index = \" << hd_index << \"\\n\"\n       << \"\\t balance = \" << balance << \"\\n\"\n       << \"\\t alias = \" << alias << \"\\n\"\n       << \"\\t address = \" << address << \"\\n\"\n       << \"\\t status = \" << status_ << \"\\n\";\n\n    return ss.str();\n}\n#endif\n\nconst std::string &wallet_address::get_name() const\n{\n    return name;\n}\nvoid wallet_address::set_name(const std::string &name)\n{\n    this->name = name;\n}\n\nconst std::string wallet_address::get_prv_key(std::string &passphrase) const\n{\n    std::string decry_output(\"\");\n\n    decrypt_string(prv_key, passphrase, decry_output);\n    return decry_output;\n}\nconst std::string wallet_address::get_prv_key() const\n{\n    return prv_key;\n}\nvoid wallet_address::set_prv_key(const std::string &prv_key, std::string &passphrase)\n{\n    std::string encry_output(\"\");\n\n    encrypt_string(prv_key, passphrase, encry_output);\n    this->prv_key = encry_output;\n}\nvoid wallet_address::set_prv_key(const std::string &prv_key)\n{\n    this->prv_key = prv_key;\n}\n\nconst std::string &wallet_address::get_pub_key() const\n{\n    return pub_key;\n}\nvoid wallet_address::set_pub_key(const std::string &pub_key)\n{\n    this->pub_key = pub_key;\n}\n\nuint32_t wallet_address::get_hd_index() const\n{\n    return hd_index;\n}\nvoid wallet_address::set_hd_index(uint32_t hd_index)\n{\n    this->hd_index = hd_index;\n}\n\nuint64_t wallet_address::get_balance() const\n{\n    return balance;\n}\nvoid wallet_address::set_balance(uint64_t balance)\n{\n    this->balance = balance;\n}\n\nconst std::string &wallet_address::get_alias() const\n{\n    return alias;\n}\nvoid wallet_address::set_alias(const std::string &alias)\n{\n    this->alias = alias;\n}\n\nconst std::string &wallet_address::get_address() const\n{\n    return address;\n}\nvoid wallet_address::set_address(const std::string &address)\n{\n    this->address = address;\n}\n\nuint8_t wallet_address::get_status() const\n{\n    return status_;\n}\nvoid wallet_address::set_status(uint8_t status)\n{\n    status_ = status;\n}\n\n} // namespace chain\n} // namespace libbitcoin\n"
  },
  {
    "path": "test/uc-cli-1.sh",
    "content": "#!/bin/bash\ntrap \"exit 1\" TERM\nTOP_PID=$$\n\nfunction alert()\n{\n\t        echo \"$(tput setaf 1)Error!\"\n\t\t kill -s TERM $TOP_PID\n}\n\nif ./uc-cli showinfo |grep \"message\"; then\n        alert\nfi\n\nif ./uc-cli showpeers|grep \"message\"; then\n        alert\nfi\n\nif ./uc-cli addpeer 192.168.16.147:5682|grep \"message\"; then\n\talert\nfi\n:<<BLOCK \nif ./uc-cli shutdown|grep \"message\"; then\n       \talert\n\tfi\nBLOCK\nif ./uc-cli  createwallet ceshi1 123456|grep \"message\"; then\n        alert\n\tfi\n\nif ./uc-cli checkwalletinfo yujiali3 123456 island|grep \"message\" ; then\n\t        alert\n\tfi\n\nif  ./uc-cli addaddress yujiali3 123456|grep \"message\"; then\n                alert\n\t  fi\n\nif  ./uc-cli validateaddress Ub9Utbs3hHMharWZBenvU8TjbygAXNtD5L|grep \"code\" -A1; then\n       alert\n fi\nif  ./uc-cli showaddresses yujiali3 123456|grep \"message\"; then \n\t       alert \n\t        fi\nif  ./uc-cli exportkeyfile yujiali3 123456 island /test/ucd/bin|grep \"message\"; then                     \n\t       alert\n\t       fi\n if  ./uc-cli deletewallet yujiali3 123456 island /test/ucd/bin|grep \"message\"; then\n\t alert\n fi\n if  ./uc-cli changepass -p 12345 yujiali3 123456|grep \"message\"; then\n\t          alert \n\t\t   fi\n if ./uc-cli importkeyfile yujiali3 123456  /test/ucd/bin/uc_keystore_yujiali3.json |grep \"message\"; then\n\t                   alert\n\t\t\t     fi\n\n :<<BLOCK if  ./uc-cli startmining snake02 123456 UcuW7wVu198Nuzok8eeMDUNEZQoGqQRRz5|grep \"message\"; then\n    alert\n    fi    \n\nif ./uc-cli startmining snake03 123456 URaJN6xB2vmFGQcXDkLkrDjaSxu9qJN4Zr |grep \"message\"; then\n\t         alert\n\t\t     fi\n\nif ./uc-cli stopmining snake02 123456 |grep \"message\"; then\n\t    alert\n\t        fi\nBLOCK\nif ./uc-cli showminers |grep \"message\"; then\n\t    alert\n\t        fi\nif ./uc-cli showblockheight |grep \"message\"; then\n\t    alert\n\t        fi\nif ./uc-cli showblock 324904 |grep \"message\"; then\n    alert\n   fi\n\nif ./uc-cli showblockheader |grep \"message\"; then\n           alert\n       fi\t\nif ./uc-cli showheaderext 324904 |grep \"message\"; then\n          alert\n      fi\t  \nif ./uc-cli showtxpool |grep \"message\"; then\n      alert\n    fi \nif ./uc-cli showtx 627e89bab348941810412ca966bd89959c6b2893e7d88385cc7204848c33a43a |grep \"message\"; then\n        alert\n    fi\nif ./uc-cli showtxs yujiali3 123456 |grep -v \"2003\" |grep \"code\" -A1 ; then\n         alert\n      fi\t  \nvar=$(./uc-cli createrawtx -r Ub9Utbs3hHMharWZBenvU8TjbygAXNtD5L:90000 -r UaeG98wu548vYTYTogvEevVPuC6ToUST3z:90000 -s UNfrtAxhJRi83PjTPjV3yNPKnjLYR22Bhx -t 0) \necho $var \nif ./uc-cli createrawtx -r Ub9Utbs3hHMharWZBenvU8TjbygAXNtD5L:90000 -r UaeG98wu548vYTYTogvEevVPuC6ToUST3z:90000 -s UNfrtAxhJRi83PjTPjV3yNPKnjLYR22Bhx -t 0 |grep \"message\";then\n\talert\nfi\n\n if ./uc-cli decoderawtx $var |grep \"message\"; then\n \t alert\n   fi\n   var1=$(./uc-cli signrawtx yang 123456 $var)\n     echo $var1    \nif ./uc-cli signrawtx yang 123456 $var\t|grep \"message\"; then\n\t    alert\n\t        fi \n./uc-cli sendrawtx $(echo $var1 | awk -F '\"' '{print $8}')\t\t\n\n\n\n\n  a=$(./uc-cli createrawtx -r Ub9Utbs3hHMharWZBenvU8TjbygAXNtD5L:10000  -s Ub9Utbs3hHMharWZBenvU8TjbygAXNtD5L -t 1) \n echo $a\nif ./uc-cli createrawtx -r Ub9Utbs3hHMharWZBenvU8TjbygAXNtD5L:10000  -s Ub9Utbs3hHMharWZBenvU8TjbygAXNtD5L -t 1|grep \"message\";then\n       alert\nfi\nif ./uc-cli decoderawtx $a |grep \"message\";then\n\talert\nfi\na1=$(./uc-cli signrawtx yujiali3 123456 $a)\necho $a1\n./uc-cli sendrawtx $(echo $a1 | awk -F '\"' '{print $8}')\n\n\n\n./uc-cli createrawtx -n BLOCK -r Ub9Utbs3hHMharWZBenvU8TjbygAXNtD5L:9 -s UcuW7wVu198Nuzok8eeMDUNEZQoGqQRRz5 -t 3 \n\nif ./uc-cli vote -r UcuW7wVu198Nuzok8eeMDUNEZQoGqQRRz5:9 yang 123456 UNfrtAxhJRi83PjTPjV3yNPKnjLYR22Bhx |grep \"message\"; then\n    alert\n    fi\n   \n./uc-cli createrawtx -n VOTE -r Ub9Utbs3hHMharWZBenvU8TjbygAXNtD5L:1 -s UcuW7wVu198Nuzok8eeMDUNEZQoGqQRRz5 -t 3\n\n\nif ./uc-cli checkpublickey yujiali3 123456 Ub9Utbs3hHMharWZBenvU8TjbygAXNtD5L |grep \"message\"; then\n    alert\n    fi\n\n\nif  ./uc-cli checkpublickey yujiali4 123456 UaeG98wu548vYTYTogvEevVPuC6ToUST3z |grep \"message\"; then\n    alert\n    fi\n\n\nif ./uc-cli createmultisigaddress -m 2 -n 2 -s 03c8a6604e22c3f5174da08c79ab3a15f99817b529a6785dfc9816d351b2f17154 -k 03d8153cc69fc4f1e9a2c0904073faf253efd7a9580c925b365134bda74e942906 yujiali3 123456 |grep \"message\"; then\n    alert\n    fi\n\nif ./uc-cli createmultisigaddress -m 2 -n 2 -s 03d8153cc69fc4f1e9a2c0904073faf253efd7a9580c925b365134bda74e942906 -k 03c8a6604e22c3f5174da08c79ab3a15f99817b529a6785dfc9816d351b2f17154 yujiali4 123456 |grep \"message\"; then\n    alert\n    fi\n\n ./uc-cli sendtokento snake02 123456 Ub9Utbs3hHMharWZBenvU8TjbygAXNtD5L BLOCK 9 \n    \n\nif ./uc-cli sendto yang 123456 3F81QMhhtBp4cK4WmDvYxRPVVfbEeZSV93  90000 |grep \"message\"; then\n    alert\n    fi\nif ./uc-cli sendtokenfrom snake02 123456 UcuW7wVu198Nuzok8eeMDUNEZQoGqQRRz5 3F81QMhhtBp4cK4WmDvYxRPVVfbEeZSV93 BLOCK 9 |grep \"message\"; then\n    alert\n    fi\n\n\n\nb=$(./uc-cli createmultisigtx -s BLOCK -t 3 yujiali3 123456 3F81QMhhtBp4cK4WmDvYxRPVVfbEeZSV93 Ub9Utbs3hHMharWZBenvU8TjbygAXNtD5L 1);\necho $b\nif ./uc-cli createmultisigtx -s BLOCK -t 3 yujiali3 123456 3F81QMhhtBp4cK4WmDvYxRPVVfbEeZSV93 Ub9Utbs3hHMharWZBenvU8TjbygAXNtD5L 1 |grep \"message\";then\nalert\nfi\n./uc-cli decoderawtx $b;\nif ./uc-cli decoderawtx $b |grep \"message\";then\nalert\nfi\nb1=$(./uc-cli signmultisigtx yujiali4 123456 $b);\necho $b1;\n./uc-cli sendrawtx $(echo $b1 | awk -F '\"' '{print $8}');\n\n./uc-cli vote -r 3F81QMhhtBp4cK4WmDvYxRPVVfbEeZSV93:9 yang 123456 UNfrtAxhJRi83PjTPjV3yNPKnjLYR22Bhx;\n\n\nc=$(./uc-cli createmultisigtx yujiali3 123456 3F81QMhhtBp4cK4WmDvYxRPVVfbEeZSV93 Ub9Utbs3hHMharWZBenvU8TjbygAXNtD5L 10000);\necho $c\nif ./uc-cli createmultisigtx yujiali3 123456 3F81QMhhtBp4cK4WmDvYxRPVVfbEeZSV93 Ub9Utbs3hHMharWZBenvU8TjbygAXNtD5L 10000 |grep \"message\";then\nalert\nfi\n./uc-cli decoderawtx $c;\nif ./uc-cli decoderawtx $c |grep \"message\";then\nalert\nfi\nc1=$(./uc-cli signmultisigtx yujiali4 123456 $c);\necho $c1;\n./uc-cli sendrawtx $(echo $c1 | awk -F '\"' '{print $8}');\n\nif ./uc-cli showmultisigaddresses yujiali3 123456 |grep \"message\"; then\n    alert\n    fi\nif ./uc-cli deletemultisigaddress yujiali3 123456 3F81QMhhtBp4cK4WmDvYxRPVVfbEeZSV93 |grep \"message\"; then\n    alert\n    fi\n\nif ./uc-cli addaddress yujiali3 123456 |grep \"message\"; then\n    alert\n    fi\nif ./uc-cli sendto yujiali3 123456 UVjsbgzEQZqqN3sM3MXrHwjvQ1MQggiXf9 10000 |grep \"message\"; then\n    alert\n    fi\nif ./uc-cli sendfrom yang 123456 UNfrtAxhJRi83PjTPjV3yNPKnjLYR22Bhx Ub9Utbs3hHMharWZBenvU8TjbygAXNtD5L 80000 |grep \"message\"; then\n    alert\n    fi\nif ./uc-cli sendtomulti -r Ub9Utbs3hHMharWZBenvU8TjbygAXNtD5L:10000 -r UaeG98wu548vYTYTogvEevVPuC6ToUST3z:100000 yang 123456 |grep \"message\"; then\n    alert\n    fi\nif ./uc-cli deposit -a Ub9Utbs3hHMharWZBenvU8TjbygAXNtD5L yujiali3 123456 10000 |grep \"message\"; then\n    alert\n    fi\nif ./uc-cli showbalances yujiali3 123456 |grep \"message\"; then\n    alert\n    fi\nif ./uc-cli showbalance yujiali3 123456 |grep \"message\"; then\n    alert\n    fi\nif ./uc-cli showaddressucn Ub9Utbs3hHMharWZBenvU8TjbygAXNtD5L |grep \"message\"; then\n    alert\n    fi\nif ./uc-cli showtokens |grep \"message\"; then\n    alert\n    fi\nif ./uc-cli showtoken |grep \"message\"; then\n    alert\n    fi\nif ./uc-cli showwallettoken yujiali3 123456 |grep \"message\"; then\n    alert\n    fi\nif ./uc-cli showaddresstoken  Ub9Utbs3hHMharWZBenvU8TjbygAXNtD5L |grep \"message\"; then\n    alert\n    fi\nif ./uc-cli sendtokenfrom snake03 123456 URaJN6xB2vmFGQcXDkLkrDjaSxu9qJN4Zr  Ub9Utbs3hHMharWZBenvU8TjbygAXNtD5L BLOCK 1  |grep \"message\"; then\n    alert\n    fi\n ./uc-cli sendtokenfrom snake02 123456 UcuW7wVu198Nuzok8eeMDUNEZQoGqQRRz5  Ub9Utbs3hHMharWZBenvU8TjbygAXNtD5L VOTE 1 \nif ./uc-cli showaddresstoken  Ub9Utbs3hHMharWZBenvU8TjbygAXNtD5L |grep \"message\"; then\n    alert\n    fi\nif ./uc-cli showtokens |grep \"message\"; then\n    alert\n    fi\n ./uc-cli destroy yujiali3 123456 BLOCK 1\n./uc-cli destroy snake02 123456 VOTE 1 \nif ./uc-cli sendtokenfrom yujiali3 123456 Ub9Utbs3hHMharWZBenvU8TjbygAXNtD5L 1111111111111111111114oLvT2 BLOCK 1 |grep \"message\"; then\n    alert\n    fi\n/uc-cli sendtokenfrom snake02 123456 UcuW7wVu198Nuzok8eeMDUNEZQoGqQRRz5  1111111111111111111114oLvT2  VOTE 1 \n    \nif ./uc-cli showaddresstoken 1111111111111111111114oLvT2 |grep \"message\"; then\n    alert\n    fi\n\n"
  },
  {
    "path": "thirdparty/CMakeLists.txt",
    "content": "ADD_SUBDIRECTORY(jsoncpp)\nADD_SUBDIRECTORY(mongoose)\nADD_SUBDIRECTORY(cryptojs)"
  },
  {
    "path": "thirdparty/README.md",
    "content": "third library\n"
  },
  {
    "path": "thirdparty/cryptojs/CMakeLists.txt",
    "content": "FILE(GLOB_RECURSE cryptojs_SOURCES \"*.cpp\")\n\nINCLUDE_DIRECTORIES(\"${PROJECT_SOURCE_DIR}/include\")\n\nADD_LIBRARY(cryptojs_static STATIC ${cryptojs_SOURCES})\nSET_TARGET_PROPERTIES(cryptojs_static PROPERTIES OUTPUT_NAME cryptojs)\nTARGET_LINK_LIBRARIES(cryptojs_static)\nINSTALL(TARGETS cryptojs_static DESTINATION lib)\n\nIF(ENABLE_SHARED_LIBS)\n    ADD_LIBRARY(cryptojs_shared SHARED ${cryptojs_SOURCES})\n    SET_TARGET_PROPERTIES(cryptojs_shared PROPERTIES OUTPUT_NAME cryptojs)\n    TARGET_LINK_LIBRARIES(cryptojs_shared)\n    INSTALL(TARGETS cryptojs_shared DESTINATION lib)\nENDIF()\n"
  },
  {
    "path": "thirdparty/cryptojs/aes256_cbc.cpp",
    "content": "/**\n *   Byte-oriented AES-256 implementation.\n *   All lookup tables replaced with 'on the fly' calculations.\n *\n *   Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com\n *   Other contributors: Hal Finney\n *\n *   Permission to use, copy, modify, and distribute this software for any\n *   purpose with or without fee is hereby granted, provided that the above\n *   copyright notice and this permission notice appear in all copies.\n *\n *   THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n *   WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n *   MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n *   ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n *   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n *   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n *   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\n#include \"aes256_cbc.h\"\n\n#include <stdint.h>\n#include <string.h> // CBC mode, for memset\nnamespace aes256_cbc\n{\n\n#define Nb 4\n#define Nk 8\n#define Nr 14\n\n/*****************************************************************************/\n/* Private variables:                                                        */\n/*****************************************************************************/\n// state - array holding the intermediate results during decryption.\ntypedef uint8_t state_t[4][4];\n\n// The lookup-tables are marked const so they can be placed in read-only storage instead of RAM\n// The numbers below can be computed dynamically trading ROM for RAM -\n// This can be useful in (embedded) bootloader applications, where ROM is often limited.\nstatic const uint8_t sbox[256] = {\n    //0     1    2      3     4    5     6     7      8    9     A      B    C     D     E     F\n    0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,\n    0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,\n    0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,\n    0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,\n    0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,\n    0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,\n    0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,\n    0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,\n    0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,\n    0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,\n    0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,\n    0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,\n    0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,\n    0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,\n    0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,\n    0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16};\n\nstatic const uint8_t rsbox[256] = {\n    0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,\n    0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,\n    0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,\n    0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,\n    0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,\n    0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,\n    0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,\n    0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,\n    0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,\n    0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,\n    0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,\n    0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,\n    0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,\n    0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,\n    0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,\n    0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d};\n\n// The round constant word array, Rcon[i], contains the values given by\n// x to the power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8)\nstatic const uint8_t Rcon[11] = {\n    0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};\n\n#define getSBoxValue(num) (sbox[(num)])\n\n#define getSBoxInvert(num) (rsbox[(num)])\n\n// This function produces Nb(Nr+1) round keys. The round keys are used in each round to decrypt the states.\nstatic void KeyExpansion(uint8_t *RoundKey, const uint8_t *Key)\n{\n    unsigned i, j, k;\n    uint8_t tempa[4]; // Used for the column/row operations\n\n    // The first round key is the key itself.\n    for (i = 0; i < Nk; ++i)\n    {\n        RoundKey[(i * 4) + 0] = Key[(i * 4) + 0];\n        RoundKey[(i * 4) + 1] = Key[(i * 4) + 1];\n        RoundKey[(i * 4) + 2] = Key[(i * 4) + 2];\n        RoundKey[(i * 4) + 3] = Key[(i * 4) + 3];\n    }\n\n    // All other round keys are found from the previous round keys.\n    for (i = Nk; i < Nb * (Nr + 1); ++i)\n    {\n        {\n            k = (i - 1) * 4;\n            tempa[0] = RoundKey[k + 0];\n            tempa[1] = RoundKey[k + 1];\n            tempa[2] = RoundKey[k + 2];\n            tempa[3] = RoundKey[k + 3];\n        }\n\n        if (i % Nk == 0)\n        {\n            // This function shifts the 4 bytes in a word to the left once.\n            // [a0,a1,a2,a3] becomes [a1,a2,a3,a0]\n\n            // Function RotWord()\n            {\n                k = tempa[0];\n                tempa[0] = tempa[1];\n                tempa[1] = tempa[2];\n                tempa[2] = tempa[3];\n                tempa[3] = k;\n            }\n\n            // SubWord() is a function that takes a four-byte input word and\n            // applies the S-box to each of the four bytes to produce an output word.\n\n            // Function Subword()\n            {\n                tempa[0] = getSBoxValue(tempa[0]);\n                tempa[1] = getSBoxValue(tempa[1]);\n                tempa[2] = getSBoxValue(tempa[2]);\n                tempa[3] = getSBoxValue(tempa[3]);\n            }\n\n            tempa[0] = tempa[0] ^ Rcon[i / Nk];\n        }\n\n        if (i % Nk == 4)\n        {\n            // Function Subword()\n            {\n                tempa[0] = getSBoxValue(tempa[0]);\n                tempa[1] = getSBoxValue(tempa[1]);\n                tempa[2] = getSBoxValue(tempa[2]);\n                tempa[3] = getSBoxValue(tempa[3]);\n            }\n        }\n\n        j = i * 4;\n        k = (i - Nk) * 4;\n        RoundKey[j + 0] = RoundKey[k + 0] ^ tempa[0];\n        RoundKey[j + 1] = RoundKey[k + 1] ^ tempa[1];\n        RoundKey[j + 2] = RoundKey[k + 2] ^ tempa[2];\n        RoundKey[j + 3] = RoundKey[k + 3] ^ tempa[3];\n    }\n}\n\nvoid AES_init_ctx(struct AES_ctx *ctx, const uint8_t *key)\n{\n    KeyExpansion(ctx->RoundKey, key);\n}\n\nvoid AES_init_ctx_iv(struct AES_ctx *ctx, const uint8_t *key, const uint8_t *iv)\n{\n    KeyExpansion(ctx->RoundKey, key);\n    memcpy(ctx->Iv, iv, AES_BLOCKLEN);\n}\n\nvoid AES_ctx_set_iv(struct AES_ctx *ctx, const uint8_t *iv)\n{\n    memcpy(ctx->Iv, iv, AES_BLOCKLEN);\n}\n\n// This function adds the round key to state.\n// The round key is added to the state by an XOR function.\nstatic void AddRoundKey(uint8_t round, state_t *state, uint8_t *RoundKey)\n{\n    uint8_t i, j;\n    for (i = 0; i < 4; ++i)\n    {\n        for (j = 0; j < 4; ++j)\n        {\n            (*state)[i][j] ^= RoundKey[(round * Nb * 4) + (i * Nb) + j];\n        }\n    }\n}\n\n// The SubBytes Function Substitutes the values in the\n// state matrix with values in an S-box.\nstatic void SubBytes(state_t *state)\n{\n    uint8_t i, j;\n    for (i = 0; i < 4; ++i)\n    {\n        for (j = 0; j < 4; ++j)\n        {\n            (*state)[j][i] = getSBoxValue((*state)[j][i]);\n        }\n    }\n}\n\n// The ShiftRows() function shifts the rows in the state to the left.\n// Each row is shifted with different offset.\n// Offset = Row number. So the first row is not shifted.\nstatic void ShiftRows(state_t *state)\n{\n    uint8_t temp;\n\n    // Rotate first row 1 columns to left\n    temp = (*state)[0][1];\n    (*state)[0][1] = (*state)[1][1];\n    (*state)[1][1] = (*state)[2][1];\n    (*state)[2][1] = (*state)[3][1];\n    (*state)[3][1] = temp;\n\n    // Rotate second row 2 columns to left\n    temp = (*state)[0][2];\n    (*state)[0][2] = (*state)[2][2];\n    (*state)[2][2] = temp;\n\n    temp = (*state)[1][2];\n    (*state)[1][2] = (*state)[3][2];\n    (*state)[3][2] = temp;\n\n    // Rotate third row 3 columns to left\n    temp = (*state)[0][3];\n    (*state)[0][3] = (*state)[3][3];\n    (*state)[3][3] = (*state)[2][3];\n    (*state)[2][3] = (*state)[1][3];\n    (*state)[1][3] = temp;\n}\n\nstatic uint8_t xtime(uint8_t x)\n{\n    return ((x << 1) ^ (((x >> 7) & 1) * 0x1b));\n}\n\n// MixColumns function mixes the columns of the state matrix\nstatic void MixColumns(state_t *state)\n{\n    uint8_t i;\n    uint8_t Tmp, Tm, t;\n    for (i = 0; i < 4; ++i)\n    {\n        t = (*state)[i][0];\n        Tmp = (*state)[i][0] ^ (*state)[i][1] ^ (*state)[i][2] ^ (*state)[i][3];\n        Tm = (*state)[i][0] ^ (*state)[i][1];\n        Tm = xtime(Tm);\n        (*state)[i][0] ^= Tm ^ Tmp;\n        Tm = (*state)[i][1] ^ (*state)[i][2];\n        Tm = xtime(Tm);\n        (*state)[i][1] ^= Tm ^ Tmp;\n        Tm = (*state)[i][2] ^ (*state)[i][3];\n        Tm = xtime(Tm);\n        (*state)[i][2] ^= Tm ^ Tmp;\n        Tm = (*state)[i][3] ^ t;\n        Tm = xtime(Tm);\n        (*state)[i][3] ^= Tm ^ Tmp;\n    }\n}\n\n#define Multiply(x, y)                         \\\n    (((y & 1) * x) ^                           \\\n     ((y >> 1 & 1) * xtime(x)) ^               \\\n     ((y >> 2 & 1) * xtime(xtime(x))) ^        \\\n     ((y >> 3 & 1) * xtime(xtime(xtime(x)))) ^ \\\n     ((y >> 4 & 1) * xtime(xtime(xtime(xtime(x))))))\n\n// MixColumns function mixes the columns of the state matrix.\n// The method used to multiply may be difficult to understand for the inexperienced.\n// Please use the references to gain more information.\nstatic void InvMixColumns(state_t *state)\n{\n    int i;\n    uint8_t a, b, c, d;\n    for (i = 0; i < 4; ++i)\n    {\n        a = (*state)[i][0];\n        b = (*state)[i][1];\n        c = (*state)[i][2];\n        d = (*state)[i][3];\n\n        (*state)[i][0] = Multiply(a, 0x0e) ^ Multiply(b, 0x0b) ^ Multiply(c, 0x0d) ^ Multiply(d, 0x09);\n        (*state)[i][1] = Multiply(a, 0x09) ^ Multiply(b, 0x0e) ^ Multiply(c, 0x0b) ^ Multiply(d, 0x0d);\n        (*state)[i][2] = Multiply(a, 0x0d) ^ Multiply(b, 0x09) ^ Multiply(c, 0x0e) ^ Multiply(d, 0x0b);\n        (*state)[i][3] = Multiply(a, 0x0b) ^ Multiply(b, 0x0d) ^ Multiply(c, 0x09) ^ Multiply(d, 0x0e);\n    }\n}\n\n// The SubBytes Function Substitutes the values in the\n// state matrix with values in an S-box.\nstatic void InvSubBytes(state_t *state)\n{\n    uint8_t i, j;\n    for (i = 0; i < 4; ++i)\n    {\n        for (j = 0; j < 4; ++j)\n        {\n            (*state)[j][i] = getSBoxInvert((*state)[j][i]);\n        }\n    }\n}\n\nstatic void InvShiftRows(state_t *state)\n{\n    uint8_t temp;\n\n    // Rotate first row 1 columns to right\n    temp = (*state)[3][1];\n    (*state)[3][1] = (*state)[2][1];\n    (*state)[2][1] = (*state)[1][1];\n    (*state)[1][1] = (*state)[0][1];\n    (*state)[0][1] = temp;\n\n    // Rotate second row 2 columns to right\n    temp = (*state)[0][2];\n    (*state)[0][2] = (*state)[2][2];\n    (*state)[2][2] = temp;\n\n    temp = (*state)[1][2];\n    (*state)[1][2] = (*state)[3][2];\n    (*state)[3][2] = temp;\n\n    // Rotate third row 3 columns to right\n    temp = (*state)[0][3];\n    (*state)[0][3] = (*state)[1][3];\n    (*state)[1][3] = (*state)[2][3];\n    (*state)[2][3] = (*state)[3][3];\n    (*state)[3][3] = temp;\n}\n\n// Cipher is the main function that encrypts the PlainText.\nstatic void Cipher(state_t *state, uint8_t *RoundKey)\n{\n    uint8_t round = 0;\n\n    // Add the First round key to the state before starting the rounds.\n    AddRoundKey(0, state, RoundKey);\n\n    // There will be Nr rounds.\n    // The first Nr-1 rounds are identical.\n    // These Nr-1 rounds are executed in the loop below.\n    for (round = 1; round < Nr; ++round)\n    {\n        SubBytes(state);\n        ShiftRows(state);\n        MixColumns(state);\n        AddRoundKey(round, state, RoundKey);\n    }\n\n    // The last round is given below.\n    // The MixColumns function is not here in the last round.\n    SubBytes(state);\n    ShiftRows(state);\n    AddRoundKey(Nr, state, RoundKey);\n}\n\nstatic void InvCipher(state_t *state, uint8_t *RoundKey)\n{\n    uint8_t round = 0;\n\n    // Add the First round key to the state before starting the rounds.\n    AddRoundKey(Nr, state, RoundKey);\n\n    // There will be Nr rounds.\n    // The first Nr-1 rounds are identical.\n    // These Nr-1 rounds are executed in the loop below.\n    for (round = (Nr - 1); round > 0; --round)\n    {\n        InvShiftRows(state);\n        InvSubBytes(state);\n        AddRoundKey(round, state, RoundKey);\n        InvMixColumns(state);\n    }\n\n    // The last round is given below.\n    // The MixColumns function is not here in the last round.\n    InvShiftRows(state);\n    InvSubBytes(state);\n    AddRoundKey(0, state, RoundKey);\n}\n\nstatic void XorWithIv(uint8_t *buf, uint8_t *Iv)\n{\n    uint8_t i;\n    for (i = 0; i < AES_BLOCKLEN; ++i) // The block in AES is always 128bit no matter the key size\n    {\n        buf[i] ^= Iv[i];\n    }\n}\n\nvoid AES_CBC_encrypt_buffer(struct AES_ctx *ctx, uint8_t *buf, uint32_t length)\n{\n    uintptr_t i;\n    uint8_t *Iv = ctx->Iv;\n    for (i = 0; i < length; i += AES_BLOCKLEN)\n    {\n        XorWithIv(buf, Iv);\n        Cipher((state_t *)buf, ctx->RoundKey);\n        Iv = buf;\n        buf += AES_BLOCKLEN;\n        //printf(\"Step %d - %d\", i/16, i);\n    }\n    /* store Iv in ctx for next call */\n    memcpy(ctx->Iv, Iv, AES_BLOCKLEN);\n}\n\nvoid AES_CBC_decrypt_buffer(struct AES_ctx *ctx, uint8_t *buf, uint32_t length)\n{\n    uintptr_t i;\n    uint8_t storeNextIv[AES_BLOCKLEN];\n    for (i = 0; i < length; i += AES_BLOCKLEN)\n    {\n        memcpy(storeNextIv, buf, AES_BLOCKLEN);\n        InvCipher((state_t *)buf, ctx->RoundKey);\n        XorWithIv(buf, ctx->Iv);\n        memcpy(ctx->Iv, storeNextIv, AES_BLOCKLEN);\n        buf += AES_BLOCKLEN;\n    }\n}\n\n} // namespace aes256_cbc"
  },
  {
    "path": "thirdparty/cryptojs/aes256_cbc.h",
    "content": "/**\n *   Byte-oriented AES-256 implementation.\n *   All lookup tables replaced with 'on the fly' calculations.\n *\n *   Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com\n *   Other contributors: Hal Finney\n *\n *   Permission to use, copy, modify, and distribute this software for any\n *   purpose with or without fee is hereby granted, provided that the above\n *   copyright notice and this permission notice appear in all copies.\n *\n *   THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\n *   WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\n *   MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\n *   ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n *   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\n *   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\n *   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n */\n\n#ifndef UChain_AES256_CBC_H\n#define UChain_AES256_CBC_H\n\n#include <stdint.h>\n#include <stdlib.h>\nnamespace aes256_cbc\n{\n\n#define AES256 1\n#define AES_BLOCKLEN 16\n\n#define AES_KEYLEN 32\n#define AES_keyExpSize 240\n\nstruct AES_ctx\n{\n    uint8_t RoundKey[AES_keyExpSize];\n    uint8_t Iv[AES_BLOCKLEN];\n};\n\nvoid AES_init_ctx(struct AES_ctx *ctx, const uint8_t *key);\n\nvoid AES_init_ctx_iv(struct AES_ctx *ctx, const uint8_t *key, const uint8_t *iv);\n\nvoid AES_ctx_set_iv(struct AES_ctx *ctx, const uint8_t *iv);\n\nvoid AES_CBC_encrypt_buffer(struct AES_ctx *ctx, uint8_t *buf, uint32_t length);\n\nvoid AES_CBC_decrypt_buffer(struct AES_ctx *ctx, uint8_t *buf, uint32_t length);\n\n} // namespace aes256_cbc\n#endif //UChain_AES256_CBC_H\n"
  },
  {
    "path": "thirdparty/cryptojs/cryptojs_impl.cpp",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n//\n// Created by czp on 18-3-30.\n//\n#include \"cryptojs_impl.h\"\n#include \"aes256_cbc.h\"\n#include \"md5.h\"\n#include <UChain/coin/utility/random.hpp>\n#include <boost/smart_ptr.hpp>\n\n#define CONCAT(a, b) a.insert(a.end(), b.begin(), b.end())\n\nnamespace cryptojs\n{\n//using libbitcoin::data_chunk;\ndata_chunk MD5Hash(const data_chunk &data)\n{\n    MD5 md5;\n    md5.update(data.data(), data.size());\n    md5.finalize();\n\n    return data_chunk(md5.raw_digest(), md5.raw_digest() + 16);\n}\n\nvoid derive_key(const data_chunk &passphrase, const data_chunk &salt, data_chunk &key, data_chunk &iv)\n{\n    const uint8_t key_size = 32;\n    const uint8_t iv_size = 16;\n    //const uint8_t iterations  = 1;\n\n    data_chunk derivedKeyWords;\n    data_chunk block;\n\n    while (derivedKeyWords.size() < (key_size + iv_size))\n    {\n        //block.insert(block.end(), passphrase.begin(), passphrase.end());\n        //block.insert(block.end(), salt.begin(), salt.end());\n        CONCAT(block, passphrase);\n        CONCAT(block, salt);\n        block = MD5Hash(block);\n        //derivedKeyWords.insert(derivedKeyWords.end(), block.begin(), block.end());\n        CONCAT(derivedKeyWords, block);\n    }\n\n    key.assign(derivedKeyWords.begin(), derivedKeyWords.begin() + key_size);\n    iv.assign(derivedKeyWords.begin() + key_size, derivedKeyWords.end());\n}\n\ndata_chunk Pkcs7_Padding(const data_chunk &data, const uint8_t &block_size = 16)\n{\n    const uint8_t nPaddingBytes = block_size - (data.size() % block_size);\n    data_chunk ret(data);\n    for (auto i = 0; i < nPaddingBytes; ++i)\n    {\n        ret.push_back(nPaddingBytes);\n    }\n    return ret;\n}\n\ndata_chunk aes256_cbc_encrypt(const data_chunk &key, const data_chunk &iv, const data_chunk &block)\n{\n\n    aes256_cbc::AES_ctx context;\n    aes256_cbc::AES_init_ctx_iv(&context, key.data(), iv.data());\n    const auto BLOCK_SIZE = block.size();\n    uint8_t *p = new uint8_t[BLOCK_SIZE];\n    boost::shared_array<uint8_t> sa(p);\n    for (size_t i = 0; i < BLOCK_SIZE; ++i)\n    {\n        p[i] = block[i];\n    }\n\n    aes256_cbc::AES_CBC_encrypt_buffer(&context, p, BLOCK_SIZE);\n\n    return data_chunk(p, p + BLOCK_SIZE);\n}\n\ndata_chunk aes256_cbc_decrypt(const data_chunk &key, const data_chunk &iv, const data_chunk &block)\n{\n\n    aes256_cbc::AES_ctx context;\n    aes256_cbc::AES_init_ctx_iv(&context, key.data(), iv.data());\n    const auto BLOCK_SIZE = block.size();\n    uint8_t *p = new uint8_t[BLOCK_SIZE];\n    boost::shared_array<uint8_t> sa(p);\n    for (size_t i = 0; i < BLOCK_SIZE; ++i)\n    {\n        p[i] = block[i];\n    }\n\n    aes256_cbc::AES_CBC_decrypt_buffer(&context, p, BLOCK_SIZE);\n\n    return data_chunk(p, p + BLOCK_SIZE);\n}\n\ndata_chunk encrypt(const std::string &message, const std::string &passphrase_)\n{\n    const auto nonce = bc::pseudo_random();\n\n    data_chunk salt = {\n        (uint8_t)(nonce >> (0 * 8)),\n        (uint8_t)(nonce >> (1 * 8)),\n        (uint8_t)(nonce >> (2 * 8)),\n        (uint8_t)(nonce >> (3 * 8)),\n        (uint8_t)(nonce >> (4 * 8)),\n        (uint8_t)(nonce >> (5 * 8)),\n        (uint8_t)(nonce >> (6 * 8)),\n        (uint8_t)(nonce >> (7 * 8)),\n    };\n    data_chunk passphrase(passphrase_.begin(), passphrase_.end());\n\n    data_chunk key;\n    data_chunk iv;\n    derive_key(passphrase, salt, key, iv);\n\n    const auto in = Pkcs7_Padding(data_chunk(message.begin(), message.end()));\n\n    data_chunk encrypted = aes256_cbc_encrypt(key, iv, in);\n\n    data_chunk prefix = {0x53, 0x61, 0x6c, 0x74, 0x65, 0x64, 0x5f, 0x5f};\n\n    CONCAT(prefix, salt);\n    CONCAT(prefix, encrypted);\n\n    return prefix; //libbitcoin::encode_base64(prefix);\n}\n\nbool decrypt(const data_chunk &cipher_txt, const std::string &passphrase_, std::string &message)\n{\n    const data_chunk &cipher_data = cipher_txt;\n    /*if (false == libbitcoin::decode_base64(cipher_data, cipher_txt)){\n            return \"base64 cipher text decode error\";\n        }*/\n\n    const data_chunk prefix = {0x53, 0x61, 0x6c, 0x74, 0x65, 0x64, 0x5f, 0x5f};\n    auto it = std::find_first_of(cipher_data.begin(), cipher_data.end(), prefix.begin(), prefix.end());\n    if (it != cipher_data.begin())\n    {\n        return false;\n    }\n\n    const data_chunk salt(cipher_data.begin() + 8, cipher_data.begin() + 16);\n    const data_chunk encrypted(cipher_data.begin() + 16, cipher_data.end());\n\n    data_chunk passphrase(passphrase_.begin(), passphrase_.end());\n    data_chunk key;\n    data_chunk iv;\n    derive_key(passphrase, salt, key, iv);\n\n    data_chunk plain_data = aes256_cbc_decrypt(key, iv, encrypted);\n    const uint8_t padding = plain_data[plain_data.size() - 1];\n    if (padding > 0x10)\n    {\n        return false;\n    }\n\n    message.assign(plain_data.begin(), plain_data.begin() + plain_data.size() - padding);\n    return true;\n}\n} // namespace cryptojs"
  },
  {
    "path": "thirdparty/cryptojs/cryptojs_impl.h",
    "content": "/**\n * Copyright (c) 2011-2018 libbitcoin developers \n * Copyright (c) 2018-2020 UChain core developers (check UC-AUTHORS)\n *\n * This file is part of UChain-server.\n *\n * UChain-server is free software: you can redistribute it and/or\n * modify it under the terms of the GNU Affero General Public License with\n * additional permissions to the one published by the Free Software\n * Foundation, either version 3 of the License, or (at your option)\n * any later version. For more information see LICENSE.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Affero General Public License for more details.\n *\n * You should have received a copy of the GNU Affero General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n//\n// Created by czp on 18-3-30.\n//\n\n#ifndef UChain_CRYPTOJS_IMPL_H\n#define UChain_CRYPTOJS_IMPL_H\n\n#include <vector>\n#include <string>\n\nnamespace cryptojs\n{\ntypedef std::vector<uint8_t> data_chunk;\ndata_chunk encrypt(const std::string &message, const std::string &passphrase_);\n\nbool decrypt(const data_chunk &cipher_txt, const std::string &passphrase_, std::string &message);\n} // namespace cryptojs\n#endif //UChain_CRYPTJS_IMPL_H\n"
  },
  {
    "path": "thirdparty/cryptojs/md5.cpp",
    "content": "/* md5.c */\r\n/* MD5\r\n converted to C++ class by Frank Thilo (thilo@unix-ag.org)\r\n for bzflag (http://www.bzflag.org)\r\n\r\n   based on:\r\n\r\n   md5.h and md5.c\r\n   reference implemantion of RFC 1321\r\n\r\n   Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All\r\nrights reserved.\r\n\r\nLicense to copy and use this software is granted provided that it\r\nis identified as the \"RSA Data Security, Inc. MD5 Message-Digest\r\nAlgorithm\" in all material mentioning or referencing this software\r\nor this function.\r\n\r\nLicense is also granted to make and use derivative works provided\r\nthat such works are identified as \"derived from the RSA Data\r\nSecurity, Inc. MD5 Message-Digest Algorithm\" in all material\r\nmentioning or referencing the derived work.\r\n\r\nRSA Data Security, Inc. makes no representations concerning either\r\nthe merchantability of this software or the suitability of this\r\nsoftware for any particular purpose. It is provided \"as is\"\r\nwithout express or implied warranty of any kind.\r\n\r\nThese notices must be retained in any copies of any part of this\r\ndocumentation and/or software.\r\n\r\n*/\r\n\r\n/* interface header */\r\n#include \"md5.h\"\r\n\r\n/* system implementation headers */\r\n#include <stdio.h>\r\n#include <string.h>\r\n\r\nnamespace cryptojs\r\n{\r\n// Constants for MD5Transform routine.\r\n#define S11 7\r\n#define S12 12\r\n#define S13 17\r\n#define S14 22\r\n#define S21 5\r\n#define S22 9\r\n#define S23 14\r\n#define S24 20\r\n#define S31 4\r\n#define S32 11\r\n#define S33 16\r\n#define S34 23\r\n#define S41 6\r\n#define S42 10\r\n#define S43 15\r\n#define S44 21\r\n\r\n///////////////////////////////////////////////\r\n// F, G, H and I are basic MD5 functions.\r\ninline MD5::uint4 MD5::F(uint4 x, uint4 y, uint4 z)\r\n{\r\n    return (x & y) | ((~x) & z);\r\n}\r\n\r\ninline MD5::uint4 MD5::G(uint4 x, uint4 y, uint4 z)\r\n{\r\n    return (x & z) | (y & ~z);\r\n}\r\n\r\ninline MD5::uint4 MD5::H(uint4 x, uint4 y, uint4 z)\r\n{\r\n    return x ^ y ^ z;\r\n}\r\n\r\ninline MD5::uint4 MD5::I(uint4 x, uint4 y, uint4 z)\r\n{\r\n    return y ^ (x | ~z);\r\n}\r\n\r\n// rotate_left rotates x left n bits.\r\ninline MD5::uint4 MD5::rotate_left(uint4 x, int n)\r\n{\r\n    return (x << n) | (x >> (32 - n));\r\n}\r\n\r\n// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.\r\n// Rotation is separate from addition to prevent recomputation.\r\ninline void MD5::FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)\r\n{\r\n    a = rotate_left(a + F(b, c, d) + x + ac, s) + b;\r\n}\r\n\r\ninline void MD5::GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)\r\n{\r\n    a = rotate_left(a + G(b, c, d) + x + ac, s) + b;\r\n}\r\n\r\ninline void MD5::HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)\r\n{\r\n    a = rotate_left(a + H(b, c, d) + x + ac, s) + b;\r\n}\r\n\r\ninline void MD5::II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac)\r\n{\r\n    a = rotate_left(a + I(b, c, d) + x + ac, s) + b;\r\n}\r\n\r\n//////////////////////////////////////////////\r\n\r\n// default ctor, just initailize\r\nMD5::MD5()\r\n{\r\n    init();\r\n}\r\n\r\n//////////////////////////////////////////////\r\n\r\n// nifty shortcut ctor, compute MD5 for string and finalize it right away\r\nMD5::MD5(const std::string &text)\r\n{\r\n    init();\r\n    update(text.c_str(), text.length());\r\n    finalize();\r\n}\r\n\r\n//////////////////////////////\r\n\r\nvoid MD5::init()\r\n{\r\n    finalized = false;\r\n\r\n    count[0] = 0;\r\n    count[1] = 0;\r\n\r\n    // load magic initialization constants.\r\n    state[0] = 0x67452301;\r\n    state[1] = 0xefcdab89;\r\n    state[2] = 0x98badcfe;\r\n    state[3] = 0x10325476;\r\n}\r\n\r\n//////////////////////////////\r\n\r\n// decodes input (unsigned char) into output (uint4). Assumes len is a multiple of 4.\r\nvoid MD5::decode(uint4 output[], const uint1 input[], size_type len)\r\n{\r\n    for (unsigned int i = 0, j = 0; j < len; i++, j += 4)\r\n        output[i] = ((uint4)input[j]) | (((uint4)input[j + 1]) << 8) |\r\n                    (((uint4)input[j + 2]) << 16) | (((uint4)input[j + 3]) << 24);\r\n}\r\n\r\n//////////////////////////////\r\n\r\n// encodes input (uint4) into output (unsigned char). Assumes len is\r\n// a multiple of 4.\r\nvoid MD5::encode(uint1 output[], const uint4 input[], size_type len)\r\n{\r\n    for (size_type i = 0, j = 0; j < len; i++, j += 4)\r\n    {\r\n        output[j] = input[i] & 0xff;\r\n        output[j + 1] = (input[i] >> 8) & 0xff;\r\n        output[j + 2] = (input[i] >> 16) & 0xff;\r\n        output[j + 3] = (input[i] >> 24) & 0xff;\r\n    }\r\n}\r\n\r\n//////////////////////////////\r\n\r\n// apply MD5 algo on a block\r\nvoid MD5::transform(const uint1 block[blocksize])\r\n{\r\n    uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];\r\n    decode(x, block, blocksize);\r\n\r\n    /* Round 1 */\r\n    FF(a, b, c, d, x[0], S11, 0xd76aa478);  /* 1 */\r\n    FF(d, a, b, c, x[1], S12, 0xe8c7b756);  /* 2 */\r\n    FF(c, d, a, b, x[2], S13, 0x242070db);  /* 3 */\r\n    FF(b, c, d, a, x[3], S14, 0xc1bdceee);  /* 4 */\r\n    FF(a, b, c, d, x[4], S11, 0xf57c0faf);  /* 5 */\r\n    FF(d, a, b, c, x[5], S12, 0x4787c62a);  /* 6 */\r\n    FF(c, d, a, b, x[6], S13, 0xa8304613);  /* 7 */\r\n    FF(b, c, d, a, x[7], S14, 0xfd469501);  /* 8 */\r\n    FF(a, b, c, d, x[8], S11, 0x698098d8);  /* 9 */\r\n    FF(d, a, b, c, x[9], S12, 0x8b44f7af);  /* 10 */\r\n    FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */\r\n    FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */\r\n    FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */\r\n    FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */\r\n    FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */\r\n    FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */\r\n\r\n    /* Round 2 */\r\n    GG(a, b, c, d, x[1], S21, 0xf61e2562);  /* 17 */\r\n    GG(d, a, b, c, x[6], S22, 0xc040b340);  /* 18 */\r\n    GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */\r\n    GG(b, c, d, a, x[0], S24, 0xe9b6c7aa);  /* 20 */\r\n    GG(a, b, c, d, x[5], S21, 0xd62f105d);  /* 21 */\r\n    GG(d, a, b, c, x[10], S22, 0x2441453);  /* 22 */\r\n    GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */\r\n    GG(b, c, d, a, x[4], S24, 0xe7d3fbc8);  /* 24 */\r\n    GG(a, b, c, d, x[9], S21, 0x21e1cde6);  /* 25 */\r\n    GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */\r\n    GG(c, d, a, b, x[3], S23, 0xf4d50d87);  /* 27 */\r\n    GG(b, c, d, a, x[8], S24, 0x455a14ed);  /* 28 */\r\n    GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */\r\n    GG(d, a, b, c, x[2], S22, 0xfcefa3f8);  /* 30 */\r\n    GG(c, d, a, b, x[7], S23, 0x676f02d9);  /* 31 */\r\n    GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */\r\n\r\n    /* Round 3 */\r\n    HH(a, b, c, d, x[5], S31, 0xfffa3942);  /* 33 */\r\n    HH(d, a, b, c, x[8], S32, 0x8771f681);  /* 34 */\r\n    HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */\r\n    HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */\r\n    HH(a, b, c, d, x[1], S31, 0xa4beea44);  /* 37 */\r\n    HH(d, a, b, c, x[4], S32, 0x4bdecfa9);  /* 38 */\r\n    HH(c, d, a, b, x[7], S33, 0xf6bb4b60);  /* 39 */\r\n    HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */\r\n    HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */\r\n    HH(d, a, b, c, x[0], S32, 0xeaa127fa);  /* 42 */\r\n    HH(c, d, a, b, x[3], S33, 0xd4ef3085);  /* 43 */\r\n    HH(b, c, d, a, x[6], S34, 0x4881d05);   /* 44 */\r\n    HH(a, b, c, d, x[9], S31, 0xd9d4d039);  /* 45 */\r\n    HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */\r\n    HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */\r\n    HH(b, c, d, a, x[2], S34, 0xc4ac5665);  /* 48 */\r\n\r\n    /* Round 4 */\r\n    II(a, b, c, d, x[0], S41, 0xf4292244);  /* 49 */\r\n    II(d, a, b, c, x[7], S42, 0x432aff97);  /* 50 */\r\n    II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */\r\n    II(b, c, d, a, x[5], S44, 0xfc93a039);  /* 52 */\r\n    II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */\r\n    II(d, a, b, c, x[3], S42, 0x8f0ccc92);  /* 54 */\r\n    II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */\r\n    II(b, c, d, a, x[1], S44, 0x85845dd1);  /* 56 */\r\n    II(a, b, c, d, x[8], S41, 0x6fa87e4f);  /* 57 */\r\n    II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */\r\n    II(c, d, a, b, x[6], S43, 0xa3014314);  /* 59 */\r\n    II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */\r\n    II(a, b, c, d, x[4], S41, 0xf7537e82);  /* 61 */\r\n    II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */\r\n    II(c, d, a, b, x[2], S43, 0x2ad7d2bb);  /* 63 */\r\n    II(b, c, d, a, x[9], S44, 0xeb86d391);  /* 64 */\r\n\r\n    state[0] += a;\r\n    state[1] += b;\r\n    state[2] += c;\r\n    state[3] += d;\r\n\r\n    // Zeroize sensitive information.\r\n    memset(x, 0, sizeof x);\r\n}\r\n\r\n//////////////////////////////\r\n\r\n// MD5 block update operation. Continues an MD5 message-digest\r\n// operation, processing another message block\r\nvoid MD5::update(const unsigned char input[], size_type length)\r\n{\r\n    // compute number of bytes mod 64\r\n    size_type index = count[0] / 8 % blocksize;\r\n\r\n    // Update number of bits\r\n    if ((count[0] += (length << 3)) < (length << 3))\r\n        count[1]++;\r\n    count[1] += (length >> 29);\r\n\r\n    // number of bytes we need to fill in buffer\r\n    size_type firstpart = 64 - index;\r\n\r\n    size_type i;\r\n\r\n    // transform as many times as possible.\r\n    if (length >= firstpart)\r\n    {\r\n        // fill buffer first, transform\r\n        memcpy(&buffer[index], input, firstpart);\r\n        transform(buffer);\r\n\r\n        // transform chunks of blocksize (64 bytes)\r\n        for (i = firstpart; i + blocksize <= length; i += blocksize)\r\n            transform(&input[i]);\r\n\r\n        index = 0;\r\n    }\r\n    else\r\n        i = 0;\r\n\r\n    // buffer remaining input\r\n    memcpy(&buffer[index], &input[i], length - i);\r\n}\r\n\r\n//////////////////////////////\r\n\r\n// for convenience provide a verson with signed char\r\nvoid MD5::update(const char input[], size_type length)\r\n{\r\n    update((const unsigned char *)input, length);\r\n}\r\n\r\n//////////////////////////////\r\n\r\n// MD5 finalization. Ends an MD5 message-digest operation, writing the\r\n// the message digest and zeroizing the context.\r\nMD5 &MD5::finalize()\r\n{\r\n    static unsigned char padding[64] = {\r\n        0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};\r\n\r\n    if (!finalized)\r\n    {\r\n        // Save number of bits\r\n        unsigned char bits[8];\r\n        encode(bits, count, 8);\r\n\r\n        // pad out to 56 mod 64.\r\n        size_type index = count[0] / 8 % 64;\r\n        size_type padLen = (index < 56) ? (56 - index) : (120 - index);\r\n        update(padding, padLen);\r\n\r\n        // Append length (before padding)\r\n        update(bits, 8);\r\n\r\n        // Store state in digest\r\n        encode(digest, state, 16);\r\n\r\n        // Zeroize sensitive information.\r\n        memset(buffer, 0, sizeof buffer);\r\n        memset(count, 0, sizeof count);\r\n\r\n        finalized = true;\r\n    }\r\n\r\n    return *this;\r\n}\r\n\r\n//////////////////////////////\r\n\r\n// return hex representation of digest as string\r\nstd::string MD5::hexdigest() const\r\n{\r\n    if (!finalized)\r\n        return \"\";\r\n\r\n    char buf[33];\r\n    for (int i = 0; i < 16; i++)\r\n        sprintf(buf + i * 2, \"%02x\", digest[i]);\r\n    buf[32] = 0;\r\n\r\n    return std::string(buf);\r\n}\r\n\r\nstd::string MD5::md5() const\r\n{\r\n    return hexdigest();\r\n}\r\n\r\n//////////////////////////////\r\n\r\nstd::ostream &operator<<(std::ostream &out, MD5 md5)\r\n{\r\n    return out << md5.hexdigest();\r\n}\r\n//////////////////////////////\r\n\r\n} // namespace cryptojs"
  },
  {
    "path": "thirdparty/cryptojs/md5.h",
    "content": "/* md5.h */\r\n/* MD5\r\n converted to C++ class by Frank Thilo (thilo@unix-ag.org)\r\n for bzflag (http://www.bzflag.org)\r\n\r\n   based on:\r\n\r\n   md5.h and md5.c\r\n   reference implementation of RFC 1321\r\n\r\n   Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All\r\nrights reserved.\r\n\r\nLicense to copy and use this software is granted provided that it\r\nis identified as the \"RSA Data Security, Inc. MD5 Message-Digest\r\nAlgorithm\" in all material mentioning or referencing this software\r\nor this function.\r\n\r\nLicense is also granted to make and use derivative works provided\r\nthat such works are identified as \"derived from the RSA Data\r\nSecurity, Inc. MD5 Message-Digest Algorithm\" in all material\r\nmentioning or referencing the derived work.\r\n\r\nRSA Data Security, Inc. makes no representations concerning either\r\nthe merchantability of this software or the suitability of this\r\nsoftware for any particular purpose. It is provided \"as is\"\r\nwithout express or implied warranty of any kind.\r\n\r\nThese notices must be retained in any copies of any part of this\r\ndocumentation and/or software.\r\n\r\n*/\r\n\r\n#ifndef BZF_MD5_H\r\n#define BZF_MD5_H\r\n\r\n#include <string>\r\n#include <iostream>\r\n\r\nnamespace cryptojs\r\n{\r\n// a small class for calculating MD5 hashes of strings or byte arrays\r\n// it is not meant to be fast or secure\r\n//\r\n// usage: 1) feed it blocks of uchars with update()\r\n//      2) finalize()\r\n//      3) get hexdigest() string\r\n//      or\r\n//      MD5(std::string).hexdigest()\r\n//\r\n// assumes that char is 8 bit and int is 32 bit\r\nclass MD5\r\n{\r\n  public:\r\n    typedef unsigned int size_type; // must be 32bit\r\n\r\n    MD5();\r\n\r\n    MD5(const std::string &text);\r\n\r\n    void update(const unsigned char *buf, size_type length);\r\n\r\n    void update(const char *buf, size_type length);\r\n\r\n    MD5 &finalize();\r\n\r\n    std::string hexdigest() const;\r\n\r\n    std::string md5() const;\r\n\r\n    friend std::ostream &operator<<(std::ostream &, MD5 md5);\r\n\r\n    const unsigned char *raw_digest() const { return digest; }\r\n\r\n  private:\r\n    void init();\r\n\r\n    typedef unsigned char uint1; //  8bit\r\n    typedef unsigned int uint4;  // 32bit\r\n    enum\r\n    {\r\n        blocksize = 64\r\n    }; // VC6 won't eat a const static int here\r\n\r\n    void transform(const uint1 block[blocksize]);\r\n\r\n    static void decode(uint4 output[], const uint1 input[], size_type len);\r\n\r\n    static void encode(uint1 output[], const uint4 input[], size_type len);\r\n\r\n    bool finalized;\r\n    uint1 buffer[blocksize]; // bytes that didn't fit in last 64 byte chunk\r\n    uint4 count[2];          // 64bit counter for number of bits (lo, hi)\r\n    uint4 state[4];          // digest so far\r\n    uint1 digest[16];        // the result\r\n\r\n    // low level logic operations\r\n    static inline uint4 F(uint4 x, uint4 y, uint4 z);\r\n\r\n    static inline uint4 G(uint4 x, uint4 y, uint4 z);\r\n\r\n    static inline uint4 H(uint4 x, uint4 y, uint4 z);\r\n\r\n    static inline uint4 I(uint4 x, uint4 y, uint4 z);\r\n\r\n    static inline uint4 rotate_left(uint4 x, int n);\r\n\r\n    static inline void FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);\r\n\r\n    static inline void GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);\r\n\r\n    static inline void HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);\r\n\r\n    static inline void II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac);\r\n};\r\n} // namespace cryptojs\r\n#endif"
  },
  {
    "path": "thirdparty/json/minijson_reader.hpp",
    "content": "#ifndef MINIJSON_READER_H\n#define MINIJSON_READER_H\n\n#include <cstdlib>\n#include <cctype>\n#include <stdint.h>\n#include <climits>\n#include <cstring>\n#include <cerrno>\n\n#include <vector>\n#include <list>\n#include <string>\n#include <utility>\n\n#include <stdexcept>\n#include <istream>\n\n#define MJR_CPP11_SUPPORTED __cplusplus > 199711L || _MSC_VER >= 1800\n\n#if MJR_CPP11_SUPPORTED\n\n#define MJR_FINAL final\n\n#else\n\n#define MJR_FINAL\n\n#endif // MJR_CPP11_SUPPORTED\n\n#ifndef MJR_NESTING_LIMIT\n#define MJR_NESTING_LIMIT 32\n#endif\n\n#define MJR_STRINGIFY(S) MJR_STRINGIFY_HELPER(S)\n#define MJR_STRINGIFY_HELPER(S) #S\n\nnamespace minijson\n{\n\nnamespace detail\n{\n\nclass noncopyable\n{\n  private:\n    // C++03 idiom to prevent copy construction and copy assignment\n    noncopyable(const noncopyable &);\n    noncopyable &operator=(const noncopyable &);\n\n  public:\n    noncopyable()\n    {\n    }\n}; // class noncopyable\n\nclass context_base : noncopyable\n{\n  public:\n    enum context_nested_status\n    {\n        NESTED_STATUS_NONE,\n        NESTED_STATUS_OBJECT,\n        NESTED_STATUS_ARRAY\n    };\n\n  private:\n    context_nested_status m_nested_status;\n    size_t m_nesting_level;\n\n  public:\n    context_base() : m_nested_status(NESTED_STATUS_NONE),\n                     m_nesting_level(0)\n    {\n    }\n\n    char nested_status() const\n    {\n        return m_nested_status;\n    }\n\n    void begin_nested(context_nested_status nested_status)\n    {\n        m_nested_status = nested_status;\n        m_nesting_level++;\n    }\n\n    void reset_nested_status()\n    {\n        m_nested_status = NESTED_STATUS_NONE;\n    }\n\n    void end_nested()\n    {\n        if (m_nesting_level > 0)\n        {\n            m_nesting_level--;\n        }\n    }\n\n    size_t nesting_level() const\n    {\n        return m_nesting_level;\n    }\n}; // class context_base\n\nclass buffer_context_base : public context_base\n{\n  protected:\n    const char *m_read_buffer;\n    char *m_write_buffer;\n    size_t m_length;\n    size_t m_read_offset;\n    size_t m_write_offset;\n    const char *m_current_write_buffer;\n\n    explicit buffer_context_base(const char *read_buffer, char *write_buffer, size_t length) : m_read_buffer(read_buffer),\n                                                                                               m_write_buffer(write_buffer),\n                                                                                               m_length(length),\n                                                                                               m_read_offset(0),\n                                                                                               m_write_offset(0),\n                                                                                               m_current_write_buffer(NULL)\n    {\n        new_write_buffer();\n    }\n\n  public:\n    char read()\n    {\n        if (m_read_offset >= m_length)\n        {\n            return 0;\n        }\n\n        return m_read_buffer[m_read_offset++];\n    }\n\n    size_t read_offset() const\n    {\n        return m_read_offset;\n    }\n\n    void new_write_buffer()\n    {\n        m_current_write_buffer = m_write_buffer + m_write_offset;\n    }\n\n    void write(char c)\n    {\n        if (m_write_offset >= m_read_offset)\n        {\n            throw std::runtime_error(\"Invalid write call, please file a bug report\");\n        }\n\n        m_write_buffer[m_write_offset++] = c;\n    }\n\n    const char *write_buffer() const\n    {\n        return m_current_write_buffer;\n    }\n}; // class buffer_context_base\n\n} // namespace detail\n\nclass buffer_context MJR_FINAL : public detail::buffer_context_base\n{\n  public:\n    explicit buffer_context(char *buffer, size_t length) : detail::buffer_context_base(buffer, buffer, length)\n    {\n    }\n}; // class buffer_context\n\nclass const_buffer_context MJR_FINAL : public detail::buffer_context_base\n{\n  public:\n    explicit const_buffer_context(const char *buffer, size_t length) : detail::buffer_context_base(buffer, new char[length], length) // don't worry about leaks, buffer_context_base can't throw\n    {\n    }\n\n    ~const_buffer_context()\n    {\n        delete[] m_write_buffer;\n    }\n}; // class const_buffer_context\n\nclass istream_context MJR_FINAL : public detail::context_base\n{\n  private:\n    std::istream &m_stream;\n    size_t m_read_offset;\n    std::list<std::vector<char>> m_write_buffers;\n\n  public:\n    explicit istream_context(std::istream &stream) : m_stream(stream),\n                                                     m_read_offset(0)\n    {\n        new_write_buffer();\n    }\n\n    char read()\n    {\n        const char c = m_stream.get();\n\n        if (m_stream)\n        {\n            m_read_offset++;\n\n            return c;\n        }\n        else\n        {\n            return 0;\n        }\n    }\n\n    size_t read_offset() const\n    {\n        return m_read_offset;\n    }\n\n    void new_write_buffer()\n    {\n        m_write_buffers.push_back(std::vector<char>());\n    }\n\n    void write(char c)\n    {\n        m_write_buffers.back().push_back(c);\n    }\n\n    // This method to retrieve the address of the write buffer MUST be called\n    // AFTER all the calls to write() for the current write buffer have been performed\n    const char *write_buffer() const\n    {\n        return !m_write_buffers.back().empty() ? &m_write_buffers.back()[0] : NULL;\n    }\n}; // class istream_context\n\nclass parse_error : public std::exception\n{\n  public:\n    enum error_reason\n    {\n        UNKNOWN,\n        EXPECTED_OPENING_QUOTE,\n        EXPECTED_UTF16_LOW_SURROGATE,\n        INVALID_ESCAPE_SEQUENCE,\n        INVALID_UTF16_CHARACTER,\n        EXPECTED_CLOSING_QUOTE,\n        INVALID_VALUE,\n        UNTERMINATED_VALUE,\n        EXPECTED_OPENING_BRACKET,\n        EXPECTED_COLON,\n        EXPECTED_COMMA_OR_CLOSING_BRACKET,\n        NESTED_OBJECT_OR_ARRAY_NOT_PARSED,\n        EXCEEDED_NESTING_LIMIT\n    };\n\n  private:\n    size_t m_offset;\n    error_reason m_reason;\n\n    template <typename Context>\n    static size_t get_offset(const Context &context)\n    {\n        const size_t read_offset = context.read_offset();\n\n        return (read_offset != 0) ? (read_offset - 1) : 0;\n    }\n\n  public:\n    template <typename Context>\n    explicit parse_error(const Context &context, error_reason reason) : m_offset(get_offset(context)),\n                                                                        m_reason(reason)\n    {\n    }\n\n    size_t offset() const\n    {\n        return m_offset;\n    }\n\n    error_reason reason() const\n    {\n        return m_reason;\n    }\n\n    const char *what() const throw()\n    {\n        switch (m_reason)\n        {\n        case UNKNOWN:\n            return \"Unknown parse error\";\n        case EXPECTED_OPENING_QUOTE:\n            return \"Expected opening quote\";\n        case EXPECTED_UTF16_LOW_SURROGATE:\n            return \"Expected UTF-16 low surrogate\";\n        case INVALID_ESCAPE_SEQUENCE:\n            return \"Invalid escape sequence\";\n        case INVALID_UTF16_CHARACTER:\n            return \"Invalid UTF-16 character\";\n        case EXPECTED_CLOSING_QUOTE:\n            return \"Expected closing quote\";\n        case INVALID_VALUE:\n            return \"Invalid value\";\n        case UNTERMINATED_VALUE:\n            return \"Unterminated value\";\n        case EXPECTED_OPENING_BRACKET:\n            return \"Expected opening bracket\";\n        case EXPECTED_COLON:\n            return \"Expected colon\";\n        case EXPECTED_COMMA_OR_CLOSING_BRACKET:\n            return \"Expected comma or closing bracket\";\n        case NESTED_OBJECT_OR_ARRAY_NOT_PARSED:\n            return \"Nested object or array not parsed\";\n        case EXCEEDED_NESTING_LIMIT:\n            return \"Exceeded nesting limit (\" MJR_STRINGIFY(MJR_NESTING_LIMIT) \")\";\n        }\n\n        return \"\"; // to suppress compiler warnings -- LCOV_EXCL_LINE\n    }\n}; // class parse_error\n\nnamespace detail\n{\n\nstruct utf8_char\n{\n    uint8_t bytes[4];\n\n    utf8_char()\n    {\n        // wanted use value-initialization, but couldn't because of a weird VS2013 warning\n        std::fill_n(bytes, sizeof(bytes), 0);\n    }\n\n    explicit utf8_char(uint8_t b0, uint8_t b1, uint8_t b2, uint8_t b3)\n    {\n        bytes[0] = b0;\n        bytes[1] = b1;\n        bytes[2] = b2;\n        bytes[3] = b3;\n    }\n\n    uint8_t &operator[](size_t i)\n    {\n        return bytes[i];\n    }\n\n    const uint8_t &operator[](size_t i) const\n    {\n        return bytes[i];\n    }\n\n    bool operator==(const utf8_char &other) const\n    {\n        return std::equal(bytes, bytes + sizeof(bytes), other.bytes);\n    }\n\n    bool operator!=(const utf8_char &other) const\n    {\n        return !operator==(other);\n    }\n}; // struct utf8_char\n\n// this exception is not to be propagated outside minijson\nstruct encoding_error\n{\n};\n\ninline uint32_t utf16_to_utf32(uint16_t high, uint16_t low)\n{\n    uint32_t result;\n\n    if (high <= 0xD7FF || high >= 0xE000)\n    {\n        if (low != 0)\n        {\n            // since the high code unit is not a surrogate, the low code unit should be zero\n            throw encoding_error();\n        }\n\n        result = high;\n    }\n    else\n    {\n        if (high > 0xDBFF) // we already know high >= 0xD800\n        {\n            // the high surrogate is not within the expected range\n            throw encoding_error();\n        }\n\n        if (low < 0xDC00 || low > 0xDFFF)\n        {\n            // the low surrogate is not within the expected range\n            throw encoding_error();\n        }\n\n        high -= 0xD800;\n        low -= 0xDC00;\n        result = 0x010000 + ((high << 10) | low);\n    }\n\n    return result;\n}\n\ninline utf8_char utf32_to_utf8(uint32_t utf32_char)\n{\n    utf8_char result;\n\n    if (utf32_char <= 0x00007F)\n    {\n        result[0] = utf32_char;\n    }\n    else if (utf32_char <= 0x0007FF)\n    {\n        result[0] = 0xC0 | ((utf32_char & (0x1F << 6)) >> 6);\n        result[1] = 0x80 | ((utf32_char & (0x3F)));\n    }\n    else if (utf32_char <= 0x00FFFF)\n    {\n        result[0] = 0xE0 | ((utf32_char & (0x0F << 12)) >> 12);\n        result[1] = 0x80 | ((utf32_char & (0x3F << 6)) >> 6);\n        result[2] = 0x80 | ((utf32_char & (0x3F)));\n    }\n    else if (utf32_char <= 0x1FFFFF)\n    {\n        result[0] = 0xF0 | ((utf32_char & (0x07 << 18)) >> 18);\n        result[1] = 0x80 | ((utf32_char & (0x3F << 12)) >> 12);\n        result[2] = 0x80 | ((utf32_char & (0x3F << 6)) >> 6);\n        result[3] = 0x80 | ((utf32_char & (0x3F)));\n    }\n    else\n    {\n        // invalid code unit\n        throw encoding_error();\n    }\n\n    return result;\n}\n\ninline utf8_char utf16_to_utf8(uint16_t high, uint16_t low)\n{\n    return utf32_to_utf8(utf16_to_utf32(high, low));\n}\n\n// this exception is not to be propagated outside minijson\nstruct number_parse_error\n{\n};\n\ninline long parse_long(const char *str, int base = 10)\n{\n    if ((str == NULL) || (*str == 0) || isspace(str[0])) // we don't accept empty strings or strings with leading spaces\n    {\n        throw number_parse_error();\n    }\n\n#ifdef __ANDROID__\n    volatile int saved_errno = errno; // save errno\n#else\n    int saved_errno = errno; // save errno\n#endif\n    errno = 0; // reset errno\n\n    char *endptr;\n    const long result = std::strtol(str, &endptr, base);\n\n    std::swap(saved_errno, errno); // restore errno\n\n    if (*endptr != 0) // we didn't consume the whole string\n    {\n        throw number_parse_error();\n    }\n    else if ((saved_errno == ERANGE) && ((result == LONG_MIN) || (result == LONG_MAX))) // overflow\n    {\n        throw number_parse_error();\n    }\n\n    return result;\n}\n\ninline double parse_double(const char *str)\n{\n    if ((str == NULL) || (*str == 0)) // we don't accept empty strings\n    {\n        throw number_parse_error();\n    }\n\n    // we perform this check to reject hex numbers (supported in C++11) and string with leading spaces\n    for (const char *c = str; *c != 0; c++)\n    {\n        if (!(isdigit(*c) || (*c == '+') || (*c == '-') || (*c == '.') || (*c == 'e') || (*c == 'E')))\n        {\n            throw number_parse_error();\n        }\n    }\n\n#ifdef __ANDROID__\n    volatile int saved_errno = errno; // save errno\n#else\n    int saved_errno = errno; // save errno\n#endif\n    errno = 0; // reset errno\n\n    char *endptr;\n    const double result = std::strtod(str, &endptr);\n\n    std::swap(saved_errno, errno); // restore errno\n\n    if (*endptr != 0) // we didn't consume the whole string\n    {\n        throw number_parse_error();\n    }\n    else if (saved_errno == ERANGE) // underflow or overflow\n    {\n        throw number_parse_error();\n    }\n\n    return result;\n}\n\nstatic const size_t UTF16_ESCAPE_SEQ_LENGTH = 4;\n\ninline uint16_t parse_utf16_escape_sequence(const char *seq)\n{\n    for (size_t i = 0; i < UTF16_ESCAPE_SEQ_LENGTH; i++)\n    {\n        if (!isxdigit(seq[i]))\n        {\n            throw encoding_error();\n        }\n    }\n\n    return static_cast<uint16_t>(parse_long(seq, 16));\n}\n\ntemplate <typename Context>\nvoid write_utf8_char(Context &context, const utf8_char &c)\n{\n    for (size_t i = 0; i < sizeof(c.bytes); i++)\n    {\n        const char byte = c[i];\n        if ((i > 0) && (byte == 0))\n        {\n            break;\n        }\n\n        context.write(byte);\n    }\n}\n\ntemplate <typename Context>\nvoid read_quoted_string(Context &context, bool skip_opening_quote = false)\n{\n    enum\n    {\n        OPENING_QUOTE,\n        CHARACTER,\n        ESCAPE_SEQUENCE,\n        UTF16_SEQUENCE,\n        CLOSED\n    } state = (skip_opening_quote) ? CHARACTER : OPENING_QUOTE;\n\n    bool empty = true;\n    char utf16_seq[UTF16_ESCAPE_SEQ_LENGTH + 1] = {0};\n    size_t utf16_seq_offset = 0;\n    uint16_t high_surrogate = 0;\n\n    char c;\n\n    while ((state != CLOSED) && ((c = context.read()) != 0))\n    {\n        empty = false;\n\n        switch (state)\n        {\n        case OPENING_QUOTE:\n\n            if (c != '\"')\n            {\n                throw parse_error(context, parse_error::EXPECTED_OPENING_QUOTE);\n            }\n            state = CHARACTER;\n\n            break;\n\n        case CHARACTER:\n\n            if (c == '\\\\')\n            {\n                state = ESCAPE_SEQUENCE;\n            }\n            else if (high_surrogate != 0)\n            {\n                throw parse_error(context, parse_error::EXPECTED_UTF16_LOW_SURROGATE);\n            }\n            else if (c == '\"')\n            {\n                state = CLOSED;\n            }\n            else\n            {\n                context.write(c);\n            }\n\n            break;\n\n        case ESCAPE_SEQUENCE:\n\n            state = CHARACTER;\n\n            switch (c)\n            {\n            case '\"':\n                context.write('\"');\n                break;\n            case '\\\\':\n                context.write('\\\\');\n                break;\n            case '/':\n                context.write('/');\n                break;\n            case 'b':\n                context.write('\\b');\n                break;\n            case 'f':\n                context.write('\\f');\n                break;\n            case 'n':\n                context.write('\\n');\n                break;\n            case 'r':\n                context.write('\\r');\n                break;\n            case 't':\n                context.write('\\t');\n                break;\n            case 'u':\n                state = UTF16_SEQUENCE;\n                break;\n            default:\n                throw parse_error(context, parse_error::INVALID_ESCAPE_SEQUENCE);\n            }\n\n            break;\n\n        case UTF16_SEQUENCE:\n\n            utf16_seq[utf16_seq_offset++] = c;\n\n            if (utf16_seq_offset == sizeof(utf16_seq) - 1)\n            {\n                try\n                {\n                    const uint16_t code_unit = parse_utf16_escape_sequence(utf16_seq);\n\n                    if (high_surrogate != 0)\n                    {\n                        // we were waiting for the low surrogate (that now is code_unit)\n                        write_utf8_char(context, utf16_to_utf8(high_surrogate, code_unit));\n                        high_surrogate = 0;\n                    }\n                    else if (code_unit >= 0xD800 && code_unit <= 0xDBFF)\n                    {\n                        high_surrogate = code_unit;\n                    }\n                    else\n                    {\n                        write_utf8_char(context, utf16_to_utf8(code_unit, 0));\n                    }\n                }\n                catch (const encoding_error &)\n                {\n                    throw parse_error(context, parse_error::INVALID_UTF16_CHARACTER);\n                }\n\n                utf16_seq_offset = 0;\n\n                state = CHARACTER;\n            }\n\n            break;\n\n        case CLOSED: // to silence compiler warnings\n\n            throw std::runtime_error(\"This line should never be reached, please file a bug report\"); // LCOV_EXCL_LINE\n        }\n    }\n\n    if (empty && !skip_opening_quote)\n    {\n        throw parse_error(context, parse_error::EXPECTED_OPENING_QUOTE);\n    }\n    else if (state != CLOSED)\n    {\n        throw parse_error(context, parse_error::EXPECTED_CLOSING_QUOTE);\n    }\n\n    context.write(0);\n}\n\n// reads any value that is not a string (or an object/array)\ntemplate <typename Context>\nchar read_unquoted_value(Context &context, char first_char = 0)\n{\n    if (first_char != 0)\n    {\n        context.write(first_char);\n    }\n\n    char c;\n\n    while (((c = context.read()) != 0) && (c != ',') && (c != '}') && (c != ']') && !isspace(c))\n    {\n        context.write(c);\n    }\n\n    if (c == 0)\n    {\n        throw parse_error(context, parse_error::UNTERMINATED_VALUE);\n    }\n\n    context.write(0);\n\n    return c; // return the termination character (or it will be lost forever)\n}\n\n} // namespace detail\n\nenum value_type\n{\n    String,\n    Number,\n    Boolean,\n    Object,\n    Array,\n    Null\n};\n\nclass value MJR_FINAL\n{\n  private:\n    value_type m_type;\n    const char *m_buffer;\n    long m_long_value;\n    double m_double_value;\n\n  public:\n    explicit value(value_type type = Null, const char *buffer = \"\", long long_value = 0, double double_value = 0.0) : m_type(type),\n                                                                                                                      m_buffer(buffer),\n                                                                                                                      m_long_value(long_value),\n                                                                                                                      m_double_value(double_value)\n    {\n    }\n\n    value_type type() const\n    {\n        return m_type;\n    }\n\n    const char *as_string() const\n    {\n        return m_buffer;\n    }\n\n    long as_long() const\n    {\n        return m_long_value;\n    }\n\n    bool as_bool() const\n    {\n        return (m_long_value) ? true : false; // to avoid VS2013 warnings\n    }\n\n    double as_double() const\n    {\n        return m_double_value;\n    }\n}; // class value\n\nnamespace detail\n{\n\ntemplate <typename Context>\nvalue parse_unquoted_value(const Context &context)\n{\n    const char *const buffer = context.write_buffer();\n\n    if (strcmp(buffer, \"true\") == 0)\n    {\n        return value(Boolean, buffer, 1, 1.0);\n    }\n    else if (strcmp(buffer, \"false\") == 0)\n    {\n        return value(Boolean, buffer, 0, 0.0);\n    }\n    else if (strcmp(buffer, \"null\") == 0)\n    {\n        return value(Null, buffer, 0, 0.0);\n    }\n    else\n    {\n        long long_value = 0;\n        double double_value = 0.0;\n\n        try\n        {\n            long_value = parse_long(buffer);\n            double_value = long_value;\n        }\n        catch (const number_parse_error &)\n        {\n            try\n            {\n                double_value = parse_double(buffer);\n            }\n            catch (const number_parse_error &)\n            {\n                throw parse_error(context, parse_error::INVALID_VALUE);\n            }\n        }\n\n        return value(Number, buffer, long_value, double_value);\n    }\n}\n\ntemplate <typename Context>\nstd::pair<value, char> read_value(Context &context, char first_char)\n{\n    if (first_char == '{')\n    {\n        return std::make_pair(value(Object), 0);\n    }\n    else if (first_char == '[')\n    {\n        return std::make_pair(value(Array), 0);\n    }\n    else if (first_char == '\"') // quoted string\n    {\n        context.new_write_buffer();\n        read_quoted_string(context, true);\n\n        return std::make_pair(value(String, context.write_buffer()), 0);\n    }\n    else // unquoted value\n    {\n        context.new_write_buffer();\n        const char ending_char = read_unquoted_value(context, first_char);\n\n        return std::make_pair(parse_unquoted_value(context), ending_char);\n    }\n}\n\ntemplate <typename Context>\nvoid parse_init_helper(const Context &context, char &c, bool &must_read)\n{\n    switch (context.nested_status())\n    {\n    case Context::NESTED_STATUS_NONE:\n        c = 0;\n        must_read = true;\n        break;\n    case Context::NESTED_STATUS_OBJECT:\n        c = '{';\n        must_read = false;\n        break;\n    case Context::NESTED_STATUS_ARRAY:\n        c = '[';\n        must_read = false;\n        break;\n    }\n}\n\ntemplate <typename Context>\nvalue parse_value_helper(Context &context, char &c, bool &must_read)\n{\n    const std::pair<value, char> read_value_result = detail::read_value(context, c);\n    const value v = read_value_result.first;\n\n    if (v.type() == Object)\n    {\n        context.begin_nested(Context::NESTED_STATUS_OBJECT);\n    }\n    else if (v.type() == Array)\n    {\n        context.begin_nested(Context::NESTED_STATUS_ARRAY);\n    }\n    else if (v.type() != String)\n    {\n        c = read_value_result.second;\n        must_read = false;\n    }\n\n    return v;\n}\n\n} // namespace detail\n\ntemplate <typename Context, typename Handler>\nvoid parse_object(Context &context, Handler handler)\n{\n    const size_t nesting_level = context.nesting_level();\n    if (nesting_level > MJR_NESTING_LIMIT)\n    {\n        throw parse_error(context, parse_error::EXCEEDED_NESTING_LIMIT);\n    }\n\n    char c = 0;\n    bool must_read = false;\n\n    parse_init_helper(context, c, must_read);\n    context.reset_nested_status();\n\n    enum\n    {\n        OPENING_BRACKET,\n        FIELD_NAME_OR_CLOSING_BRACKET, // in case the object is empty\n        FIELD_NAME,\n        COLON,\n        FIELD_VALUE,\n        COMMA_OR_CLOSING_BRACKET,\n        END\n    } state = OPENING_BRACKET;\n\n    const char *field_name = \"\";\n\n    while (state != END)\n    {\n        if (context.nesting_level() != nesting_level)\n        {\n            throw parse_error(context, parse_error::NESTED_OBJECT_OR_ARRAY_NOT_PARSED);\n        }\n\n        if (must_read)\n        {\n            c = context.read();\n        }\n\n        must_read = true;\n\n        if (isspace(c)) // skip whitespace\n        {\n            continue;\n        }\n\n        switch (state)\n        {\n        case OPENING_BRACKET:\n            if (c != '{')\n            {\n                //std::cout<<\"fuck:\"<<static_cast<int>(c)<<std::endl;\n                throw parse_error(context, parse_error::EXPECTED_OPENING_BRACKET);\n            }\n            state = FIELD_NAME_OR_CLOSING_BRACKET;\n            break;\n\n        case FIELD_NAME_OR_CLOSING_BRACKET:\n            if (c == '}')\n            {\n                state = END;\n                break;\n            }\n            // intentional fall-through\n\n        case FIELD_NAME:\n            if (c != '\"')\n            {\n                throw parse_error(context, parse_error::EXPECTED_OPENING_QUOTE);\n            }\n            context.new_write_buffer();\n            detail::read_quoted_string(context, true);\n            field_name = context.write_buffer();\n            state = COLON;\n            break;\n\n        case COLON:\n            if (c != ':')\n            {\n                throw parse_error(context, parse_error::EXPECTED_COLON);\n            }\n            state = FIELD_VALUE;\n            break;\n\n        case FIELD_VALUE:\n            handler(field_name, parse_value_helper(context, c, must_read));\n            state = COMMA_OR_CLOSING_BRACKET;\n            break;\n\n        case COMMA_OR_CLOSING_BRACKET:\n            if (c == ',')\n            {\n                state = FIELD_NAME;\n            }\n            else if (c == '}')\n            {\n                state = END;\n            }\n            else\n            {\n                throw parse_error(context, parse_error::EXPECTED_COMMA_OR_CLOSING_BRACKET);\n            }\n            break;\n\n        case END:\n\n            throw std::runtime_error(\"This line should never be reached, please file a bug report\"); // LCOV_EXCL_LINE\n        }\n\n        if (c == 0)\n        {\n            throw std::runtime_error(\"This line should never be reached, please file a bug report\"); // LCOV_EXCL_LINE\n        }\n    }\n\n    context.end_nested();\n}\n\ntemplate <typename Context, typename Handler>\nvoid parse_array(Context &context, Handler handler)\n{\n    const size_t nesting_level = context.nesting_level();\n    if (nesting_level > MJR_NESTING_LIMIT)\n    {\n        throw parse_error(context, parse_error::EXCEEDED_NESTING_LIMIT);\n    }\n\n    char c = 0;\n    bool must_read = false;\n\n    parse_init_helper(context, c, must_read);\n    context.reset_nested_status();\n\n    enum\n    {\n        OPENING_BRACKET,\n        VALUE_OR_CLOSING_BRACKET, // in case the array is empty\n        VALUE,\n        COMMA_OR_CLOSING_BRACKET,\n        END\n    } state = OPENING_BRACKET;\n\n    while (state != END)\n    {\n        if (context.nesting_level() != nesting_level)\n        {\n            throw parse_error(context, parse_error::NESTED_OBJECT_OR_ARRAY_NOT_PARSED);\n        }\n\n        if (must_read)\n        {\n            c = context.read();\n        }\n\n        must_read = true;\n\n        if (isspace(c)) // skip whitespace\n        {\n            continue;\n        }\n\n        switch (state)\n        {\n        case OPENING_BRACKET:\n            if (c != '[')\n            {\n                throw parse_error(context, parse_error::EXPECTED_OPENING_BRACKET);\n            }\n            state = VALUE_OR_CLOSING_BRACKET;\n            break;\n\n        case VALUE_OR_CLOSING_BRACKET:\n            if (c == ']')\n            {\n                state = END;\n                break;\n            }\n            // intentional fall-through\n\n        case VALUE:\n            handler(parse_value_helper(context, c, must_read));\n            state = COMMA_OR_CLOSING_BRACKET;\n            break;\n\n        case COMMA_OR_CLOSING_BRACKET:\n            if (c == ',')\n            {\n                state = VALUE;\n            }\n            else if (c == ']')\n            {\n                state = END;\n            }\n            else\n            {\n                throw parse_error(context, parse_error::EXPECTED_COMMA_OR_CLOSING_BRACKET);\n            }\n            break;\n\n        case END:\n\n            throw std::runtime_error(\"This line should never be reached, please file a bug report\"); // LCOV_EXCL_LINE\n        }\n\n        if (c == 0)\n        {\n            throw std::runtime_error(\"This line should never be reached, please file a bug report\"); // LCOV_EXCL_LINE\n        }\n    }\n\n    context.end_nested();\n}\n\nnamespace detail\n{\n\nclass dispatch_rule; // forward declaration\n\n} // namespace detail\n\nclass dispatch : detail::noncopyable\n{\n    friend class detail::dispatch_rule;\n\n  private:\n    const char *m_field_name;\n    bool m_handled;\n\n  public:\n    explicit dispatch(const char *field_name) : m_field_name(field_name),\n                                                m_handled(false)\n    {\n    }\n\n    explicit dispatch(const std::string &field_name) : m_field_name(field_name.c_str()),\n                                                       m_handled(false)\n    {\n    }\n\n    detail::dispatch_rule operator<<(const char *field_name);\n    detail::dispatch_rule operator<<(const std::string &field_name);\n}; // class dispatch\n\nnamespace detail\n{\n\nclass dispatch_rule\n{\n  private:\n    dispatch &m_dispatch;\n    const char *m_field_name;\n\n  public:\n    explicit dispatch_rule(dispatch &parent_dispatch, const char *field_name) : m_dispatch(parent_dispatch),\n                                                                                m_field_name(field_name)\n    {\n    }\n\n    template <typename Handler>\n    dispatch &operator>>(Handler handler) const\n    {\n        if (!m_dispatch.m_handled && ((m_field_name == NULL) || (strcmp(m_dispatch.m_field_name, m_field_name) == 0)))\n        {\n            handler();\n            m_dispatch.m_handled = true;\n        }\n\n        return m_dispatch;\n    }\n}; // class dispatch_rule\n\ntemplate <typename Context>\nclass ignore\n{\n    Context &m_context;\n\n  public:\n    explicit ignore(Context &context) : m_context(context)\n    {\n    }\n\n    void operator()(const char *, value)\n    {\n        operator()();\n    }\n\n    void operator()(value)\n    {\n        operator()();\n    }\n\n    void operator()() const\n    {\n        switch (m_context.nested_status())\n        {\n        case Context::NESTED_STATUS_NONE:\n            break;\n        case Context::NESTED_STATUS_OBJECT:\n            parse_object(m_context, *this);\n            break;\n        case Context::NESTED_STATUS_ARRAY:\n            parse_array(m_context, *this);\n            break;\n        }\n    }\n}; // class ignore\n\n} // namespace detail\n\ninline detail::dispatch_rule dispatch::operator<<(const char *field_name)\n{\n    return detail::dispatch_rule(*this, field_name);\n}\n\ninline detail::dispatch_rule dispatch::operator<<(const std::string &field_name)\n{\n    return operator<<(field_name.c_str());\n}\n\nstatic const char *const any = NULL;\n\ntemplate <typename Context>\nvoid ignore(Context &context)\n{\n    detail::ignore<Context> ignore(context);\n    ignore();\n}\n\n} // namespace minijson\n\n#endif // MINIJSON_READER_H\n\n#undef MJR_STRINGIFY\n#undef MJR_STRINGIFY_HELPER\n"
  },
  {
    "path": "thirdparty/json/minijson_writer.hpp",
    "content": "#ifndef MINIJSON_WRITER_H\n#define MINIJSON_WRITER_H\n\n#include <cstddef>\n#include <iomanip>\n#include <iterator>\n#include <locale>\n#include <ostream>\n#include <string>\n#include <utility>\n\n#define MJW_CPP11_SUPPORTED __cplusplus > 199711L || _MSC_VER >= 1800\n\n#if MJW_CPP11_SUPPORTED\n\n#include <cmath>\n#include <type_traits>\n#define MJW_LIB_NS std\n#define MJW_ISFINITE(X) std::isfinite(X)\n#define MJW_STATIC_ASSERT(COND, MESSAGE) static_assert(COND, MESSAGE)\n\n#else\n\n#include <boost/type_traits/remove_cv.hpp>\n#include <boost/type_traits/is_integral.hpp>\n#include <boost/type_traits/is_same.hpp>\n#include <boost/type_traits/is_floating_point.hpp>\n#include <boost/math/special_functions/fpclassify.hpp>\n#define MJW_LIB_NS boost\n#define MJW_ISFINITE(X) boost::math::isfinite(X)\n#define MJW_STATIC_ASSERT(COND, MESSAGE) BOOST_STATIC_ASSERT(COND)\n\n#endif\n\nnamespace minijson\n{\n\nenum null_t\n{\n    null = 0\n};\n\nclass writer_configuration\n{\n  private:\n    size_t m_nesting_level;\n    bool m_pretty_printing;\n    size_t m_indent_spaces;\n    bool m_use_tabs;\n\n  public:\n    explicit writer_configuration() : m_nesting_level(0),\n                                      m_pretty_printing(false),\n                                      m_indent_spaces(4),\n                                      m_use_tabs(false)\n    {\n    }\n\n    size_t nesting_level() const\n    {\n        return m_nesting_level;\n    }\n\n    writer_configuration increase_nesting_level() const\n    {\n        writer_configuration result = *this;\n        result.m_nesting_level++;\n\n        return result;\n    }\n\n    bool pretty_printing() const\n    {\n        return m_pretty_printing;\n    }\n\n    writer_configuration pretty_printing(bool value) const\n    {\n        writer_configuration result = *this;\n        result.m_pretty_printing = value;\n\n        return result;\n    }\n\n    size_t indent_spaces() const\n    {\n        return m_indent_spaces;\n    }\n\n    writer_configuration indent_spaces(size_t value) const\n    {\n        writer_configuration result = *this;\n        result.m_indent_spaces = value;\n\n        return result;\n    }\n\n    bool use_tabs() const\n    {\n        return m_use_tabs;\n    }\n\n    writer_configuration use_tabs(bool value) const\n    {\n        writer_configuration result = *this;\n        result.m_use_tabs = value;\n\n        return result;\n    }\n};\n\ntemplate <typename V, typename Enable = void>\nstruct default_value_writer;\n\ntemplate <typename InputIt>\nvoid write_array(\n    std::ostream &stream,\n    InputIt begin, InputIt end,\n    const writer_configuration &configuration = writer_configuration());\n\ntemplate <typename InputIt, typename ValueWriter>\nvoid write_array(\n    std::ostream &stream,\n    InputIt begin, InputIt end,\n    const ValueWriter &value_writer,\n    const writer_configuration &configuration = writer_configuration());\n\nnamespace detail\n{\n\ntemplate <bool>\nstruct enable_if;\n\ntemplate <>\nstruct enable_if<true>\n{\n    typedef void type;\n};\n\ntemplate <typename InputIt>\nstruct get_value_type\n{\n    typedef typename MJW_LIB_NS::remove_cv<typename std::iterator_traits<InputIt>::value_type>::type type;\n};\n\n#if MJW_CPP11_SUPPORTED\n\ntemplate <size_t Rank>\nstruct overload_rank : overload_rank<Rank - 1>\n{\n};\n\ntemplate <>\nstruct overload_rank<0>\n{\n};\n\ntypedef overload_rank<63> call_ranked;\n\ntemplate <typename Functor>\nstruct two_or_three_args_functor\n{\n  private:\n    Functor functor;\n\n    template <typename Arg1, typename Arg2, typename Arg3>\n    auto operator_impl(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3, overload_rank<1>)\n        -> decltype(functor(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2), std::forward<Arg3>(arg3)))\n    {\n        functor(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2), std::forward<Arg3>(arg3));\n    }\n\n    template <typename Arg1, typename Arg2, typename Arg3>\n    auto operator_impl(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&, overload_rank<0>)\n        -> decltype(functor(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2)))\n    {\n        functor(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2));\n    }\n\n  public:\n    explicit two_or_three_args_functor(Functor functor) : functor(std::move(functor))\n    {\n    }\n\n    template <typename Arg1, typename Arg2, typename Arg3>\n    void operator()(Arg1 &&arg1, Arg2 &&arg2, Arg3 &&arg3)\n    {\n        operator_impl(std::forward<Arg1>(arg1), std::forward<Arg2>(arg2), std::forward<Arg3>(arg3), call_ranked());\n    }\n};\n\n#else\n\ntemplate <typename Functor>\nstruct two_or_three_args_functor : Functor\n{\n    mutable Functor functor;\n\n    explicit two_or_three_args_functor(const Functor &functor) : Functor(functor),\n                                                                 functor(functor)\n    {\n    }\n\n    using Functor::operator();\n\n    template <typename Arg1, typename Arg2, typename Arg3>\n    void operator()(Arg1 &arg1, Arg2 &arg2, Arg3 &) const\n    {\n        functor(arg1, arg2);\n    }\n};\n\ntemplate <typename R, typename X1, typename X2>\nstruct two_or_three_args_functor<R (*)(X1, X2)>\n{\n    typedef R (*Function)(X1, X2);\n\n    Function function;\n\n    explicit two_or_three_args_functor(Function function) : function(function)\n    {\n    }\n\n    template <typename Arg1, typename Arg2, typename Arg3>\n    void operator()(Arg1 &arg1, Arg2 &arg2, Arg3 &) const\n    {\n        function(arg1, arg2);\n    }\n};\n\ntemplate <typename R, typename X1, typename X2, typename X3>\nstruct two_or_three_args_functor<R (*)(X1, X2, X3)>\n{\n    typedef R (*Function)(X1, X2, X3);\n\n    Function function;\n\n    explicit two_or_three_args_functor(Function function) : function(function)\n    {\n    }\n\n    template <typename Arg1, typename Arg2, typename Arg3>\n    void operator()(Arg1 &arg1, Arg2 &arg2, Arg3 &arg3) const\n    {\n        function(arg1, arg2, arg3);\n    }\n};\n\n#endif\n\ntemplate <typename Functor>\ntwo_or_three_args_functor<Functor> wrap_two_or_three_args_functor(Functor functor)\n{\n    return two_or_three_args_functor<Functor>(functor);\n}\n\ntemplate <size_t Size = 128>\nclass buffered_writer\n{\n    MJW_STATIC_ASSERT(Size != 0, \"Illegal instantiation of buffered_writer\");\n\n  private:\n    std::ostream &m_stream;\n    char m_buffer[Size];\n    size_t m_offset;\n\n    buffered_writer(const buffered_writer &);\n    buffered_writer &operator=(const buffered_writer &);\n\n  public:\n    explicit buffered_writer(std::ostream &stream) : m_stream(stream),\n                                                     m_offset(0)\n    {\n    }\n\n    buffered_writer &operator<<(char c)\n    {\n        if (m_offset == Size)\n        {\n            flush();\n        }\n\n        m_buffer[m_offset++] = c;\n\n        return *this;\n    }\n\n    template <size_t N>\n    buffered_writer &operator<<(const char (&str)[N])\n    {\n        MJW_STATIC_ASSERT(N != 0, \"Illegal instantiation of buffered_writer::operator<<(const char (&str)[N])\");\n\n        for (size_t i = 0; i < N - 1; i++)\n        {\n            operator<<(str[i]);\n        }\n\n        return *this;\n    }\n\n    void flush()\n    {\n        m_stream.write(m_buffer, m_offset);\n\n        m_offset = 0;\n    }\n};\n\nnamespace\n{\n\nvoid adjust_stream_settings(std::ostream &stream)\n{\n    stream.imbue(std::locale::classic());\n    stream << std::resetiosflags(std::ios::showpoint | std::ios::showpos);\n    stream << std::dec << std::setw(0);\n}\n\nvoid write_quoted_string(std::ostream &stream, const char *str)\n{\n    stream << std::hex << std::right << std::setfill('0');\n\n    buffered_writer<> writer(stream);\n\n    writer << '\"';\n\n    while (*str != '\\0')\n    {\n        switch (*str)\n        {\n        case '\"':\n            writer << \"\\\\\\\"\";\n            break;\n\n        case '\\\\':\n            writer << \"\\\\\\\\\";\n            break;\n\n        case '\\n':\n            writer << \"\\\\n\";\n            break;\n\n        case '\\r':\n            writer << \"\\\\r\";\n            break;\n\n        case '\\t':\n            writer << \"\\\\t\";\n            break;\n\n        default:\n            if ((*str > 0 && *str < 32) || *str == 127) // ASCII control characters (NUL is not supported)\n            {\n                writer << \"\\\\u\";\n\n                writer.flush();\n                stream << std::setw(4) << static_cast<unsigned>(*str);\n            }\n            else\n            {\n                writer << *str;\n            }\n            break;\n        }\n        str++;\n    }\n\n    writer << '\"';\n\n    writer.flush();\n\n    stream << std::dec;\n}\n\n} // unnamed namespace\n\ntemplate <typename InputIt>\nstruct range\n{\n    InputIt begin;\n    InputIt end;\n};\n\ntemplate <typename InputIt>\nrange<InputIt> make_range(InputIt begin, InputIt end)\n{\n    const range<InputIt> range = {begin, end};\n\n    return range;\n}\n\ntemplate <typename InputIt, typename ValueWriter>\nclass range_writer\n{\n  private:\n    ValueWriter m_value_writer;\n\n  public:\n    explicit range_writer(const ValueWriter &value_writer) : m_value_writer(value_writer)\n    {\n    }\n\n    void operator()(std::ostream &stream, const range<InputIt> &range, const writer_configuration &configuration) const\n    {\n        write_array(stream, range.begin, range.end, m_value_writer, configuration);\n    }\n};\n\n} // namespace detail\n\nclass writer\n{\n  private:\n    enum status\n    {\n        EMPTY,\n        OPEN,\n        CLOSED\n    };\n\n    bool m_array;\n    status m_status;\n    std::ostream *m_stream;\n    writer_configuration m_configuration;\n\n    enum pretty_print_token\n    {\n        BEFORE_ELEMENT,\n        AFTER_COLON,\n        BEFORE_CLOSING_BRACKET\n    };\n\n    void write_pretty_print_token(pretty_print_token token)\n    {\n        if (!m_configuration.pretty_printing())\n        {\n            return;\n        }\n\n        detail::buffered_writer<16> writer(*m_stream);\n\n        if ((token == BEFORE_ELEMENT) || ((token == BEFORE_CLOSING_BRACKET) && (m_status != EMPTY)))\n        {\n            const size_t base_depth = (token == BEFORE_ELEMENT) ? 1 : 0;\n            const size_t no_indent_characters = m_configuration.use_tabs() ? (base_depth + m_configuration.nesting_level()) : (base_depth + m_configuration.nesting_level()) * m_configuration.indent_spaces();\n\n            writer << '\\n';\n\n            for (size_t i = 0; i < no_indent_characters; i++)\n            {\n                writer << ((m_configuration.use_tabs()) ? '\\t' : ' ');\n            }\n        }\n        else if (token == AFTER_COLON)\n        {\n            writer << ' ';\n        }\n\n        writer.flush();\n    }\n\n    void write_opening_bracket()\n    {\n        if (m_array)\n        {\n            *m_stream << '[';\n        }\n        else\n        {\n            *m_stream << '{';\n        }\n    }\n\n    void write_closing_bracket()\n    {\n        write_pretty_print_token(BEFORE_CLOSING_BRACKET);\n\n        if (m_array)\n        {\n            *m_stream << ']';\n        }\n        else\n        {\n            *m_stream << '}';\n        }\n    }\n\n  protected:\n    void next_field()\n    {\n        if (m_status == EMPTY)\n        {\n            write_opening_bracket();\n        }\n        else if (m_status == OPEN)\n        {\n            *m_stream << ',';\n        }\n\n        write_pretty_print_token(BEFORE_ELEMENT);\n\n        m_status = OPEN;\n    }\n\n    void write_field_name(const char *name)\n    {\n        detail::write_quoted_string(*m_stream, name);\n\n        *m_stream << ':';\n\n        write_pretty_print_token(AFTER_COLON);\n    }\n\n    template <typename V, typename ValueWriter>\n    void write_helper(const char *field_name, const V &value, const ValueWriter &value_writer)\n    {\n        if (m_status == CLOSED)\n        {\n            return;\n        }\n\n        detail::adjust_stream_settings(*m_stream);\n\n        next_field();\n\n        if (field_name != NULL)\n        {\n            write_field_name(field_name);\n        }\n\n        const writer_configuration nested_object_configuration = m_configuration.increase_nesting_level();\n        detail::wrap_two_or_three_args_functor(value_writer)(*m_stream, value, nested_object_configuration);\n    }\n\n    explicit writer(std::ostream &stream, bool array, const writer_configuration &configuration) : m_array(array),\n                                                                                                   m_status(EMPTY),\n                                                                                                   m_stream(&stream),\n                                                                                                   m_configuration(configuration)\n    {\n    }\n\n  public:\n    std::ostream &stream() const\n    {\n        return *m_stream;\n    }\n\n    const writer_configuration &configuration() const\n    {\n        return m_configuration;\n    }\n\n    void close()\n    {\n        if (m_status == CLOSED)\n        {\n            return;\n        }\n\n        detail::adjust_stream_settings(*m_stream);\n\n        if (m_status == EMPTY)\n        {\n            write_opening_bracket();\n        }\n\n        write_closing_bracket();\n\n        m_status = CLOSED;\n    }\n};\n\nclass object_writer;\nclass array_writer;\n\nclass object_writer : public writer\n{\n  public:\n    explicit object_writer(std::ostream &stream, const writer_configuration &configuration = writer_configuration()) : writer(stream, false, configuration)\n    {\n    }\n\n    template <typename V>\n    void write(const char *field_name, const V &value)\n    {\n        write_helper(field_name, value, default_value_writer<V>());\n    }\n\n    template <typename V, typename ValueWriter>\n    void write(const char *field_name, const V &value, const ValueWriter &value_writer)\n    {\n        write_helper(field_name, value, value_writer);\n    }\n\n    template <typename InputIt>\n    void write_array(const char *field_name, InputIt begin, InputIt end)\n    {\n        write_array(field_name, begin, end, default_value_writer<typename detail::get_value_type<InputIt>::type>());\n    }\n\n    template <typename InputIt, typename ValueWriter>\n    void write_array(const char *field_name, InputIt begin, InputIt end, ValueWriter value_writer)\n    {\n        write(field_name, detail::make_range(begin, end), detail::range_writer<InputIt, ValueWriter>(value_writer));\n    }\n\n    object_writer nested_object(const char *field_name);\n\n    array_writer nested_array(const char *field_name);\n};\n\nclass array_writer : public writer\n{\n  public:\n    explicit array_writer(std::ostream &stream, const writer_configuration &configuration = writer_configuration()) : writer(stream, true, configuration)\n    {\n    }\n\n    template <typename V>\n    void write(const V &value)\n    {\n        write_helper(NULL, value, default_value_writer<V>());\n    }\n\n    template <typename V, typename ValueWriter>\n    void write(const V &value, const ValueWriter &value_writer)\n    {\n        write_helper(NULL, value, value_writer);\n    }\n\n    template <typename InputIt>\n    void write_array(InputIt begin, InputIt end)\n    {\n        write_array(begin, end, default_value_writer<typename detail::get_value_type<InputIt>::type>());\n    }\n\n    template <typename InputIt, typename ValueWriter>\n    void write_array(InputIt begin, InputIt end, ValueWriter value_writer)\n    {\n        write(detail::make_range(begin, end), detail::range_writer<InputIt, ValueWriter>(value_writer));\n    }\n\n    object_writer nested_object();\n\n    array_writer nested_array();\n};\n\ninline object_writer object_writer::nested_object(const char *field_name)\n{\n    detail::adjust_stream_settings(stream());\n\n    next_field();\n    write_field_name(field_name);\n\n    return object_writer(stream(), configuration().increase_nesting_level());\n}\n\ninline array_writer object_writer::nested_array(const char *field_name)\n{\n    detail::adjust_stream_settings(stream());\n\n    next_field();\n    write_field_name(field_name);\n\n    return array_writer(stream(), configuration().increase_nesting_level());\n}\n\ninline object_writer array_writer::nested_object()\n{\n    detail::adjust_stream_settings(stream());\n\n    next_field();\n\n    return object_writer(stream(), configuration().increase_nesting_level());\n}\n\ninline array_writer array_writer::nested_array()\n{\n    detail::adjust_stream_settings(stream());\n\n    next_field();\n\n    return array_writer(stream(), configuration().increase_nesting_level());\n}\n\ntemplate <>\nstruct default_value_writer<null_t>\n{\n    void operator()(std::ostream &stream, null_t) const\n    {\n        stream << \"null\";\n    }\n};\n\n#if MJW_CPP11_SUPPORTED\ntemplate <>\nstruct default_value_writer<std::nullptr_t>\n{\n    void operator()(std::ostream &stream, std::nullptr_t) const\n    {\n        default_value_writer<null_t>()(stream, null);\n    }\n};\n#endif\n\ntemplate <typename IntegralType>\nstruct default_value_writer<\n    IntegralType,\n    typename detail::enable_if<MJW_LIB_NS::is_integral<IntegralType>::value && !MJW_LIB_NS::is_same<IntegralType, bool>::value>::type>\n{\n    void operator()(std::ostream &stream, IntegralType value) const\n    {\n        // the unary plus is used here to force chars to be printed as integers\n        stream << +value;\n    }\n};\n\ntemplate <>\nstruct default_value_writer<bool>\n{\n    void operator()(std::ostream &stream, bool value) const\n    {\n        if (value)\n        {\n            stream << \"true\";\n        }\n        else\n        {\n            stream << \"false\";\n        }\n    }\n};\n\ntemplate <typename FloatingPoint>\nstruct default_value_writer<\n    FloatingPoint,\n    typename detail::enable_if<MJW_LIB_NS::is_floating_point<FloatingPoint>::value>::type>\n{\n    void operator()(std::ostream &stream, FloatingPoint value) const\n    {\n        // Numeric values that cannot be represented as sequences of digits\n        // (such as Infinity and NaN) are not permitted in JSON\n        if (!MJW_ISFINITE(value))\n        {\n            default_value_writer<null_t>()(stream, null); // falling back to null\n        }\n        else\n        {\n            stream << value;\n        }\n    }\n};\n\ntemplate <>\nstruct default_value_writer<char *>\n{\n    void operator()(std::ostream &stream, const char *str) const\n    {\n        detail::write_quoted_string(stream, str);\n    }\n};\n\ntemplate <>\nstruct default_value_writer<const char *> : public default_value_writer<char *>\n{\n};\n\ntemplate <size_t N>\nstruct default_value_writer<char[N]> : public default_value_writer<char *>\n{\n};\n\ntemplate <size_t N>\nstruct default_value_writer<const char[N]> : public default_value_writer<char *>\n{\n};\n\ntemplate <>\nstruct default_value_writer<std::string>\n{\n    void operator()(std::ostream &stream, const std::string &str) const\n    {\n        default_value_writer<char *>()(stream, str.c_str());\n    }\n};\n\ntemplate <typename InputIt>\nvoid write_array(\n    std::ostream &stream,\n    InputIt begin, InputIt end,\n    const writer_configuration &configuration)\n{\n    write_array(stream, begin, end, default_value_writer<typename detail::get_value_type<InputIt>::type>(), configuration);\n}\n\ntemplate <typename InputIt, typename ValueWriter>\nvoid write_array(\n    std::ostream &stream,\n    InputIt begin, InputIt end,\n    const ValueWriter &value_writer,\n    const writer_configuration &configuration)\n{\n    array_writer writer(stream, configuration);\n\n    for (InputIt it = begin; it != end; ++it)\n    {\n        writer.write(*it, value_writer);\n    }\n\n    writer.close();\n}\n\n} // namespace minijson\n\n#endif // MINIJSON_WRITER_H\n"
  },
  {
    "path": "thirdparty/jsoncpp/CMakeLists.txt",
    "content": "FILE(GLOB_RECURSE jsoncpp_SOURCES \"*.cpp\")\n\nSET(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations\")\n\nADD_LIBRARY(jsoncpp_static STATIC ${jsoncpp_SOURCES})\nSET_TARGET_PROPERTIES(jsoncpp_static PROPERTIES OUTPUT_NAME jsoncpp)\nTARGET_LINK_LIBRARIES(jsoncpp_static)\nINSTALL(TARGETS jsoncpp_static DESTINATION lib)\n\nIF(ENABLE_SHARED_LIBS)\n  ADD_LIBRARY(jsoncpp_shared SHARED ${jsoncpp_SOURCES})\n  SET_TARGET_PROPERTIES(jsoncpp_shared PROPERTIES OUTPUT_NAME jsoncpp)\n  TARGET_LINK_LIBRARIES(jsoncpp_shared)\n  INSTALL(TARGETS jsoncpp_shared DESTINATION lib)\nENDIF()\n"
  },
  {
    "path": "thirdparty/jsoncpp/json/json-forwards.h",
    "content": "/// Json-cpp amalgated forward header (http://jsoncpp.sourceforge.net/).\n/// It is intended to be used with #include \"json/json-forwards.h\"\n/// This header provides forward declaration for all JsonCpp types.\n\n// //////////////////////////////////////////////////////////////////////\n// Beginning of content of file: LICENSE\n// //////////////////////////////////////////////////////////////////////\n\n/*\nThe JsonCpp library's source code, including accompanying documentation, \ntests and demonstration applications, are licensed under the following\nconditions...\n\nBaptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all \njurisdictions which recognize such a disclaimer. In such jurisdictions, \nthis software is released into the Public Domain.\n\nIn jurisdictions which do not recognize Public Domain property (e.g. Germany as of\n2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and\nThe JsonCpp Authors, and is released under the terms of the MIT License (see below).\n\nIn jurisdictions which recognize Public Domain property, the user of this \nsoftware may choose to accept it either as 1) Public Domain, 2) under the \nconditions of the MIT License (see below), or 3) under the terms of dual \nPublic Domain/MIT License conditions described here, as they choose.\n\nThe MIT License is about as close to Public Domain as a license can get, and is\ndescribed in clear, concise terms at:\n\n   http://en.wikipedia.org/wiki/MIT_License\n   \nThe full text of the MIT License follows:\n\n========================================================================\nCopyright (c) 2007-2010 Baptiste Lepilleur and The JsonCpp Authors\n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this software and associated documentation\nfiles (the \"Software\"), to deal in the Software without\nrestriction, including without limitation the rights to use, copy,\nmodify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\nBE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\nACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n========================================================================\n(END LICENSE TEXT)\n\nThe MIT license is compatible with both the GPL and commercial\nsoftware, affording one all of the rights of Public Domain with the\nminor nuisance of being required to keep the above copyright notice\nand license text in the source code. Note also that by accepting the\nPublic Domain \"license\" you can re-license your copy using whatever\nlicense you like.\n\n*/\n\n// //////////////////////////////////////////////////////////////////////\n// End of content of file: LICENSE\n// //////////////////////////////////////////////////////////////////////\n\n#ifndef JSON_FORWARD_AMALGATED_H_INCLUDED\n#define JSON_FORWARD_AMALGATED_H_INCLUDED\n/// If defined, indicates that the source file is amalgated\n/// to prevent private header inclusion.\n#define JSON_IS_AMALGAMATION\n\n// //////////////////////////////////////////////////////////////////////\n// Beginning of content of file: include/json/config.h\n// //////////////////////////////////////////////////////////////////////\n\n// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors\n// Distributed under MIT license, or public domain if desired and\n// recognized in your jurisdiction.\n// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE\n\n#ifndef JSON_CONFIG_H_INCLUDED\n#define JSON_CONFIG_H_INCLUDED\n#include <stddef.h>\n#include <string>   //typedef String\n#include <stdint.h> //typedef int64_t, uint64_t\n\n/// If defined, indicates that json library is embedded in CppTL library.\n//# define JSON_IN_CPPTL 1\n\n/// If defined, indicates that json may leverage CppTL library\n//#  define JSON_USE_CPPTL 1\n/// If defined, indicates that cpptl vector based map should be used instead of\n/// std::map\n/// as Value container.\n//#  define JSON_USE_CPPTL_SMALLMAP 1\n\n// If non-zero, the library uses exceptions to report bad input instead of C\n// assertion macros. The default is to use exceptions.\n#ifndef JSON_USE_EXCEPTION\n#define JSON_USE_EXCEPTION 1\n#endif\n\n/// If defined, indicates that the source file is amalgated\n/// to prevent private header inclusion.\n/// Remarks: it is automatically defined in the generated amalgated header.\n// #define JSON_IS_AMALGAMATION\n\n#ifdef JSON_IN_CPPTL\n#include <cpptl/config.h>\n#ifndef JSON_USE_CPPTL\n#define JSON_USE_CPPTL 1\n#endif\n#endif\n\n#ifdef JSON_IN_CPPTL\n#define JSON_API CPPTL_API\n#elif defined(JSON_DLL_BUILD)\n#if defined(_MSC_VER) || defined(__MINGW32__)\n#define JSON_API __declspec(dllexport)\n#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING\n#endif // if defined(_MSC_VER)\n#elif defined(JSON_DLL)\n#if defined(_MSC_VER) || defined(__MINGW32__)\n#define JSON_API __declspec(dllimport)\n#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING\n#endif // if defined(_MSC_VER)\n#endif // ifdef JSON_IN_CPPTL\n#if !defined(JSON_API)\n#define JSON_API\n#endif\n\n// If JSON_NO_INT64 is defined, then Json only support C++ \"int\" type for\n// integer\n// Storages, and 64 bits integer support is disabled.\n// #define JSON_NO_INT64 1\n\n#if defined(_MSC_VER) // MSVC\n#if _MSC_VER <= 1200  // MSVC 6\n// Microsoft Visual Studio 6 only support conversion from __int64 to double\n// (no conversion from unsigned __int64).\n#define JSON_USE_INT64_DOUBLE_CONVERSION 1\n// Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255'\n// characters in the debug information)\n// All projects I've ever seen with VS6 were using this globally (not bothering\n// with pragma push/pop).\n#pragma warning(disable : 4786)\n#endif // MSVC 6\n\n#if _MSC_VER >= 1500 // MSVC 2008\n/// Indicates that the following function is deprecated.\n#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))\n#endif\n\n#endif // defined(_MSC_VER)\n\n// In c++11 the override keyword allows you to explicity define that a function\n// is intended to override the base-class version.  This makes the code more\n// managable and fixes a set of common hard-to-find bugs.\n#if __cplusplus >= 201103L\n#define JSONCPP_OVERRIDE override\n#define JSONCPP_NOEXCEPT noexcept\n#elif defined(_MSC_VER) && _MSC_VER > 1600 && _MSC_VER < 1900\n#define JSONCPP_OVERRIDE override\n#define JSONCPP_NOEXCEPT throw()\n#elif defined(_MSC_VER) && _MSC_VER >= 1900\n#define JSONCPP_OVERRIDE override\n#define JSONCPP_NOEXCEPT noexcept\n#else\n#define JSONCPP_OVERRIDE\n#define JSONCPP_NOEXCEPT throw()\n#endif\n\n#ifndef JSON_HAS_RVALUE_REFERENCES\n\n#if defined(_MSC_VER) && _MSC_VER >= 1600 // MSVC >= 2010\n#define JSON_HAS_RVALUE_REFERENCES 1\n#endif // MSVC >= 2010\n\n#ifdef __clang__\n#if __has_feature(cxx_rvalue_references)\n#define JSON_HAS_RVALUE_REFERENCES 1\n#endif // has_feature\n\n#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)\n#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)\n#define JSON_HAS_RVALUE_REFERENCES 1\n#endif // GXX_EXPERIMENTAL\n\n#endif // __clang__ || __GNUC__\n\n#endif // not defined JSON_HAS_RVALUE_REFERENCES\n\n#ifndef JSON_HAS_RVALUE_REFERENCES\n#define JSON_HAS_RVALUE_REFERENCES 0\n#endif\n\n#ifdef __clang__\n#if __has_extension(attribute_deprecated_with_message)\n#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))\n#endif\n#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)\n#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))\n#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))\n#elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))\n#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))\n#endif // GNUC version\n#endif // __clang__ || __GNUC__\n\n#if !defined(JSONCPP_DEPRECATED)\n#define JSONCPP_DEPRECATED(message)\n#endif // if !defined(JSONCPP_DEPRECATED)\n\n#if __GNUC__ >= 6\n#define JSON_USE_INT64_DOUBLE_CONVERSION 1\n#endif\n\n#if !defined(JSON_IS_AMALGAMATION)\n\n#include \"version.h\"\n\n#if JSONCPP_USING_SECURE_MEMORY\n#include \"allocator.h\" //typedef Allocator\n#endif\n\n#endif // if !defined(JSON_IS_AMALGAMATION)\n\nnamespace Json\n{\ntypedef int Int;\ntypedef unsigned int UInt;\n#if defined(JSON_NO_INT64)\ntypedef int LargestInt;\ntypedef unsigned int LargestUInt;\n#undef JSON_HAS_INT64\n#else                 // if defined(JSON_NO_INT64)\n// For Microsoft Visual use specific types as long long is not supported\n#if defined(_MSC_VER) // Microsoft Visual Studio\ntypedef __int64 Int64;\ntypedef unsigned __int64 UInt64;\n#else                 // if defined(_MSC_VER) // Other platforms, use long long\ntypedef int64_t Int64;\ntypedef uint64_t UInt64;\n#endif                // if defined(_MSC_VER)\ntypedef Int64 LargestInt;\ntypedef UInt64 LargestUInt;\n#define JSON_HAS_INT64\n#endif // if defined(JSON_NO_INT64)\n#if JSONCPP_USING_SECURE_MEMORY\n#define JSONCPP_STRING std::basic_string<char, std::char_traits<char>, Json::SecureAllocator<char>>\n#define JSONCPP_OSTRINGSTREAM std::basic_ostringstream<char, std::char_traits<char>, Json::SecureAllocator<char>>\n#define JSONCPP_OSTREAM std::basic_ostream<char, std::char_traits<char>>\n#define JSONCPP_ISTRINGSTREAM std::basic_istringstream<char, std::char_traits<char>, Json::SecureAllocator<char>>\n#define JSONCPP_ISTREAM std::istream\n#else\n#define JSONCPP_STRING std::string\n#define JSONCPP_OSTRINGSTREAM std::ostringstream\n#define JSONCPP_OSTREAM std::ostream\n#define JSONCPP_ISTRINGSTREAM std::istringstream\n#define JSONCPP_ISTREAM std::istream\n#endif // if JSONCPP_USING_SECURE_MEMORY\n} // end namespace Json\n\n#endif // JSON_CONFIG_H_INCLUDED\n\n// //////////////////////////////////////////////////////////////////////\n// End of content of file: include/json/config.h\n// //////////////////////////////////////////////////////////////////////\n\n// //////////////////////////////////////////////////////////////////////\n// Beginning of content of file: include/json/forwards.h\n// //////////////////////////////////////////////////////////////////////\n\n// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors\n// Distributed under MIT license, or public domain if desired and\n// recognized in your jurisdiction.\n// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE\n\n#ifndef JSON_FORWARDS_H_INCLUDED\n#define JSON_FORWARDS_H_INCLUDED\n\n#if !defined(JSON_IS_AMALGAMATION)\n#include \"config.h\"\n#endif // if !defined(JSON_IS_AMALGAMATION)\n\nnamespace Json\n{\n\n// writer.h\nclass FastWriter;\nclass StyledWriter;\n\n// reader.h\nclass Reader;\n\n// features.h\nclass Features;\n\n// value.h\ntypedef unsigned int ArrayIndex;\nclass StaticString;\nclass Path;\nclass PathArgument;\nclass Value;\nclass ValueIteratorBase;\nclass ValueIterator;\nclass ValueConstIterator;\n\n} // namespace Json\n\n#endif // JSON_FORWARDS_H_INCLUDED\n\n// //////////////////////////////////////////////////////////////////////\n// End of content of file: include/json/forwards.h\n// //////////////////////////////////////////////////////////////////////\n\n#endif //ifndef JSON_FORWARD_AMALGATED_H_INCLUDED\n"
  },
  {
    "path": "thirdparty/jsoncpp/json/json.h",
    "content": "/// Json-cpp amalgated header (http://jsoncpp.sourceforge.net/).\n/// It is intended to be used with #include \"json/json.h\"\n\n// //////////////////////////////////////////////////////////////////////\n// Beginning of content of file: LICENSE\n// //////////////////////////////////////////////////////////////////////\n\n/*\nThe JsonCpp library's source code, including accompanying documentation, \ntests and demonstration applications, are licensed under the following\nconditions...\n\nBaptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all \njurisdictions which recognize such a disclaimer. In such jurisdictions, \nthis software is released into the Public Domain.\n\nIn jurisdictions which do not recognize Public Domain property (e.g. Germany as of\n2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and\nThe JsonCpp Authors, and is released under the terms of the MIT License (see below).\n\nIn jurisdictions which recognize Public Domain property, the user of this \nsoftware may choose to accept it either as 1) Public Domain, 2) under the \nconditions of the MIT License (see below), or 3) under the terms of dual \nPublic Domain/MIT License conditions described here, as they choose.\n\nThe MIT License is about as close to Public Domain as a license can get, and is\ndescribed in clear, concise terms at:\n\n   http://en.wikipedia.org/wiki/MIT_License\n   \nThe full text of the MIT License follows:\n\n========================================================================\nCopyright (c) 2007-2010 Baptiste Lepilleur and The JsonCpp Authors\n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this software and associated documentation\nfiles (the \"Software\"), to deal in the Software without\nrestriction, including without limitation the rights to use, copy,\nmodify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\nBE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\nACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n========================================================================\n(END LICENSE TEXT)\n\nThe MIT license is compatible with both the GPL and commercial\nsoftware, affording one all of the rights of Public Domain with the\nminor nuisance of being required to keep the above copyright notice\nand license text in the source code. Note also that by accepting the\nPublic Domain \"license\" you can re-license your copy using whatever\nlicense you like.\n\n*/\n\n// //////////////////////////////////////////////////////////////////////\n// End of content of file: LICENSE\n// //////////////////////////////////////////////////////////////////////\n\n#ifndef JSON_AMALGATED_H_INCLUDED\n#define JSON_AMALGATED_H_INCLUDED\n/// If defined, indicates that the source file is amalgated\n/// to prevent private header inclusion.\n#define JSON_IS_AMALGAMATION\n\n// //////////////////////////////////////////////////////////////////////\n// Beginning of content of file: include/json/version.h\n// //////////////////////////////////////////////////////////////////////\n\n// DO NOT EDIT. This file (and \"version\") is generated by CMake.\n// Run CMake configure step to update it.\n#ifndef JSON_VERSION_H_INCLUDED\n#define JSON_VERSION_H_INCLUDED\n\n#define JSONCPP_VERSION_STRING \"1.8.3\"\n#define JSONCPP_VERSION_MAJOR 1\n#define JSONCPP_VERSION_MINOR 8\n#define JSONCPP_VERSION_PATCH 3\n#define JSONCPP_VERSION_QUALIFIER\n#define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8))\n\n#ifdef JSONCPP_USING_SECURE_MEMORY\n#undef JSONCPP_USING_SECURE_MEMORY\n#endif\n#define JSONCPP_USING_SECURE_MEMORY 0\n// If non-zero, the library zeroes any memory that it has allocated before\n// it frees its memory.\n\n#endif // JSON_VERSION_H_INCLUDED\n\n// //////////////////////////////////////////////////////////////////////\n// End of content of file: include/json/version.h\n// //////////////////////////////////////////////////////////////////////\n\n// //////////////////////////////////////////////////////////////////////\n// Beginning of content of file: include/json/config.h\n// //////////////////////////////////////////////////////////////////////\n\n// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors\n// Distributed under MIT license, or public domain if desired and\n// recognized in your jurisdiction.\n// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE\n\n#ifndef JSON_CONFIG_H_INCLUDED\n#define JSON_CONFIG_H_INCLUDED\n#include <stddef.h>\n#include <string>   //typedef String\n#include <stdint.h> //typedef int64_t, uint64_t\n\n/// If defined, indicates that json library is embedded in CppTL library.\n//# define JSON_IN_CPPTL 1\n\n/// If defined, indicates that json may leverage CppTL library\n//#  define JSON_USE_CPPTL 1\n/// If defined, indicates that cpptl vector based map should be used instead of\n/// std::map\n/// as Value container.\n//#  define JSON_USE_CPPTL_SMALLMAP 1\n\n// If non-zero, the library uses exceptions to report bad input instead of C\n// assertion macros. The default is to use exceptions.\n#ifndef JSON_USE_EXCEPTION\n#define JSON_USE_EXCEPTION 1\n#endif\n\n/// If defined, indicates that the source file is amalgated\n/// to prevent private header inclusion.\n/// Remarks: it is automatically defined in the generated amalgated header.\n// #define JSON_IS_AMALGAMATION\n\n#ifdef JSON_IN_CPPTL\n#include <cpptl/config.h>\n#ifndef JSON_USE_CPPTL\n#define JSON_USE_CPPTL 1\n#endif\n#endif\n\n#ifdef JSON_IN_CPPTL\n#define JSON_API CPPTL_API\n#elif defined(JSON_DLL_BUILD)\n#if defined(_MSC_VER) || defined(__MINGW32__)\n#define JSON_API __declspec(dllexport)\n#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING\n#endif // if defined(_MSC_VER)\n#elif defined(JSON_DLL)\n#if defined(_MSC_VER) || defined(__MINGW32__)\n#define JSON_API __declspec(dllimport)\n#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING\n#endif // if defined(_MSC_VER)\n#endif // ifdef JSON_IN_CPPTL\n#if !defined(JSON_API)\n#define JSON_API\n#endif\n\n// If JSON_NO_INT64 is defined, then Json only support C++ \"int\" type for\n// integer\n// Storages, and 64 bits integer support is disabled.\n// #define JSON_NO_INT64 1\n\n#if defined(_MSC_VER) // MSVC\n#if _MSC_VER <= 1200  // MSVC 6\n                      // Microsoft Visual Studio 6 only support conversion from __int64 to double\n                      // (no conversion from unsigned __int64).\n#define JSON_USE_INT64_DOUBLE_CONVERSION 1\n// Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255'\n// characters in the debug information)\n// All projects I've ever seen with VS6 were using this globally (not bothering\n// with pragma push/pop).\n#pragma warning(disable : 4786)\n#endif // MSVC 6\n\n#if _MSC_VER >= 1500 // MSVC 2008\n                     /// Indicates that the following function is deprecated.\n#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))\n#endif\n\n#endif // defined(_MSC_VER)\n\n// In c++11 the override keyword allows you to explicity define that a function\n// is intended to override the base-class version.  This makes the code more\n// managable and fixes a set of common hard-to-find bugs.\n#if __cplusplus >= 201103L\n#define JSONCPP_OVERRIDE override\n#define JSONCPP_NOEXCEPT noexcept\n#elif defined(_MSC_VER) && _MSC_VER > 1600 && _MSC_VER < 1900\n#define JSONCPP_OVERRIDE override\n#define JSONCPP_NOEXCEPT throw()\n#elif defined(_MSC_VER) && _MSC_VER >= 1900\n#define JSONCPP_OVERRIDE override\n#define JSONCPP_NOEXCEPT noexcept\n#else\n#define JSONCPP_OVERRIDE\n#define JSONCPP_NOEXCEPT throw()\n#endif\n\n#ifndef JSON_HAS_RVALUE_REFERENCES\n\n#if defined(_MSC_VER) && _MSC_VER >= 1600 // MSVC >= 2010\n#define JSON_HAS_RVALUE_REFERENCES 1\n#endif // MSVC >= 2010\n\n#ifdef __clang__\n#if __has_feature(cxx_rvalue_references)\n#define JSON_HAS_RVALUE_REFERENCES 1\n#endif // has_feature\n\n#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)\n#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)\n#define JSON_HAS_RVALUE_REFERENCES 1\n#endif // GXX_EXPERIMENTAL\n\n#endif // __clang__ || __GNUC__\n\n#endif // not defined JSON_HAS_RVALUE_REFERENCES\n\n#ifndef JSON_HAS_RVALUE_REFERENCES\n#define JSON_HAS_RVALUE_REFERENCES 0\n#endif\n\n#ifdef __clang__\n#if __has_extension(attribute_deprecated_with_message)\n#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))\n#endif\n#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)\n#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))\n#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))\n#elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))\n#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))\n#endif // GNUC version\n#endif // __clang__ || __GNUC__\n\n#if !defined(JSONCPP_DEPRECATED)\n#define JSONCPP_DEPRECATED(message)\n#endif // if !defined(JSONCPP_DEPRECATED)\n\n#if __GNUC__ >= 6\n#define JSON_USE_INT64_DOUBLE_CONVERSION 1\n#endif\n\n#if !defined(JSON_IS_AMALGAMATION)\n\n#include \"version.h\"\n\n#if JSONCPP_USING_SECURE_MEMORY\n#include \"allocator.h\" //typedef Allocator\n#endif\n\n#endif // if !defined(JSON_IS_AMALGAMATION)\n\nnamespace Json\n{\ntypedef int Int;\ntypedef unsigned int UInt;\n#if defined(JSON_NO_INT64)\ntypedef int LargestInt;\ntypedef unsigned int LargestUInt;\n#undef JSON_HAS_INT64\n#else                 // if defined(JSON_NO_INT64)\n// For Microsoft Visual use specific types as long long is not supported\n#if defined(_MSC_VER) // Microsoft Visual Studio\ntypedef __int64 Int64;\ntypedef unsigned __int64 UInt64;\n#else                 // if defined(_MSC_VER) // Other platforms, use long long\ntypedef int64_t Int64;\ntypedef uint64_t UInt64;\n#endif                // if defined(_MSC_VER)\ntypedef Int64 LargestInt;\ntypedef UInt64 LargestUInt;\n#define JSON_HAS_INT64\n#endif // if defined(JSON_NO_INT64)\n#if JSONCPP_USING_SECURE_MEMORY\n#define JSONCPP_STRING std::basic_string<char, std::char_traits<char>, Json::SecureAllocator<char>>\n#define JSONCPP_OSTRINGSTREAM std::basic_ostringstream<char, std::char_traits<char>, Json::SecureAllocator<char>>\n#define JSONCPP_OSTREAM std::basic_ostream<char, std::char_traits<char>>\n#define JSONCPP_ISTRINGSTREAM std::basic_istringstream<char, std::char_traits<char>, Json::SecureAllocator<char>>\n#define JSONCPP_ISTREAM std::istream\n#else\n#define JSONCPP_STRING std::string\n#define JSONCPP_OSTRINGSTREAM std::ostringstream\n#define JSONCPP_OSTREAM std::ostream\n#define JSONCPP_ISTRINGSTREAM std::istringstream\n#define JSONCPP_ISTREAM std::istream\n#endif // if JSONCPP_USING_SECURE_MEMORY\n} // end namespace Json\n\n#endif // JSON_CONFIG_H_INCLUDED\n\n// //////////////////////////////////////////////////////////////////////\n// End of content of file: include/json/config.h\n// //////////////////////////////////////////////////////////////////////\n\n// //////////////////////////////////////////////////////////////////////\n// Beginning of content of file: include/json/forwards.h\n// //////////////////////////////////////////////////////////////////////\n\n// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors\n// Distributed under MIT license, or public domain if desired and\n// recognized in your jurisdiction.\n// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE\n\n#ifndef JSON_FORWARDS_H_INCLUDED\n#define JSON_FORWARDS_H_INCLUDED\n\n#if !defined(JSON_IS_AMALGAMATION)\n#include \"config.h\"\n#endif // if !defined(JSON_IS_AMALGAMATION)\n\nnamespace Json\n{\n\n// writer.h\nclass FastWriter;\nclass StyledWriter;\n\n// reader.h\nclass Reader;\n\n// features.h\nclass Features;\n\n// value.h\ntypedef unsigned int ArrayIndex;\nclass StaticString;\nclass Path;\nclass PathArgument;\nclass Value;\nclass ValueIteratorBase;\nclass ValueIterator;\nclass ValueConstIterator;\n\n} // namespace Json\n\n#endif // JSON_FORWARDS_H_INCLUDED\n\n// //////////////////////////////////////////////////////////////////////\n// End of content of file: include/json/forwards.h\n// //////////////////////////////////////////////////////////////////////\n\n// //////////////////////////////////////////////////////////////////////\n// Beginning of content of file: include/json/features.h\n// //////////////////////////////////////////////////////////////////////\n\n// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors\n// Distributed under MIT license, or public domain if desired and\n// recognized in your jurisdiction.\n// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE\n\n#ifndef CPPTL_JSON_FEATURES_H_INCLUDED\n#define CPPTL_JSON_FEATURES_H_INCLUDED\n\n#if !defined(JSON_IS_AMALGAMATION)\n#include \"forwards.h\"\n#endif // if !defined(JSON_IS_AMALGAMATION)\n\n#pragma pack(push, 8)\n\nnamespace Json\n{\n\n/** \\brief Configuration passed to reader and writer.\n * This configuration object can be used to force the Reader or Writer\n * to behave in a standard conforming way.\n */\nclass JSON_API Features\n{\npublic:\n  /** \\brief A configuration that allows all features and assumes all strings\n   * are UTF-8.\n   * - C & C++ comments are allowed\n   * - Root object can be any JSON value\n   * - Assumes Value strings are encoded in UTF-8\n   */\n  static Features all();\n\n  /** \\brief A configuration that is strictly compatible with the JSON\n   * specification.\n   * - Comments are forbidden.\n   * - Root object must be either an array or an object value.\n   * - Assumes Value strings are encoded in UTF-8\n   */\n  static Features strictMode();\n\n  /** \\brief Initialize the configuration like JsonConfig::allFeatures;\n   */\n  Features();\n\n  /// \\c true if comments are allowed. Default: \\c true.\n  bool allowComments_;\n\n  /// \\c true if root must be either an array or an object value. Default: \\c\n  /// false.\n  bool strictRoot_;\n\n  /// \\c true if dropped null placeholders are allowed. Default: \\c false.\n  bool allowDroppedNullPlaceholders_;\n\n  /// \\c true if numeric object key are allowed. Default: \\c false.\n  bool allowNumericKeys_;\n};\n\n} // namespace Json\n\n#pragma pack(pop)\n\n#endif // CPPTL_JSON_FEATURES_H_INCLUDED\n\n// //////////////////////////////////////////////////////////////////////\n// End of content of file: include/json/features.h\n// //////////////////////////////////////////////////////////////////////\n\n// //////////////////////////////////////////////////////////////////////\n// Beginning of content of file: include/json/value.h\n// //////////////////////////////////////////////////////////////////////\n\n// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors\n// Distributed under MIT license, or public domain if desired and\n// recognized in your jurisdiction.\n// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE\n\n#ifndef CPPTL_JSON_H_INCLUDED\n#define CPPTL_JSON_H_INCLUDED\n\n#if !defined(JSON_IS_AMALGAMATION)\n#include \"forwards.h\"\n#endif // if !defined(JSON_IS_AMALGAMATION)\n#include <string>\n#include <vector>\n#include <exception>\n\n#ifndef JSON_USE_CPPTL_SMALLMAP\n#include <map>\n#else\n#include <cpptl/smallmap.h>\n#endif\n#ifdef JSON_USE_CPPTL\n#include <cpptl/forwards.h>\n#endif\n\n//Conditional NORETURN attribute on the throw functions would:\n// a) suppress false positives from static code analysis\n// b) possibly improve optimization opportunities.\n#if !defined(JSONCPP_NORETURN)\n#if defined(_MSC_VER)\n#define JSONCPP_NORETURN __declspec(noreturn)\n#elif defined(__GNUC__)\n#define JSONCPP_NORETURN __attribute__((__noreturn__))\n#else\n#define JSONCPP_NORETURN\n#endif\n#endif\n\n// Disable warning C4251: <data member>: <type> needs to have dll-interface to\n// be used by...\n#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)\n#pragma warning(push)\n#pragma warning(disable : 4251)\n#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)\n\n#pragma pack(push, 8)\n\n/** \\brief JSON (JavaScript Object Notation).\n */\nnamespace Json\n{\n\n/** Base class for all exceptions we throw.\n *\n * We use nothing but these internally. Of course, STL can throw others.\n */\nclass JSON_API Exception : public std::exception\n{\npublic:\n  Exception(JSONCPP_STRING const &msg);\n  ~Exception() JSONCPP_NOEXCEPT JSONCPP_OVERRIDE;\n  char const *what() const JSONCPP_NOEXCEPT JSONCPP_OVERRIDE;\n\nprotected:\n  JSONCPP_STRING msg_;\n};\n\n/** Exceptions which the user cannot easily avoid.\n *\n * E.g. out-of-memory (when we use malloc), stack-overflow, malicious input\n *\n * \\remark derived from Json::Exception\n */\nclass JSON_API RuntimeError : public Exception\n{\npublic:\n  RuntimeError(JSONCPP_STRING const &msg);\n};\n\n/** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros.\n *\n * These are precondition-violations (user bugs) and internal errors (our bugs).\n *\n * \\remark derived from Json::Exception\n */\nclass JSON_API LogicError : public Exception\n{\npublic:\n  LogicError(JSONCPP_STRING const &msg);\n};\n\n/// used internally\nJSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const &msg);\n/// used internally\nJSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const &msg);\n\n/** \\brief Type of the value held by a Value object.\n */\nenum ValueType\n{\n  nullValue = 0, ///< 'null' value\n  intValue,      ///< signed integer value\n  uintValue,     ///< unsigned integer value\n  realValue,     ///< double value\n  stringValue,   ///< UTF-8 string value\n  booleanValue,  ///< bool value\n  arrayValue,    ///< array value (ordered list)\n  objectValue    ///< object value (collection of name/value pairs).\n};\n\nenum CommentPlacement\n{\n  commentBefore = 0,      ///< a comment placed on the line before a value\n  commentAfterOnSameLine, ///< a comment just after a value on the same line\n  commentAfter,           ///< a comment on the line after a value (only make sense for\n  /// root value)\n  numberOfCommentPlacement\n};\n\n//# ifdef JSON_USE_CPPTL\n//   typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;\n//   typedef CppTL::AnyEnumerator<const Value &> EnumValues;\n//# endif\n\n/** \\brief Lightweight wrapper to tag static string.\n *\n * Value constructor and objectValue member assignement takes advantage of the\n * StaticString and avoid the cost of string duplication when storing the\n * string or the member name.\n *\n * Example of usage:\n * \\code\n * Json::Value aValue( StaticString(\"some text\") );\n * Json::Value object;\n * static const StaticString code(\"code\");\n * object[code] = 1234;\n * \\endcode\n */\nclass JSON_API StaticString\n{\npublic:\n  explicit StaticString(const char *czstring) : c_str_(czstring) {}\n\n  operator const char *() const { return c_str_; }\n\n  const char *c_str() const { return c_str_; }\n\nprivate:\n  const char *c_str_;\n};\n\n/** \\brief Represents a <a HREF=\"http://www.json.org\">JSON</a> value.\n *\n * This class is a discriminated union wrapper that can represents a:\n * - signed integer [range: Value::minInt - Value::maxInt]\n * - unsigned integer (range: 0 - Value::maxUInt)\n * - double\n * - UTF-8 string\n * - boolean\n * - 'null'\n * - an ordered list of Value\n * - collection of name/value pairs (javascript object)\n *\n * The type of the held value is represented by a #ValueType and\n * can be obtained using type().\n *\n * Values of an #objectValue or #arrayValue can be accessed using operator[]()\n * methods.\n * Non-const methods will automatically create the a #nullValue element\n * if it does not exist.\n * The sequence of an #arrayValue will be automatically resized and initialized\n * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.\n *\n * The get() methods can be used to obtain default value in the case the\n * required element does not exist.\n *\n * It is possible to iterate over the list of a #objectValue values using\n * the getMemberNames() method.\n *\n * \\note #Value string-length fit in size_t, but keys must be < 2^30.\n * (The reason is an implementation detail.) A #CharReader will raise an\n * exception if a bound is exceeded to avoid security holes in your app,\n * but the Value API does *not* check bounds. That is the responsibility\n * of the caller.\n */\nclass JSON_API Value\n{\n  friend class ValueIteratorBase;\n\npublic:\n  typedef std::vector<JSONCPP_STRING> Members;\n  typedef ValueIterator iterator;\n  typedef ValueConstIterator const_iterator;\n  typedef Json::UInt UInt;\n  typedef Json::Int Int;\n#if defined(JSON_HAS_INT64)\n  typedef Json::UInt64 UInt64;\n  typedef Json::Int64 Int64;\n#endif // defined(JSON_HAS_INT64)\n  typedef Json::LargestInt LargestInt;\n  typedef Json::LargestUInt LargestUInt;\n  typedef Json::ArrayIndex ArrayIndex;\n\n  static const Value &null;            ///< We regret this reference to a global instance; prefer the simpler Value().\n  static const Value &nullRef;         ///< just a kludge for binary-compatibility; same as null\n  static Value const &nullSingleton(); ///< Prefer this to null or nullRef.\n\n  /// Minimum signed integer value that can be stored in a Json::Value.\n  static const LargestInt minLargestInt;\n  /// Maximum signed integer value that can be stored in a Json::Value.\n  static const LargestInt maxLargestInt;\n  /// Maximum unsigned integer value that can be stored in a Json::Value.\n  static const LargestUInt maxLargestUInt;\n\n  /// Minimum signed int value that can be stored in a Json::Value.\n  static const Int minInt;\n  /// Maximum signed int value that can be stored in a Json::Value.\n  static const Int maxInt;\n  /// Maximum unsigned int value that can be stored in a Json::Value.\n  static const UInt maxUInt;\n\n#if defined(JSON_HAS_INT64)\n  /// Minimum signed 64 bits int value that can be stored in a Json::Value.\n  static const Int64 minInt64;\n  /// Maximum signed 64 bits int value that can be stored in a Json::Value.\n  static const Int64 maxInt64;\n  /// Maximum unsigned 64 bits int value that can be stored in a Json::Value.\n  static const UInt64 maxUInt64;\n#endif // defined(JSON_HAS_INT64)\n\nprivate:\n#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION\n  class CZString\n  {\n  public:\n    enum DuplicationPolicy\n    {\n      noDuplication = 0,\n      duplicate,\n      duplicateOnCopy\n    };\n    CZString(ArrayIndex index);\n    CZString(char const *str, unsigned length, DuplicationPolicy allocate);\n    CZString(CZString const &other);\n#if JSON_HAS_RVALUE_REFERENCES\n    CZString(CZString &&other);\n#endif\n    ~CZString();\n    CZString &operator=(const CZString &other);\n\n#if JSON_HAS_RVALUE_REFERENCES\n    CZString &operator=(CZString &&other);\n#endif\n\n    bool operator<(CZString const &other) const;\n    bool operator==(CZString const &other) const;\n    ArrayIndex index() const;\n    //const char* c_str() const; ///< \\deprecated\n    char const *data() const;\n    unsigned length() const;\n    bool isStaticString() const;\n\n  private:\n    void swap(CZString &other);\n\n    struct StringStorage\n    {\n      unsigned policy_ : 2;\n      unsigned length_ : 30; // 1GB max\n    };\n\n    char const *cstr_; // actually, a prefixed string, unless policy is noDup\n    union {\n      ArrayIndex index_;\n      StringStorage storage_;\n    };\n  };\n\npublic:\n#ifndef JSON_USE_CPPTL_SMALLMAP\n  typedef std::map<CZString, Value> ObjectValues;\n#else\n  typedef CppTL::SmallMap<CZString, Value> ObjectValues;\n#endif // ifndef JSON_USE_CPPTL_SMALLMAP\n#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION\n\npublic:\n  /** \\brief Create a default Value of the given type.\n\n    This is a very useful constructor.\n    To create an empty array, pass arrayValue.\n    To create an empty object, pass objectValue.\n    Another Value can then be set to this one by assignment.\nThis is useful since clear() and resize() will not alter types.\n\n    Examples:\n\\code\nJson::Value null_value; // null\nJson::Value arr_value(Json::arrayValue); // []\nJson::Value obj_value(Json::objectValue); // {}\n\\endcode\n  */\n  Value(ValueType type = nullValue);\n  Value(Int value);\n  Value(UInt value);\n#if defined(JSON_HAS_INT64)\n  Value(Int64 value);\n  Value(UInt64 value);\n#endif // if defined(JSON_HAS_INT64)\n  Value(double value);\n  Value(const char *value);                  ///< Copy til first 0. (NULL causes to seg-fault.)\n  Value(const char *begin, const char *end); ///< Copy all, incl zeroes.\n  /** \\brief Constructs a value from a static string.\n\n   * Like other value string constructor but do not duplicate the string for\n   * internal storage. The given string must remain alive after the call to this\n   * constructor.\n   * \\note This works only for null-terminated strings. (We cannot change the\n   *   size of this class, so we have nowhere to store the length,\n   *   which might be computed later for various operations.)\n   *\n   * Example of usage:\n   * \\code\n   * static StaticString foo(\"some text\");\n   * Json::Value aValue(foo);\n   * \\endcode\n   */\n  Value(const StaticString &value);\n  Value(const JSONCPP_STRING &value); ///< Copy data() til size(). Embedded zeroes too.\n#ifdef JSON_USE_CPPTL\n  Value(const CppTL::ConstString &value);\n#endif\n  Value(bool value);\n  /// Deep copy.\n  Value(const Value &other);\n#if JSON_HAS_RVALUE_REFERENCES\n  /// Move constructor\n  Value(Value &&other);\n#endif\n  ~Value();\n\n  /// Deep copy, then swap(other).\n  /// \\note Over-write existing comments. To preserve comments, use #swapPayload().\n  Value &operator=(Value other);\n\n  /// Swap everything.\n  void swap(Value &other);\n  /// Swap values but leave comments and source offsets in place.\n  void swapPayload(Value &other);\n\n  /// copy everything.\n  void copy(const Value &other);\n  /// copy values but leave comments and source offsets in place.\n  void copyPayload(const Value &other);\n\n  ValueType type() const;\n\n  /// Compare payload only, not comments etc.\n  bool operator<(const Value &other) const;\n  bool operator<=(const Value &other) const;\n  bool operator>=(const Value &other) const;\n  bool operator>(const Value &other) const;\n  bool operator==(const Value &other) const;\n  bool operator!=(const Value &other) const;\n  int compare(const Value &other) const;\n\n  const char *asCString() const; ///< Embedded zeroes could cause you trouble!\n#if JSONCPP_USING_SECURE_MEMORY\n  unsigned getCStringLength() const; //Allows you to understand the length of the CString\n#endif\n  JSONCPP_STRING asString() const; ///< Embedded zeroes are possible.\n  /** Get raw char* of string-value.\n   *  \\return false if !string. (Seg-fault if str or end are NULL.)\n   */\n  bool getString(\n      char const **begin, char const **end) const;\n#ifdef JSON_USE_CPPTL\n  CppTL::ConstString asConstString() const;\n#endif\n  Int asInt() const;\n  UInt asUInt() const;\n#if defined(JSON_HAS_INT64)\n  Int64 asInt64() const;\n  UInt64 asUInt64() const;\n#endif // if defined(JSON_HAS_INT64)\n  LargestInt asLargestInt() const;\n  LargestUInt asLargestUInt() const;\n  float asFloat() const;\n  double asDouble() const;\n  bool asBool() const;\n\n  bool isNull() const;\n  bool isBool() const;\n  bool isInt() const;\n  bool isInt64() const;\n  bool isUInt() const;\n  bool isUInt64() const;\n  bool isIntegral() const;\n  bool isDouble() const;\n  bool isNumeric() const;\n  bool isString() const;\n  bool isArray() const;\n  bool isObject() const;\n\n  bool isConvertibleTo(ValueType other) const;\n\n  /// Number of values in array or object\n  ArrayIndex size() const;\n\n  /// \\brief Return true if empty array, empty object, or null;\n  /// otherwise, false.\n  bool empty() const;\n\n  /// Return isNull()\n  bool operator!() const;\n\n  /// Remove all object members and array elements.\n  /// \\pre type() is arrayValue, objectValue, or nullValue\n  /// \\post type() is unchanged\n  void clear();\n\n  /// Resize the array to size elements.\n  /// New elements are initialized to null.\n  /// May only be called on nullValue or arrayValue.\n  /// \\pre type() is arrayValue or nullValue\n  /// \\post type() is arrayValue\n  void resize(ArrayIndex size);\n\n  /// Access an array element (zero based index ).\n  /// If the array contains less than index element, then null value are\n  /// inserted\n  /// in the array so that its size is index+1.\n  /// (You may need to say 'value[0u]' to get your compiler to distinguish\n  ///  this from the operator[] which takes a string.)\n  Value &operator[](ArrayIndex index);\n\n  /// Access an array element (zero based index ).\n  /// If the array contains less than index element, then null value are\n  /// inserted\n  /// in the array so that its size is index+1.\n  /// (You may need to say 'value[0u]' to get your compiler to distinguish\n  ///  this from the operator[] which takes a string.)\n  Value &operator[](int index);\n\n  /// Access an array element (zero based index )\n  /// (You may need to say 'value[0u]' to get your compiler to distinguish\n  ///  this from the operator[] which takes a string.)\n  const Value &operator[](ArrayIndex index) const;\n\n  /// Access an array element (zero based index )\n  /// (You may need to say 'value[0u]' to get your compiler to distinguish\n  ///  this from the operator[] which takes a string.)\n  const Value &operator[](int index) const;\n\n  /// If the array contains at least index+1 elements, returns the element\n  /// value,\n  /// otherwise returns defaultValue.\n  Value get(ArrayIndex index, const Value &defaultValue) const;\n  /// Return true if index < size().\n  bool isValidIndex(ArrayIndex index) const;\n  /// \\brief Append value to array at the end.\n  ///\n  /// Equivalent to jsonvalue[jsonvalue.size()] = value;\n  Value &append(const Value &value);\n\n#if JSON_HAS_RVALUE_REFERENCES\n  Value &append(Value &&value);\n#endif\n\n  /// Access an object value by name, create a null member if it does not exist.\n  /// \\note Because of our implementation, keys are limited to 2^30 -1 chars.\n  ///  Exceeding that will cause an exception.\n  Value &operator[](const char *key);\n  /// Access an object value by name, returns null if there is no member with\n  /// that name.\n  const Value &operator[](const char *key) const;\n  /// Access an object value by name, create a null member if it does not exist.\n  /// \\param key may contain embedded nulls.\n  Value &operator[](const JSONCPP_STRING &key);\n  /// Access an object value by name, returns null if there is no member with\n  /// that name.\n  /// \\param key may contain embedded nulls.\n  const Value &operator[](const JSONCPP_STRING &key) const;\n  /** \\brief Access an object value by name, create a null member if it does not\n   exist.\n\n   * If the object has no entry for that name, then the member name used to store\n   * the new entry is not duplicated.\n   * Example of use:\n   * \\code\n   * Json::Value object;\n   * static const StaticString code(\"code\");\n   * object[code] = 1234;\n   * \\endcode\n   */\n  Value &operator[](const StaticString &key);\n#ifdef JSON_USE_CPPTL\n  /// Access an object value by name, create a null member if it does not exist.\n  Value &operator[](const CppTL::ConstString &key);\n  /// Access an object value by name, returns null if there is no member with\n  /// that name.\n  const Value &operator[](const CppTL::ConstString &key) const;\n#endif\n  /// Return the member named key if it exist, defaultValue otherwise.\n  /// \\note deep copy\n  Value get(const char *key, const Value &defaultValue) const;\n  /// Return the member named key if it exist, defaultValue otherwise.\n  /// \\note deep copy\n  /// \\note key may contain embedded nulls.\n  Value get(const char *begin, const char *end, const Value &defaultValue) const;\n  /// Return the member named key if it exist, defaultValue otherwise.\n  /// \\note deep copy\n  /// \\param key may contain embedded nulls.\n  Value get(const JSONCPP_STRING &key, const Value &defaultValue) const;\n#ifdef JSON_USE_CPPTL\n  /// Return the member named key if it exist, defaultValue otherwise.\n  /// \\note deep copy\n  Value get(const CppTL::ConstString &key, const Value &defaultValue) const;\n#endif\n  /// Most general and efficient version of isMember()const, get()const,\n  /// and operator[]const\n  /// \\note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30\n  Value const *find(char const *begin, char const *end) const;\n  /// Most general and efficient version of object-mutators.\n  /// \\note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30\n  /// \\return non-zero, but JSON_ASSERT if this is neither object nor nullValue.\n  Value const *demand(char const *begin, char const *end);\n  /// \\brief Remove and return the named member.\n  ///\n  /// Do nothing if it did not exist.\n  /// \\return the removed Value, or null.\n  /// \\pre type() is objectValue or nullValue\n  /// \\post type() is unchanged\n  /// \\deprecated\n  JSONCPP_DEPRECATED(\"\")\n  Value removeMember(const char *key);\n  /// Same as removeMember(const char*)\n  /// \\param key may contain embedded nulls.\n  /// \\deprecated\n  JSONCPP_DEPRECATED(\"\")\n  Value removeMember(const JSONCPP_STRING &key);\n  /// Same as removeMember(const char* begin, const char* end, Value* removed),\n  /// but 'key' is null-terminated.\n  bool removeMember(const char *key, Value *removed);\n  /** \\brief Remove the named map member.\n\n      Update 'removed' iff removed.\n      \\param key may contain embedded nulls.\n      \\return true iff removed (no exceptions)\n  */\n  bool removeMember(JSONCPP_STRING const &key, Value *removed);\n  /// Same as removeMember(JSONCPP_STRING const& key, Value* removed)\n  bool removeMember(const char *begin, const char *end, Value *removed);\n  /** \\brief Remove the indexed array element.\n\n      O(n) expensive operations.\n      Update 'removed' iff removed.\n      \\return true iff removed (no exceptions)\n  */\n  bool removeIndex(ArrayIndex i, Value *removed);\n\n  /// Return true if the object has a member named key.\n  /// \\note 'key' must be null-terminated.\n  bool isMember(const char *key) const;\n  /// Return true if the object has a member named key.\n  /// \\param key may contain embedded nulls.\n  bool isMember(const JSONCPP_STRING &key) const;\n  /// Same as isMember(JSONCPP_STRING const& key)const\n  bool isMember(const char *begin, const char *end) const;\n#ifdef JSON_USE_CPPTL\n  /// Return true if the object has a member named key.\n  bool isMember(const CppTL::ConstString &key) const;\n#endif\n\n  /// \\brief Return a list of the member names.\n  ///\n  /// If null, return an empty list.\n  /// \\pre type() is objectValue or nullValue\n  /// \\post if type() was nullValue, it remains nullValue\n  Members getMemberNames() const;\n\n  //# ifdef JSON_USE_CPPTL\n  //      EnumMemberNames enumMemberNames() const;\n  //      EnumValues enumValues() const;\n  //# endif\n\n  /// \\deprecated Always pass len.\n  JSONCPP_DEPRECATED(\"Use setComment(JSONCPP_STRING const&) instead.\")\n  void setComment(const char *comment, CommentPlacement placement);\n  /// Comments must be //... or /* ... */\n  void setComment(const char *comment, size_t len, CommentPlacement placement);\n  /// Comments must be //... or /* ... */\n  void setComment(const JSONCPP_STRING &comment, CommentPlacement placement);\n  bool hasComment(CommentPlacement placement) const;\n  /// Include delimiters and embedded newlines.\n  JSONCPP_STRING getComment(CommentPlacement placement) const;\n\n  JSONCPP_STRING toStyledString() const;\n\n  const_iterator begin() const;\n  const_iterator end() const;\n\n  iterator begin();\n  iterator end();\n\n  // Accessors for the [start, limit) range of bytes within the JSON text from\n  // which this value was parsed, if any.\n  void setOffsetStart(ptrdiff_t start);\n  void setOffsetLimit(ptrdiff_t limit);\n  ptrdiff_t getOffsetStart() const;\n  ptrdiff_t getOffsetLimit() const;\n\nprivate:\n  void initBasic(ValueType type, bool allocated = false);\n\n  Value &resolveReference(const char *key);\n  Value &resolveReference(const char *key, const char *end);\n\n  struct CommentInfo\n  {\n    CommentInfo();\n    ~CommentInfo();\n\n    void setComment(const char *text, size_t len);\n\n    char *comment_;\n  };\n\n  // struct MemberNamesTransform\n  //{\n  //   typedef const char *result_type;\n  //   const char *operator()( const CZString &name ) const\n  //   {\n  //      return name.c_str();\n  //   }\n  //};\n\n  union ValueHolder {\n    LargestInt int_;\n    LargestUInt uint_;\n    double real_;\n    bool bool_;\n    char *string_; // actually ptr to unsigned, followed by str, unless !allocated_\n    ObjectValues *map_;\n  } value_;\n  ValueType type_ : 8;\n  unsigned int allocated_ : 1; // Notes: if declared as bool, bitfield is useless.\n                               // If not allocated_, string_ must be null-terminated.\n  CommentInfo *comments_;\n\n  // [start, limit) byte offsets in the source JSON text from which this Value\n  // was extracted.\n  ptrdiff_t start_;\n  ptrdiff_t limit_;\n};\n\n/** \\brief Experimental and untested: represents an element of the \"path\" to\n * access a node.\n */\nclass JSON_API PathArgument\n{\npublic:\n  friend class Path;\n\n  PathArgument();\n  PathArgument(ArrayIndex index);\n  PathArgument(const char *key);\n  PathArgument(const JSONCPP_STRING &key);\n\nprivate:\n  enum Kind\n  {\n    kindNone = 0,\n    kindIndex,\n    kindKey\n  };\n  JSONCPP_STRING key_;\n  ArrayIndex index_;\n  Kind kind_;\n};\n\n/** \\brief Experimental and untested: represents a \"path\" to access a node.\n *\n * Syntax:\n * - \".\" => root node\n * - \".[n]\" => elements at index 'n' of root node (an array value)\n * - \".name\" => member named 'name' of root node (an object value)\n * - \".name1.name2.name3\"\n * - \".[0][1][2].name1[3]\"\n * - \".%\" => member name is provided as parameter\n * - \".[%]\" => index is provied as parameter\n */\nclass JSON_API Path\n{\npublic:\n  Path(const JSONCPP_STRING &path,\n       const PathArgument &a1 = PathArgument(),\n       const PathArgument &a2 = PathArgument(),\n       const PathArgument &a3 = PathArgument(),\n       const PathArgument &a4 = PathArgument(),\n       const PathArgument &a5 = PathArgument());\n\n  const Value &resolve(const Value &root) const;\n  Value resolve(const Value &root, const Value &defaultValue) const;\n  /// Creates the \"path\" to access the specified node and returns a reference on\n  /// the node.\n  Value &make(Value &root) const;\n\nprivate:\n  typedef std::vector<const PathArgument *> InArgs;\n  typedef std::vector<PathArgument> Args;\n\n  void makePath(const JSONCPP_STRING &path, const InArgs &in);\n  void addPathInArg(const JSONCPP_STRING &path,\n                    const InArgs &in,\n                    InArgs::const_iterator &itInArg,\n                    PathArgument::Kind kind);\n  void invalidPath(const JSONCPP_STRING &path, int location);\n\n  Args args_;\n};\n\n/** \\brief base class for Value iterators.\n *\n */\nclass JSON_API ValueIteratorBase\n{\npublic:\n  typedef std::bidirectional_iterator_tag iterator_category;\n  typedef unsigned int size_t;\n  typedef int difference_type;\n  typedef ValueIteratorBase SelfType;\n\n  bool operator==(const SelfType &other) const { return isEqual(other); }\n\n  bool operator!=(const SelfType &other) const { return !isEqual(other); }\n\n  difference_type operator-(const SelfType &other) const\n  {\n    return other.computeDistance(*this);\n  }\n\n  /// Return either the index or the member name of the referenced value as a\n  /// Value.\n  Value key() const;\n\n  /// Return the index of the referenced Value, or -1 if it is not an arrayValue.\n  UInt index() const;\n\n  /// Return the member name of the referenced Value, or \"\" if it is not an\n  /// objectValue.\n  /// \\note Avoid `c_str()` on result, as embedded zeroes are possible.\n  JSONCPP_STRING name() const;\n\n  /// Return the member name of the referenced Value. \"\" if it is not an\n  /// objectValue.\n  /// \\deprecated This cannot be used for UTF-8 strings, since there can be embedded nulls.\n  JSONCPP_DEPRECATED(\"Use `key = name();` instead.\")\n  char const *memberName() const;\n  /// Return the member name of the referenced Value, or NULL if it is not an\n  /// objectValue.\n  /// \\note Better version than memberName(). Allows embedded nulls.\n  char const *memberName(char const **end) const;\n\nprotected:\n  Value &deref() const;\n\n  void increment();\n\n  void decrement();\n\n  difference_type computeDistance(const SelfType &other) const;\n\n  bool isEqual(const SelfType &other) const;\n\n  void copy(const SelfType &other);\n\nprivate:\n  Value::ObjectValues::iterator current_;\n  // Indicates that iterator is for a null value.\n  bool isNull_;\n\npublic:\n  // For some reason, BORLAND needs these at the end, rather\n  // than earlier. No idea why.\n  ValueIteratorBase();\n  explicit ValueIteratorBase(const Value::ObjectValues::iterator &current);\n};\n\n/** \\brief const iterator for object and array value.\n *\n */\nclass JSON_API ValueConstIterator : public ValueIteratorBase\n{\n  friend class Value;\n\npublic:\n  typedef const Value value_type;\n  //typedef unsigned int size_t;\n  //typedef int difference_type;\n  typedef const Value &reference;\n  typedef const Value *pointer;\n  typedef ValueConstIterator SelfType;\n\n  ValueConstIterator();\n  ValueConstIterator(ValueIterator const &other);\n\nprivate:\n  /*! \\internal Use by Value to create an iterator.\n */\n  explicit ValueConstIterator(const Value::ObjectValues::iterator &current);\n\npublic:\n  SelfType &operator=(const ValueIteratorBase &other);\n\n  SelfType operator++(int)\n  {\n    SelfType temp(*this);\n    ++*this;\n    return temp;\n  }\n\n  SelfType operator--(int)\n  {\n    SelfType temp(*this);\n    --*this;\n    return temp;\n  }\n\n  SelfType &operator--()\n  {\n    decrement();\n    return *this;\n  }\n\n  SelfType &operator++()\n  {\n    increment();\n    return *this;\n  }\n\n  reference operator*() const { return deref(); }\n\n  pointer operator->() const { return &deref(); }\n};\n\n/** \\brief Iterator for object and array value.\n */\nclass JSON_API ValueIterator : public ValueIteratorBase\n{\n  friend class Value;\n\npublic:\n  typedef Value value_type;\n  typedef unsigned int size_t;\n  typedef int difference_type;\n  typedef Value &reference;\n  typedef Value *pointer;\n  typedef ValueIterator SelfType;\n\n  ValueIterator();\n  explicit ValueIterator(const ValueConstIterator &other);\n  ValueIterator(const ValueIterator &other);\n\nprivate:\n  /*! \\internal Use by Value to create an iterator.\n */\n  explicit ValueIterator(const Value::ObjectValues::iterator &current);\n\npublic:\n  SelfType &operator=(const SelfType &other);\n\n  SelfType operator++(int)\n  {\n    SelfType temp(*this);\n    ++*this;\n    return temp;\n  }\n\n  SelfType operator--(int)\n  {\n    SelfType temp(*this);\n    --*this;\n    return temp;\n  }\n\n  SelfType &operator--()\n  {\n    decrement();\n    return *this;\n  }\n\n  SelfType &operator++()\n  {\n    increment();\n    return *this;\n  }\n\n  reference operator*() const { return deref(); }\n\n  pointer operator->() const { return &deref(); }\n};\n\n} // namespace Json\n\nnamespace std\n{\n/// Specialize std::swap() for Json::Value.\ntemplate <>\ninline void swap(Json::Value &a, Json::Value &b) { a.swap(b); }\n} // namespace std\n\n#pragma pack(pop)\n\n#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)\n#pragma warning(pop)\n#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)\n\n#endif // CPPTL_JSON_H_INCLUDED\n\n// //////////////////////////////////////////////////////////////////////\n// End of content of file: include/json/value.h\n// //////////////////////////////////////////////////////////////////////\n\n// //////////////////////////////////////////////////////////////////////\n// Beginning of content of file: include/json/reader.h\n// //////////////////////////////////////////////////////////////////////\n\n// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors\n// Distributed under MIT license, or public domain if desired and\n// recognized in your jurisdiction.\n// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE\n\n#ifndef CPPTL_JSON_READER_H_INCLUDED\n#define CPPTL_JSON_READER_H_INCLUDED\n\n#if !defined(JSON_IS_AMALGAMATION)\n#include \"features.h\"\n#include \"value.h\"\n#endif // if !defined(JSON_IS_AMALGAMATION)\n#include <deque>\n#include <iosfwd>\n#include <stack>\n#include <string>\n#include <istream>\n\n// Disable warning C4251: <data member>: <type> needs to have dll-interface to\n// be used by...\n#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)\n#pragma warning(push)\n#pragma warning(disable : 4251)\n#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)\n\n#pragma pack(push, 8)\n\nnamespace Json\n{\n\n/** \\brief Unserialize a <a HREF=\"http://www.json.org\">JSON</a> document into a\n *Value.\n *\n * \\deprecated Use CharReader and CharReaderBuilder.\n */\nclass JSONCPP_DEPRECATED(\"Use CharReader and CharReaderBuilder instead\") JSON_API Reader\n{\npublic:\n  typedef char Char;\n  typedef const Char *Location;\n\n  /** \\brief An error tagged with where in the JSON text it was encountered.\n   *\n   * The offsets give the [start, limit) range of bytes within the text. Note\n   * that this is bytes, not codepoints.\n   *\n   */\n  struct StructuredError\n  {\n    ptrdiff_t offset_start;\n    ptrdiff_t offset_limit;\n    JSONCPP_STRING message;\n  };\n\n  /** \\brief Constructs a Reader allowing all features\n   * for parsing.\n   */\n  Reader();\n\n  /** \\brief Constructs a Reader allowing the specified feature set\n   * for parsing.\n   */\n  Reader(const Features &features);\n\n  /** \\brief Read a Value from a <a HREF=\"http://www.json.org\">JSON</a>\n   * document.\n   * \\param document UTF-8 encoded string containing the document to read.\n   * \\param root [out] Contains the root value of the document if it was\n   *             successfully parsed.\n   * \\param collectComments \\c true to collect comment and allow writing them\n   * back during\n   *                        serialization, \\c false to discard comments.\n   *                        This parameter is ignored if\n   * Features::allowComments_\n   *                        is \\c false.\n   * \\return \\c true if the document was successfully parsed, \\c false if an\n   * error occurred.\n   */\n  bool\n  parse(const std::string &document, Value &root, bool collectComments = true);\n\n  /** \\brief Read a Value from a <a HREF=\"http://www.json.org\">JSON</a>\n   document.\n   * \\param beginDoc Pointer on the beginning of the UTF-8 encoded string of the\n   document to read.\n   * \\param endDoc Pointer on the end of the UTF-8 encoded string of the\n   document to read.\n   *               Must be >= beginDoc.\n   * \\param root [out] Contains the root value of the document if it was\n   *             successfully parsed.\n   * \\param collectComments \\c true to collect comment and allow writing them\n   back during\n   *                        serialization, \\c false to discard comments.\n   *                        This parameter is ignored if\n   Features::allowComments_\n   *                        is \\c false.\n   * \\return \\c true if the document was successfully parsed, \\c false if an\n   error occurred.\n   */\n  bool parse(const char *beginDoc,\n             const char *endDoc,\n             Value &root,\n             bool collectComments = true);\n\n  /// \\brief Parse from input stream.\n  /// \\see Json::operator>>(std::istream&, Json::Value&).\n  bool parse(JSONCPP_ISTREAM &is, Value &root, bool collectComments = true);\n\n  /** \\brief Returns a user friendly string that list errors in the parsed\n   * document.\n   * \\return Formatted error message with the list of errors with their location\n   * in\n   *         the parsed document. An empty string is returned if no error\n   * occurred\n   *         during parsing.\n   * \\deprecated Use getFormattedErrorMessages() instead (typo fix).\n   */\n  JSONCPP_DEPRECATED(\"Use getFormattedErrorMessages() instead.\")\n  JSONCPP_STRING getFormatedErrorMessages() const;\n\n  /** \\brief Returns a user friendly string that list errors in the parsed\n   * document.\n   * \\return Formatted error message with the list of errors with their location\n   * in\n   *         the parsed document. An empty string is returned if no error\n   * occurred\n   *         during parsing.\n   */\n  JSONCPP_STRING getFormattedErrorMessages() const;\n\n  /** \\brief Returns a vector of structured erros encounted while parsing.\n   * \\return A (possibly empty) vector of StructuredError objects. Currently\n   *         only one error can be returned, but the caller should tolerate\n   * multiple\n   *         errors.  This can occur if the parser recovers from a non-fatal\n   *         parse error and then encounters additional errors.\n   */\n  std::vector<StructuredError> getStructuredErrors() const;\n\n  /** \\brief Add a semantic error message.\n   * \\param value JSON Value location associated with the error\n   * \\param message The error message.\n   * \\return \\c true if the error was successfully added, \\c false if the\n   * Value offset exceeds the document size.\n   */\n  bool pushError(const Value &value, const JSONCPP_STRING &message);\n\n  /** \\brief Add a semantic error message with extra context.\n   * \\param value JSON Value location associated with the error\n   * \\param message The error message.\n   * \\param extra Additional JSON Value location to contextualize the error\n   * \\return \\c true if the error was successfully added, \\c false if either\n   * Value offset exceeds the document size.\n   */\n  bool pushError(const Value &value, const JSONCPP_STRING &message, const Value &extra);\n\n  /** \\brief Return whether there are any errors.\n   * \\return \\c true if there are no errors to report \\c false if\n   * errors have occurred.\n   */\n  bool good() const;\n\nprivate:\n  enum TokenType\n  {\n    tokenEndOfStream = 0,\n    tokenObjectBegin,\n    tokenObjectEnd,\n    tokenArrayBegin,\n    tokenArrayEnd,\n    tokenString,\n    tokenNumber,\n    tokenTrue,\n    tokenFalse,\n    tokenNull,\n    tokenArraySeparator,\n    tokenMemberSeparator,\n    tokenComment,\n    tokenError\n  };\n\n  class Token\n  {\n  public:\n    TokenType type_;\n    Location start_;\n    Location end_;\n  };\n\n  class ErrorInfo\n  {\n  public:\n    Token token_;\n    JSONCPP_STRING message_;\n    Location extra_;\n  };\n\n  typedef std::deque<ErrorInfo> Errors;\n\n  bool readToken(Token &token);\n  void skipSpaces();\n  bool match(Location pattern, int patternLength);\n  bool readComment();\n  bool readCStyleComment();\n  bool readCppStyleComment();\n  bool readString();\n  void readNumber();\n  bool readValue();\n  bool readObject(Token &token);\n  bool readArray(Token &token);\n  bool decodeNumber(Token &token);\n  bool decodeNumber(Token &token, Value &decoded);\n  bool decodeString(Token &token);\n  bool decodeString(Token &token, JSONCPP_STRING &decoded);\n  bool decodeDouble(Token &token);\n  bool decodeDouble(Token &token, Value &decoded);\n  bool decodeUnicodeCodePoint(Token &token,\n                              Location &current,\n                              Location end,\n                              unsigned int &unicode);\n  bool decodeUnicodeEscapeSequence(Token &token,\n                                   Location &current,\n                                   Location end,\n                                   unsigned int &unicode);\n  bool addError(const JSONCPP_STRING &message, Token &token, Location extra = 0);\n  bool recoverFromError(TokenType skipUntilToken);\n  bool addErrorAndRecover(const JSONCPP_STRING &message,\n                          Token &token,\n                          TokenType skipUntilToken);\n  void skipUntilSpace();\n  Value &currentValue();\n  Char getNextChar();\n  void\n  getLocationLineAndColumn(Location location, int &line, int &column) const;\n  JSONCPP_STRING getLocationLineAndColumn(Location location) const;\n  void addComment(Location begin, Location end, CommentPlacement placement);\n  void skipCommentTokens(Token &token);\n\n  static bool containsNewLine(Location begin, Location end);\n  static JSONCPP_STRING normalizeEOL(Location begin, Location end);\n\n  typedef std::stack<Value *> Nodes;\n  Nodes nodes_;\n  Errors errors_;\n  JSONCPP_STRING document_;\n  Location begin_;\n  Location end_;\n  Location current_;\n  Location lastValueEnd_;\n  Value *lastValue_;\n  JSONCPP_STRING commentsBefore_;\n  Features features_;\n  bool collectComments_;\n}; // Reader\n\n/** Interface for reading JSON from a char array.\n */\nclass JSON_API CharReader\n{\npublic:\n  virtual ~CharReader() {}\n  /** \\brief Read a Value from a <a HREF=\"http://www.json.org\">JSON</a>\n   document.\n   * The document must be a UTF-8 encoded string containing the document to read.\n   *\n   * \\param beginDoc Pointer on the beginning of the UTF-8 encoded string of the\n   document to read.\n   * \\param endDoc Pointer on the end of the UTF-8 encoded string of the\n   document to read.\n   *        Must be >= beginDoc.\n   * \\param root [out] Contains the root value of the document if it was\n   *             successfully parsed.\n   * \\param errs [out] Formatted error messages (if not NULL)\n   *        a user friendly string that lists errors in the parsed\n   * document.\n   * \\return \\c true if the document was successfully parsed, \\c false if an\n   error occurred.\n   */\n  virtual bool parse(\n      char const *beginDoc, char const *endDoc,\n      Value *root, JSONCPP_STRING *errs) = 0;\n\n  class JSON_API Factory\n  {\n  public:\n    virtual ~Factory() {}\n    /** \\brief Allocate a CharReader via operator new().\n     * \\throw std::exception if something goes wrong (e.g. invalid settings)\n     */\n    virtual CharReader *newCharReader() const = 0;\n  }; // Factory\n};   // CharReader\n\n/** \\brief Build a CharReader implementation.\n\nUsage:\n\\code\n  using namespace Json;\n  CharReaderBuilder builder;\n  builder[\"collectComments\"] = false;\n  Value value;\n  JSONCPP_STRING errs;\n  bool ok = parseFromStream(builder, std::cin, &value, &errs);\n\\endcode\n*/\nclass JSON_API CharReaderBuilder : public CharReader::Factory\n{\npublic:\n  // Note: We use a Json::Value so that we can add data-members to this class\n  // without a major version bump.\n  /** Configuration of this builder.\n    These are case-sensitive.\n    Available settings (case-sensitive):\n    - `\"collectComments\": false or true`\n      - true to collect comment and allow writing them\n        back during serialization, false to discard comments.\n        This parameter is ignored if allowComments is false.\n    - `\"allowComments\": false or true`\n      - true if comments are allowed.\n    - `\"strictRoot\": false or true`\n      - true if root must be either an array or an object value\n    - `\"allowDroppedNullPlaceholders\": false or true`\n      - true if dropped null placeholders are allowed. (See StreamWriterBuilder.)\n    - `\"allowNumericKeys\": false or true`\n      - true if numeric object keys are allowed.\n    - `\"allowSingleQuotes\": false or true`\n      - true if '' are allowed for strings (both keys and values)\n    - `\"stackLimit\": integer`\n      - Exceeding stackLimit (recursive depth of `readValue()`) will\n        cause an exception.\n      - This is a security issue (seg-faults caused by deeply nested JSON),\n        so the default is low.\n    - `\"failIfExtra\": false or true`\n      - If true, `parse()` returns false when extra non-whitespace trails\n        the JSON value in the input string.\n    - `\"rejectDupKeys\": false or true`\n      - If true, `parse()` returns false when a key is duplicated within an object.\n    - `\"allowSpecialFloats\": false or true`\n      - If true, special float values (NaNs and infinities) are allowed \n        and their values are lossfree restorable.\n\n    You can examine 'settings_` yourself\n    to see the defaults. You can also write and read them just like any\n    JSON Value.\n    \\sa setDefaults()\n    */\n  Json::Value settings_;\n\n  CharReaderBuilder();\n  ~CharReaderBuilder() JSONCPP_OVERRIDE;\n\n  CharReader *newCharReader() const JSONCPP_OVERRIDE;\n\n  /** \\return true if 'settings' are legal and consistent;\n   *   otherwise, indicate bad settings via 'invalid'.\n   */\n  bool validate(Json::Value *invalid) const;\n\n  /** A simple way to update a specific setting.\n   */\n  Value &operator[](JSONCPP_STRING key);\n\n  /** Called by ctor, but you can use this to reset settings_.\n   * \\pre 'settings' != NULL (but Json::null is fine)\n   * \\remark Defaults:\n   * \\snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults\n   */\n  static void setDefaults(Json::Value *settings);\n  /** Same as old Features::strictMode().\n   * \\pre 'settings' != NULL (but Json::null is fine)\n   * \\remark Defaults:\n   * \\snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode\n   */\n  static void strictMode(Json::Value *settings);\n};\n\n/** Consume entire stream and use its begin/end.\n  * Someday we might have a real StreamReader, but for now this\n  * is convenient.\n  */\nbool JSON_API parseFromStream(\n    CharReader::Factory const &,\n    JSONCPP_ISTREAM &,\n    Value *root, std::string *errs);\n\n/** \\brief Read from 'sin' into 'root'.\n\n Always keep comments from the input JSON.\n\n This can be used to read a file into a particular sub-object.\n For example:\n \\code\n Json::Value root;\n cin >> root[\"dir\"][\"file\"];\n cout << root;\n \\endcode\n Result:\n \\verbatim\n {\n \"dir\": {\n     \"file\": {\n     // The input stream JSON would be nested here.\n     }\n }\n }\n \\endverbatim\n \\throw std::exception on parse error.\n \\see Json::operator<<()\n*/\nJSON_API JSONCPP_ISTREAM &operator>>(JSONCPP_ISTREAM &, Value &);\n\n} // namespace Json\n\n#pragma pack(pop)\n\n#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)\n#pragma warning(pop)\n#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)\n\n#endif // CPPTL_JSON_READER_H_INCLUDED\n\n// //////////////////////////////////////////////////////////////////////\n// End of content of file: include/json/reader.h\n// //////////////////////////////////////////////////////////////////////\n\n// //////////////////////////////////////////////////////////////////////\n// Beginning of content of file: include/json/writer.h\n// //////////////////////////////////////////////////////////////////////\n\n// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors\n// Distributed under MIT license, or public domain if desired and\n// recognized in your jurisdiction.\n// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE\n\n#ifndef JSON_WRITER_H_INCLUDED\n#define JSON_WRITER_H_INCLUDED\n\n#if !defined(JSON_IS_AMALGAMATION)\n#include \"value.h\"\n#endif // if !defined(JSON_IS_AMALGAMATION)\n#include <vector>\n#include <string>\n#include <ostream>\n\n// Disable warning C4251: <data member>: <type> needs to have dll-interface to\n// be used by...\n#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)\n#pragma warning(push)\n#pragma warning(disable : 4251)\n#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)\n\n#pragma pack(push, 8)\n\nnamespace Json\n{\n\nclass Value;\n\n/**\n\nUsage:\n\\code\n  using namespace Json;\n  void writeToStdout(StreamWriter::Factory const& factory, Value const& value) {\n    std::unique_ptr<StreamWriter> const writer(\n      factory.newStreamWriter());\n    writer->write(value, &std::cout);\n    std::cout << std::endl;  // add lf and flush\n  }\n\\endcode\n*/\nclass JSON_API StreamWriter\n{\nprotected:\n  JSONCPP_OSTREAM *sout_; // not owned; will not delete\npublic:\n  StreamWriter();\n  virtual ~StreamWriter();\n  /** Write Value into document as configured in sub-class.\n      Do not take ownership of sout, but maintain a reference during function.\n      \\pre sout != NULL\n      \\return zero on success (For now, we always return zero, so check the stream instead.)\n      \\throw std::exception possibly, depending on configuration\n   */\n  virtual int write(Value const &root, JSONCPP_OSTREAM *sout) = 0;\n\n  /** \\brief A simple abstract factory.\n   */\n  class JSON_API Factory\n  {\n  public:\n    virtual ~Factory();\n    /** \\brief Allocate a CharReader via operator new().\n     * \\throw std::exception if something goes wrong (e.g. invalid settings)\n     */\n    virtual StreamWriter *newStreamWriter() const = 0;\n  }; // Factory\n};   // StreamWriter\n\n/** \\brief Write into stringstream, then return string, for convenience.\n * A StreamWriter will be created from the factory, used, and then deleted.\n */\nJSONCPP_STRING JSON_API writeString(StreamWriter::Factory const &factory, Value const &root);\n\n/** \\brief Build a StreamWriter implementation.\n\nUsage:\n\\code\n  using namespace Json;\n  Value value = ...;\n  StreamWriterBuilder builder;\n  builder[\"commentStyle\"] = \"None\";\n  builder[\"indentation\"] = \"   \";  // or whatever you like\n  std::unique_ptr<Json::StreamWriter> writer(\n      builder.newStreamWriter());\n  writer->write(value, &std::cout);\n  std::cout << std::endl;  // add lf and flush\n\\endcode\n*/\nclass JSON_API StreamWriterBuilder : public StreamWriter::Factory\n{\npublic:\n  // Note: We use a Json::Value so that we can add data-members to this class\n  // without a major version bump.\n  /** Configuration of this builder.\n    Available settings (case-sensitive):\n    - \"commentStyle\": \"None\" or \"All\"\n    - \"indentation\":  \"<anything>\"\n    - \"enableYAMLCompatibility\": false or true\n      - slightly change the whitespace around colons\n    - \"dropNullPlaceholders\": false or true\n      - Drop the \"null\" string from the writer's output for nullValues.\n        Strictly speaking, this is not valid JSON. But when the output is being\n        fed to a browser's Javascript, it makes for smaller output and the\n        browser can handle the output just fine.\n    - \"useSpecialFloats\": false or true\n      - If true, outputs non-finite floating point values in the following way:\n        NaN values as \"NaN\", positive infinity as \"Infinity\", and negative infinity\n        as \"-Infinity\".\n\n    You can examine 'settings_` yourself\n    to see the defaults. You can also write and read them just like any\n    JSON Value.\n    \\sa setDefaults()\n    */\n  Json::Value settings_;\n\n  StreamWriterBuilder();\n  ~StreamWriterBuilder() JSONCPP_OVERRIDE;\n\n  /**\n   * \\throw std::exception if something goes wrong (e.g. invalid settings)\n   */\n  StreamWriter *newStreamWriter() const JSONCPP_OVERRIDE;\n\n  /** \\return true if 'settings' are legal and consistent;\n   *   otherwise, indicate bad settings via 'invalid'.\n   */\n  bool validate(Json::Value *invalid) const;\n  /** A simple way to update a specific setting.\n   */\n  Value &operator[](JSONCPP_STRING key);\n\n  /** Called by ctor, but you can use this to reset settings_.\n   * \\pre 'settings' != NULL (but Json::null is fine)\n   * \\remark Defaults:\n   * \\snippet src/lib_json/json_writer.cpp StreamWriterBuilderDefaults\n   */\n  static void setDefaults(Json::Value *settings);\n};\n\n/** \\brief Abstract class for writers.\n * \\deprecated Use StreamWriter. (And really, this is an implementation detail.)\n */\nclass JSONCPP_DEPRECATED(\"Use StreamWriter instead\") JSON_API Writer\n{\npublic:\n  virtual ~Writer();\n\n  virtual JSONCPP_STRING write(const Value &root) = 0;\n};\n\n/** \\brief Outputs a Value in <a HREF=\"http://www.json.org\">JSON</a> format\n *without formatting (not human friendly).\n *\n * The JSON document is written in a single line. It is not intended for 'human'\n *consumption,\n * but may be usefull to support feature such as RPC where bandwith is limited.\n * \\sa Reader, Value\n * \\deprecated Use StreamWriterBuilder.\n */\nclass JSONCPP_DEPRECATED(\"Use StreamWriterBuilder instead\") JSON_API FastWriter : public Writer\n{\n\npublic:\n  FastWriter();\n  ~FastWriter() JSONCPP_OVERRIDE {}\n\n  void enableYAMLCompatibility();\n\n  /** \\brief Drop the \"null\" string from the writer's output for nullValues.\n   * Strictly speaking, this is not valid JSON. But when the output is being\n   * fed to a browser's Javascript, it makes for smaller output and the\n   * browser can handle the output just fine.\n   */\n  void dropNullPlaceholders();\n\n  void omitEndingLineFeed();\n\npublic: // overridden from Writer\n  JSONCPP_STRING write(const Value &root) JSONCPP_OVERRIDE;\n\nprivate:\n  void writeValue(const Value &value);\n\n  JSONCPP_STRING document_;\n  bool yamlCompatiblityEnabled_;\n  bool dropNullPlaceholders_;\n  bool omitEndingLineFeed_;\n};\n\n/** \\brief Writes a Value in <a HREF=\"http://www.json.org\">JSON</a> format in a\n *human friendly way.\n *\n * The rules for line break and indent are as follow:\n * - Object value:\n *     - if empty then print {} without indent and line break\n *     - if not empty the print '{', line break & indent, print one value per\n *line\n *       and then unindent and line break and print '}'.\n * - Array value:\n *     - if empty then print [] without indent and line break\n *     - if the array contains no object value, empty array or some other value\n *types,\n *       and all the values fit on one lines, then print the array on a single\n *line.\n *     - otherwise, it the values do not fit on one line, or the array contains\n *       object or non empty array, then print one value per line.\n *\n * If the Value have comments then they are outputed according to their\n *#CommentPlacement.\n *\n * \\sa Reader, Value, Value::setComment()\n * \\deprecated Use StreamWriterBuilder.\n */\nclass JSONCPP_DEPRECATED(\"Use StreamWriterBuilder instead\") JSON_API StyledWriter : public Writer\n{\npublic:\n  StyledWriter();\n  ~StyledWriter() JSONCPP_OVERRIDE {}\n\npublic: // overridden from Writer\n  /** \\brief Serialize a Value in <a HREF=\"http://www.json.org\">JSON</a> format.\n   * \\param root Value to serialize.\n   * \\return String containing the JSON document that represents the root value.\n   */\n  JSONCPP_STRING write(const Value &root) JSONCPP_OVERRIDE;\n\nprivate:\n  void writeValue(const Value &value);\n  void writeArrayValue(const Value &value);\n  bool isMultineArray(const Value &value);\n  void pushValue(const JSONCPP_STRING &value);\n  void writeIndent();\n  void writeWithIndent(const JSONCPP_STRING &value);\n  void indent();\n  void unindent();\n  void writeCommentBeforeValue(const Value &root);\n  void writeCommentAfterValueOnSameLine(const Value &root);\n  bool hasCommentForValue(const Value &value);\n  static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING &text);\n\n  typedef std::vector<JSONCPP_STRING> ChildValues;\n\n  ChildValues childValues_;\n  JSONCPP_STRING document_;\n  JSONCPP_STRING indentString_;\n  unsigned int rightMargin_;\n  unsigned int indentSize_;\n  bool addChildValues_;\n};\n\n/** \\brief Writes a Value in <a HREF=\"http://www.json.org\">JSON</a> format in a\n human friendly way,\n     to a stream rather than to a string.\n *\n * The rules for line break and indent are as follow:\n * - Object value:\n *     - if empty then print {} without indent and line break\n *     - if not empty the print '{', line break & indent, print one value per\n line\n *       and then unindent and line break and print '}'.\n * - Array value:\n *     - if empty then print [] without indent and line break\n *     - if the array contains no object value, empty array or some other value\n types,\n *       and all the values fit on one lines, then print the array on a single\n line.\n *     - otherwise, it the values do not fit on one line, or the array contains\n *       object or non empty array, then print one value per line.\n *\n * If the Value have comments then they are outputed according to their\n #CommentPlacement.\n *\n * \\sa Reader, Value, Value::setComment()\n * \\deprecated Use StreamWriterBuilder.\n */\nclass JSONCPP_DEPRECATED(\"Use StreamWriterBuilder instead\") JSON_API StyledStreamWriter\n{\npublic:\n  /**\n * \\param indentation Each level will be indented by this amount extra.\n */\n  StyledStreamWriter(JSONCPP_STRING indentation = \"\\t\");\n  ~StyledStreamWriter() {}\n\npublic:\n  /** \\brief Serialize a Value in <a HREF=\"http://www.json.org\">JSON</a> format.\n   * \\param out Stream to write to. (Can be ostringstream, e.g.)\n   * \\param root Value to serialize.\n   * \\note There is no point in deriving from Writer, since write() should not\n   * return a value.\n   */\n  void write(JSONCPP_OSTREAM &out, const Value &root);\n\nprivate:\n  void writeValue(const Value &value);\n  void writeArrayValue(const Value &value);\n  bool isMultineArray(const Value &value);\n  void pushValue(const JSONCPP_STRING &value);\n  void writeIndent();\n  void writeWithIndent(const JSONCPP_STRING &value);\n  void indent();\n  void unindent();\n  void writeCommentBeforeValue(const Value &root);\n  void writeCommentAfterValueOnSameLine(const Value &root);\n  bool hasCommentForValue(const Value &value);\n  static JSONCPP_STRING normalizeEOL(const JSONCPP_STRING &text);\n\n  typedef std::vector<JSONCPP_STRING> ChildValues;\n\n  ChildValues childValues_;\n  JSONCPP_OSTREAM *document_;\n  JSONCPP_STRING indentString_;\n  unsigned int rightMargin_;\n  JSONCPP_STRING indentation_;\n  bool addChildValues_ : 1;\n  bool indented_ : 1;\n};\n\n#if defined(JSON_HAS_INT64)\nJSONCPP_STRING JSON_API valueToString(Int value);\nJSONCPP_STRING JSON_API valueToString(UInt value);\n#endif // if defined(JSON_HAS_INT64)\nJSONCPP_STRING JSON_API valueToString(LargestInt value);\nJSONCPP_STRING JSON_API valueToString(LargestUInt value);\nJSONCPP_STRING JSON_API valueToString(double value);\nJSONCPP_STRING JSON_API valueToString(bool value);\nJSONCPP_STRING JSON_API valueToQuotedString(const char *value);\n\n/// \\brief Output using the StyledStreamWriter.\n/// \\see Json::operator>>()\nJSON_API JSONCPP_OSTREAM &operator<<(JSONCPP_OSTREAM &, const Value &root);\n\n} // namespace Json\n\n#pragma pack(pop)\n\n#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)\n#pragma warning(pop)\n#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)\n\n#endif // JSON_WRITER_H_INCLUDED\n\n// //////////////////////////////////////////////////////////////////////\n// End of content of file: include/json/writer.h\n// //////////////////////////////////////////////////////////////////////\n\n// //////////////////////////////////////////////////////////////////////\n// Beginning of content of file: include/json/assertions.h\n// //////////////////////////////////////////////////////////////////////\n\n// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors\n// Distributed under MIT license, or public domain if desired and\n// recognized in your jurisdiction.\n// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE\n\n#ifndef CPPTL_JSON_ASSERTIONS_H_INCLUDED\n#define CPPTL_JSON_ASSERTIONS_H_INCLUDED\n\n#include <stdlib.h>\n#include <sstream>\n\n#if !defined(JSON_IS_AMALGAMATION)\n#include \"config.h\"\n#endif // if !defined(JSON_IS_AMALGAMATION)\n\n/** It should not be possible for a maliciously designed file to\n *  cause an abort() or seg-fault, so these macros are used only\n *  for pre-condition violations and internal logic errors.\n */\n#if JSON_USE_EXCEPTION\n\n// @todo <= add detail about condition in exception\n#define JSON_ASSERT(condition)                     \\\n  {                                                \\\n    if (!(condition))                              \\\n    {                                              \\\n      Json::throwLogicError(\"assert json failed\"); \\\n    }                                              \\\n  }\n\n#define JSON_FAIL_MESSAGE(message)    \\\n  {                                   \\\n    JSONCPP_OSTRINGSTREAM oss;        \\\n    oss << message;                   \\\n    Json::throwLogicError(oss.str()); \\\n    abort();                          \\\n  }\n\n#else // JSON_USE_EXCEPTION\n\n#define JSON_ASSERT(condition) assert(condition)\n\n// The call to assert() will show the failure message in debug builds. In\n// release builds we abort, for a core-dump or debugger.\n#define JSON_FAIL_MESSAGE(message)      \\\n  {                                     \\\n    JSONCPP_OSTRINGSTREAM oss;          \\\n    oss << message;                     \\\n    assert(false && oss.str().c_str()); \\\n    abort();                            \\\n  }\n\n#endif\n\n#define JSON_ASSERT_MESSAGE(condition, message) \\\n  if (!(condition))                             \\\n  {                                             \\\n    JSON_FAIL_MESSAGE(message);                 \\\n  }\n\n#endif // CPPTL_JSON_ASSERTIONS_H_INCLUDED\n\n// //////////////////////////////////////////////////////////////////////\n// End of content of file: include/json/assertions.h\n// //////////////////////////////////////////////////////////////////////\n\n#endif //ifndef JSON_AMALGATED_H_INCLUDED\n"
  },
  {
    "path": "thirdparty/jsoncpp/jsoncpp.cpp",
    "content": "/// Json-cpp amalgated source (http://jsoncpp.sourceforge.net/).\n/// It is intended to be used with #include \"json/json.h\"\n\n// //////////////////////////////////////////////////////////////////////\n// Beginning of content of file: LICENSE\n// //////////////////////////////////////////////////////////////////////\n\n/*\nThe JsonCpp library's source code, including accompanying documentation,\ntests and demonstration applications, are licensed under the following\nconditions...\n\nBaptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all\njurisdictions which recognize such a disclaimer. In such jurisdictions,\nthis software is released into the Public Domain.\n\nIn jurisdictions which do not recognize Public Domain property (e.g. Germany as of\n2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and\nThe JsonCpp Authors, and is released under the terms of the MIT License (see below).\n\nIn jurisdictions which recognize Public Domain property, the user of this\nsoftware may choose to accept it either as 1) Public Domain, 2) under the\nconditions of the MIT License (see below), or 3) under the terms of dual\nPublic Domain/MIT License conditions described here, as they choose.\n\nThe MIT License is about as close to Public Domain as a license can get, and is\ndescribed in clear, concise terms at:\n\n   http://en.wikipedia.org/wiki/MIT_License\n\nThe full text of the MIT License follows:\n\n========================================================================\nCopyright (c) 2007-2010 Baptiste Lepilleur and The JsonCpp Authors\n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this software and associated documentation\nfiles (the \"Software\"), to deal in the Software without\nrestriction, including without limitation the rights to use, copy,\nmodify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\nBE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\nACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n========================================================================\n(END LICENSE TEXT)\n\nThe MIT license is compatible with both the GPL and commercial\nsoftware, affording one all of the rights of Public Domain with the\nminor nuisance of being required to keep the above copyright notice\nand license text in the source code. Note also that by accepting the\nPublic Domain \"license\" you can re-license your copy using whatever\nlicense you like.\n\n*/\n\n// //////////////////////////////////////////////////////////////////////\n// End of content of file: LICENSE\n// //////////////////////////////////////////////////////////////////////\n\n#include \"json/json.h\"\n\n#ifndef JSON_IS_AMALGAMATION\n#error \"Compile with -I PATH_TO_JSON_DIRECTORY\"\n#endif\n\n// //////////////////////////////////////////////////////////////////////\n// Beginning of content of file: src/lib_json/json_tool.h\n// //////////////////////////////////////////////////////////////////////\n\n// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors\n// Distributed under MIT license, or public domain if desired and\n// recognized in your jurisdiction.\n// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE\n\n#ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED\n#define LIB_JSONCPP_JSON_TOOL_H_INCLUDED\n\n// Also support old flag NO_LOCALE_SUPPORT\n#ifdef NO_LOCALE_SUPPORT\n#define JSONCPP_NO_LOCALE_SUPPORT\n#endif\n\n#ifndef JSONCPP_NO_LOCALE_SUPPORT\n#include <clocale>\n#endif\n\n/* This header provides common string manipulation support, such as UTF-8,\n * portable conversion from/to string...\n *\n * It is an internal header that must not be exposed.\n */\n\nnamespace Json\n{\nstatic char getDecimalPoint()\n{\n#ifdef JSONCPP_NO_LOCALE_SUPPORT\n  return '\\0';\n#else\n  struct lconv *lc = localeconv();\n  return lc ? *(lc->decimal_point) : '\\0';\n#endif\n}\n\n/// Converts a unicode code-point to UTF-8.\nstatic inline JSONCPP_STRING codePointToUTF8(unsigned int cp)\n{\n  JSONCPP_STRING result;\n\n  // based on description from http://en.wikipedia.org/wiki/UTF-8\n\n  if (cp <= 0x7f)\n  {\n    result.resize(1);\n    result[0] = static_cast<char>(cp);\n  }\n  else if (cp <= 0x7FF)\n  {\n    result.resize(2);\n    result[1] = static_cast<char>(0x80 | (0x3f & cp));\n    result[0] = static_cast<char>(0xC0 | (0x1f & (cp >> 6)));\n  }\n  else if (cp <= 0xFFFF)\n  {\n    result.resize(3);\n    result[2] = static_cast<char>(0x80 | (0x3f & cp));\n    result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 6)));\n    result[0] = static_cast<char>(0xE0 | (0xf & (cp >> 12)));\n  }\n  else if (cp <= 0x10FFFF)\n  {\n    result.resize(4);\n    result[3] = static_cast<char>(0x80 | (0x3f & cp));\n    result[2] = static_cast<char>(0x80 | (0x3f & (cp >> 6)));\n    result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 12)));\n    result[0] = static_cast<char>(0xF0 | (0x7 & (cp >> 18)));\n  }\n\n  return result;\n}\n\n/// Returns true if ch is a control character (in range [1,31]).\nstatic inline bool isControlCharacter(char ch) { return ch > 0 && ch <= 0x1F; }\n\nenum\n{\n  /// Constant that specify the size of the buffer that must be passed to\n  /// uintToString.\n  uintToStringBufferSize = 3 * sizeof(LargestUInt) + 1\n};\n\n// Defines a char buffer for use with uintToString().\ntypedef char UIntToStringBuffer[uintToStringBufferSize];\n\n/** Converts an unsigned integer to string.\n * @param value Unsigned interger to convert to string\n * @param current Input/Output string buffer.\n *        Must have at least uintToStringBufferSize chars free.\n */\nstatic inline void uintToString(LargestUInt value, char *&current)\n{\n  *--current = 0;\n  do\n  {\n    *--current = static_cast<char>(value % 10U + static_cast<unsigned>('0'));\n    value /= 10;\n  } while (value != 0);\n}\n\n/** Change ',' to '.' everywhere in buffer.\n *\n * We had a sophisticated way, but it did not work in WinCE.\n * @see https://github.com/open-source-parsers/jsoncpp/pull/9\n */\nstatic inline void fixNumericLocale(char *begin, char *end)\n{\n  while (begin < end)\n  {\n    if (*begin == ',')\n    {\n      *begin = '.';\n    }\n    ++begin;\n  }\n}\n\nstatic inline void fixNumericLocaleInput(char *begin, char *end)\n{\n  char decimalPoint = getDecimalPoint();\n  if (decimalPoint != '\\0' && decimalPoint != '.')\n  {\n    while (begin < end)\n    {\n      if (*begin == '.')\n      {\n        *begin = decimalPoint;\n      }\n      ++begin;\n    }\n  }\n}\n\n} // namespace Json\n\n#endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED\n\n// //////////////////////////////////////////////////////////////////////\n// End of content of file: src/lib_json/json_tool.h\n// //////////////////////////////////////////////////////////////////////\n\n// //////////////////////////////////////////////////////////////////////\n// Beginning of content of file: src/lib_json/json_reader.cpp\n// //////////////////////////////////////////////////////////////////////\n\n// Copyright 2007-2011 Baptiste Lepilleur and The JsonCpp Authors\n// Copyright (C) 2016 InfoTeCS JSC. All rights reserved.\n// Distributed under MIT license, or public domain if desired and\n// recognized in your jurisdiction.\n// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE\n\n#if !defined(JSON_IS_AMALGAMATION)\n#include <json/assertions.h>\n#include <json/reader.h>\n#include <json/value.h>\n#include \"json_tool.h\"\n#endif // if !defined(JSON_IS_AMALGAMATION)\n#include <utility>\n#include <cstdio>\n#include <cassert>\n#include <cstring>\n#include <istream>\n#include <sstream>\n#include <memory>\n#include <set>\n#include <limits>\n\n#if defined(_MSC_VER)\n#if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && _MSC_VER >= 1500 // VC++ 9.0 and above\n#define snprintf sprintf_s\n#elif _MSC_VER >= 1900 // VC++ 14.0 and above\n#define snprintf std::snprintf\n#else\n#define snprintf _snprintf\n#endif\n#elif defined(__ANDROID__) || defined(__QNXNTO__)\n#define snprintf snprintf\n#elif __cplusplus >= 201103L\n#if !defined(__MINGW32__) && !defined(__CYGWIN__)\n#define snprintf std::snprintf\n#endif\n#endif\n\n#if defined(__QNXNTO__)\n#define sscanf std::sscanf\n#endif\n\n#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0\n// Disable warning about strdup being deprecated.\n#pragma warning(disable : 4996)\n#endif\n\n// Define JSONCPP_DEPRECATED_STACK_LIMIT as an appropriate integer at compile time to change the stack limit\n#if !defined(JSONCPP_DEPRECATED_STACK_LIMIT)\n#define JSONCPP_DEPRECATED_STACK_LIMIT 1000\n#endif\n\nstatic size_t const stackLimit_g = JSONCPP_DEPRECATED_STACK_LIMIT; // see readValue()\n\nnamespace Json\n{\n\n#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520)\ntypedef std::unique_ptr<CharReader> CharReaderPtr;\n#else\ntypedef std::auto_ptr<CharReader> CharReaderPtr;\n#endif\n\n// Implementation of class Features\n// ////////////////////////////////\n\nFeatures::Features()\n    : allowComments_(true), strictRoot_(false),\n      allowDroppedNullPlaceholders_(false), allowNumericKeys_(false) {}\n\nFeatures Features::all() { return Features(); }\n\nFeatures Features::strictMode()\n{\n  Features features;\n  features.allowComments_ = false;\n  features.strictRoot_ = true;\n  features.allowDroppedNullPlaceholders_ = false;\n  features.allowNumericKeys_ = false;\n  return features;\n}\n\n// Implementation of class Reader\n// ////////////////////////////////\n\nbool Reader::containsNewLine(Reader::Location begin, Reader::Location end)\n{\n  for (; begin < end; ++begin)\n    if (*begin == '\\n' || *begin == '\\r')\n      return true;\n  return false;\n}\n\n// Class Reader\n// //////////////////////////////////////////////////////////////////\n\nReader::Reader()\n    : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),\n      lastValue_(), commentsBefore_(), features_(Features::all()),\n      collectComments_() {}\n\nReader::Reader(const Features &features)\n    : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),\n      lastValue_(), commentsBefore_(), features_(features), collectComments_()\n{\n}\n\nbool Reader::parse(const std::string &document, Value &root, bool collectComments)\n{\n  document_.assign(document.begin(), document.end());\n  const char *begin = document_.c_str();\n  const char *end = begin + document_.length();\n  return parse(begin, end, root, collectComments);\n}\n\nbool Reader::parse(std::istream &sin, Value &root, bool collectComments)\n{\n  // std::istream_iterator<char> begin(sin);\n  // std::istream_iterator<char> end;\n  // Those would allow streamed input from a file, if parse() were a\n  // template function.\n\n  // Since JSONCPP_STRING is reference-counted, this at least does not\n  // create an extra copy.\n  JSONCPP_STRING doc;\n  std::getline(sin, doc, (char)EOF);\n  return parse(doc.data(), doc.data() + doc.size(), root, collectComments);\n}\n\nbool Reader::parse(const char *beginDoc,\n                   const char *endDoc,\n                   Value &root,\n                   bool collectComments)\n{\n  if (!features_.allowComments_)\n  {\n    collectComments = false;\n  }\n\n  begin_ = beginDoc;\n  end_ = endDoc;\n  collectComments_ = collectComments;\n  current_ = begin_;\n  lastValueEnd_ = 0;\n  lastValue_ = 0;\n  commentsBefore_.clear();\n  errors_.clear();\n  while (!nodes_.empty())\n    nodes_.pop();\n  nodes_.push(&root);\n\n  bool successful = readValue();\n  Token token;\n  skipCommentTokens(token);\n  if (collectComments_ && !commentsBefore_.empty())\n    root.setComment(commentsBefore_, commentAfter);\n  if (features_.strictRoot_)\n  {\n    if (!root.isArray() && !root.isObject())\n    {\n      // Set error location to start of doc, ideally should be first token found\n      // in doc\n      token.type_ = tokenError;\n      token.start_ = beginDoc;\n      token.end_ = endDoc;\n      addError(\n          \"A valid JSON document must be either an array or an object value.\",\n          token);\n      return false;\n    }\n  }\n  return successful;\n}\n\nbool Reader::readValue()\n{\n  // readValue() may call itself only if it calls readObject() or ReadArray().\n  // These methods execute nodes_.push() just before and nodes_.pop)() just after calling readValue().\n  // parse() executes one nodes_.push(), so > instead of >=.\n  if (nodes_.size() > stackLimit_g)\n    throwRuntimeError(\"Exceeded stackLimit in readValue().\");\n\n  Token token;\n  skipCommentTokens(token);\n  bool successful = true;\n\n  if (collectComments_ && !commentsBefore_.empty())\n  {\n    currentValue().setComment(commentsBefore_, commentBefore);\n    commentsBefore_.clear();\n  }\n\n  switch (token.type_)\n  {\n  case tokenObjectBegin:\n    successful = readObject(token);\n    currentValue().setOffsetLimit(current_ - begin_);\n    break;\n  case tokenArrayBegin:\n    successful = readArray(token);\n    currentValue().setOffsetLimit(current_ - begin_);\n    break;\n  case tokenNumber:\n    successful = decodeNumber(token);\n    break;\n  case tokenString:\n    successful = decodeString(token);\n    break;\n  case tokenTrue:\n  {\n    Value v(true);\n    currentValue().swapPayload(v);\n    currentValue().setOffsetStart(token.start_ - begin_);\n    currentValue().setOffsetLimit(token.end_ - begin_);\n  }\n  break;\n  case tokenFalse:\n  {\n    Value v(false);\n    currentValue().swapPayload(v);\n    currentValue().setOffsetStart(token.start_ - begin_);\n    currentValue().setOffsetLimit(token.end_ - begin_);\n  }\n  break;\n  case tokenNull:\n  {\n    Value v;\n    currentValue().swapPayload(v);\n    currentValue().setOffsetStart(token.start_ - begin_);\n    currentValue().setOffsetLimit(token.end_ - begin_);\n  }\n  break;\n  case tokenArraySeparator:\n  case tokenObjectEnd:\n  case tokenArrayEnd:\n    if (features_.allowDroppedNullPlaceholders_)\n    {\n      // \"Un-read\" the current token and mark the current value as a null\n      // token.\n      current_--;\n      Value v;\n      currentValue().swapPayload(v);\n      currentValue().setOffsetStart(current_ - begin_ - 1);\n      currentValue().setOffsetLimit(current_ - begin_);\n      break;\n    } // Else, fall through...\n  default:\n    currentValue().setOffsetStart(token.start_ - begin_);\n    currentValue().setOffsetLimit(token.end_ - begin_);\n    return addError(\"Syntax error: value, object or array expected.\", token);\n  }\n\n  if (collectComments_)\n  {\n    lastValueEnd_ = current_;\n    lastValue_ = &currentValue();\n  }\n\n  return successful;\n}\n\nvoid Reader::skipCommentTokens(Token &token)\n{\n  if (features_.allowComments_)\n  {\n    do\n    {\n      readToken(token);\n    } while (token.type_ == tokenComment);\n  }\n  else\n  {\n    readToken(token);\n  }\n}\n\nbool Reader::readToken(Token &token)\n{\n  skipSpaces();\n  token.start_ = current_;\n  Char c = getNextChar();\n  bool ok = true;\n  switch (c)\n  {\n  case '{':\n    token.type_ = tokenObjectBegin;\n    break;\n  case '}':\n    token.type_ = tokenObjectEnd;\n    break;\n  case '[':\n    token.type_ = tokenArrayBegin;\n    break;\n  case ']':\n    token.type_ = tokenArrayEnd;\n    break;\n  case '\"':\n    token.type_ = tokenString;\n    ok = readString();\n    break;\n  case '/':\n    token.type_ = tokenComment;\n    ok = readComment();\n    break;\n  case '0':\n  case '1':\n  case '2':\n  case '3':\n  case '4':\n  case '5':\n  case '6':\n  case '7':\n  case '8':\n  case '9':\n  case '-':\n    token.type_ = tokenNumber;\n    readNumber();\n    break;\n  case 't':\n    token.type_ = tokenTrue;\n    ok = match(\"rue\", 3);\n    break;\n  case 'f':\n    token.type_ = tokenFalse;\n    ok = match(\"alse\", 4);\n    break;\n  case 'n':\n    token.type_ = tokenNull;\n    ok = match(\"ull\", 3);\n    break;\n  case ',':\n    token.type_ = tokenArraySeparator;\n    break;\n  case ':':\n    token.type_ = tokenMemberSeparator;\n    break;\n  case 0:\n    token.type_ = tokenEndOfStream;\n    break;\n  default:\n    ok = false;\n    break;\n  }\n  if (!ok)\n    token.type_ = tokenError;\n  token.end_ = current_;\n  return true;\n}\n\nvoid Reader::skipSpaces()\n{\n  while (current_ != end_)\n  {\n    Char c = *current_;\n    if (c == ' ' || c == '\\t' || c == '\\r' || c == '\\n')\n      ++current_;\n    else\n      break;\n  }\n}\n\nbool Reader::match(Location pattern, int patternLength)\n{\n  if (end_ - current_ < patternLength)\n    return false;\n  int index = patternLength;\n  while (index--)\n    if (current_[index] != pattern[index])\n      return false;\n  current_ += patternLength;\n  return true;\n}\n\nbool Reader::readComment()\n{\n  Location commentBegin = current_ - 1;\n  Char c = getNextChar();\n  bool successful = false;\n  if (c == '*')\n    successful = readCStyleComment();\n  else if (c == '/')\n    successful = readCppStyleComment();\n  if (!successful)\n    return false;\n\n  if (collectComments_)\n  {\n    CommentPlacement placement = commentBefore;\n    if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin))\n    {\n      if (c != '*' || !containsNewLine(commentBegin, current_))\n        placement = commentAfterOnSameLine;\n    }\n\n    addComment(commentBegin, current_, placement);\n  }\n  return true;\n}\n\nJSONCPP_STRING Reader::normalizeEOL(Reader::Location begin, Reader::Location end)\n{\n  JSONCPP_STRING normalized;\n  normalized.reserve(static_cast<size_t>(end - begin));\n  Reader::Location current = begin;\n  while (current != end)\n  {\n    char c = *current++;\n    if (c == '\\r')\n    {\n      if (current != end && *current == '\\n')\n        // convert dos EOL\n        ++current;\n      // convert Mac EOL\n      normalized += '\\n';\n    }\n    else\n    {\n      normalized += c;\n    }\n  }\n  return normalized;\n}\n\nvoid Reader::addComment(Location begin, Location end, CommentPlacement placement)\n{\n  assert(collectComments_);\n  const JSONCPP_STRING &normalized = normalizeEOL(begin, end);\n  if (placement == commentAfterOnSameLine)\n  {\n    assert(lastValue_ != 0);\n    lastValue_->setComment(normalized, placement);\n  }\n  else\n  {\n    commentsBefore_ += normalized;\n  }\n}\n\nbool Reader::readCStyleComment()\n{\n  while ((current_ + 1) < end_)\n  {\n    Char c = getNextChar();\n    if (c == '*' && *current_ == '/')\n      break;\n  }\n  return getNextChar() == '/';\n}\n\nbool Reader::readCppStyleComment()\n{\n  while (current_ != end_)\n  {\n    Char c = getNextChar();\n    if (c == '\\n')\n      break;\n    if (c == '\\r')\n    {\n      // Consume DOS EOL. It will be normalized in addComment.\n      if (current_ != end_ && *current_ == '\\n')\n        getNextChar();\n      // Break on Moc OS 9 EOL.\n      break;\n    }\n  }\n  return true;\n}\n\nvoid Reader::readNumber()\n{\n  const char *p = current_;\n  char c = '0'; // stopgap for already consumed character\n  // integral part\n  while (c >= '0' && c <= '9')\n    c = (current_ = p) < end_ ? *p++ : '\\0';\n  // fractional part\n  if (c == '.')\n  {\n    c = (current_ = p) < end_ ? *p++ : '\\0';\n    while (c >= '0' && c <= '9')\n      c = (current_ = p) < end_ ? *p++ : '\\0';\n  }\n  // exponential part\n  if (c == 'e' || c == 'E')\n  {\n    c = (current_ = p) < end_ ? *p++ : '\\0';\n    if (c == '+' || c == '-')\n      c = (current_ = p) < end_ ? *p++ : '\\0';\n    while (c >= '0' && c <= '9')\n      c = (current_ = p) < end_ ? *p++ : '\\0';\n  }\n}\n\nbool Reader::readString()\n{\n  Char c = '\\0';\n  while (current_ != end_)\n  {\n    c = getNextChar();\n    if (c == '\\\\')\n      getNextChar();\n    else if (c == '\"')\n      break;\n  }\n  return c == '\"';\n}\n\nbool Reader::readObject(Token &tokenStart)\n{\n  Token tokenName;\n  JSONCPP_STRING name;\n  Value init(objectValue);\n  currentValue().swapPayload(init);\n  currentValue().setOffsetStart(tokenStart.start_ - begin_);\n  while (readToken(tokenName))\n  {\n    bool initialTokenOk = true;\n    while (tokenName.type_ == tokenComment && initialTokenOk)\n      initialTokenOk = readToken(tokenName);\n    if (!initialTokenOk)\n      break;\n    if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object\n      return true;\n    name.clear();\n    if (tokenName.type_ == tokenString)\n    {\n      if (!decodeString(tokenName, name))\n        return recoverFromError(tokenObjectEnd);\n    }\n    else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_)\n    {\n      Value numberName;\n      if (!decodeNumber(tokenName, numberName))\n        return recoverFromError(tokenObjectEnd);\n      name = JSONCPP_STRING(numberName.asCString());\n    }\n    else\n    {\n      break;\n    }\n\n    Token colon;\n    if (!readToken(colon) || colon.type_ != tokenMemberSeparator)\n    {\n      return addErrorAndRecover(\n          \"Missing ':' after object member name\", colon, tokenObjectEnd);\n    }\n    Value &value = currentValue()[name];\n    nodes_.push(&value);\n    bool ok = readValue();\n    nodes_.pop();\n    if (!ok) // error already set\n      return recoverFromError(tokenObjectEnd);\n\n    Token comma;\n    if (!readToken(comma) ||\n        (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&\n         comma.type_ != tokenComment))\n    {\n      return addErrorAndRecover(\n          \"Missing ',' or '}' in object declaration\", comma, tokenObjectEnd);\n    }\n    bool finalizeTokenOk = true;\n    while (comma.type_ == tokenComment && finalizeTokenOk)\n      finalizeTokenOk = readToken(comma);\n    if (comma.type_ == tokenObjectEnd)\n      return true;\n  }\n  return addErrorAndRecover(\n      \"Missing '}' or object member name\", tokenName, tokenObjectEnd);\n}\n\nbool Reader::readArray(Token &tokenStart)\n{\n  Value init(arrayValue);\n  currentValue().swapPayload(init);\n  currentValue().setOffsetStart(tokenStart.start_ - begin_);\n  skipSpaces();\n  if (current_ != end_ && *current_ == ']') // empty array\n  {\n    Token endArray;\n    readToken(endArray);\n    return true;\n  }\n  int index = 0;\n  for (;;)\n  {\n    Value &value = currentValue()[index++];\n    nodes_.push(&value);\n    bool ok = readValue();\n    nodes_.pop();\n    if (!ok) // error already set\n      return recoverFromError(tokenArrayEnd);\n\n    Token token;\n    // Accept Comment after last item in the array.\n    ok = readToken(token);\n    while (token.type_ == tokenComment && ok)\n    {\n      ok = readToken(token);\n    }\n    bool badTokenType =\n        (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd);\n    if (!ok || badTokenType)\n    {\n      return addErrorAndRecover(\n          \"Missing ',' or ']' in array declaration\", token, tokenArrayEnd);\n    }\n    if (token.type_ == tokenArrayEnd)\n      break;\n  }\n  return true;\n}\n\nbool Reader::decodeNumber(Token &token)\n{\n  Value decoded;\n  if (!decodeNumber(token, decoded))\n    return false;\n  currentValue().swapPayload(decoded);\n  currentValue().setOffsetStart(token.start_ - begin_);\n  currentValue().setOffsetLimit(token.end_ - begin_);\n  return true;\n}\n\nbool Reader::decodeNumber(Token &token, Value &decoded)\n{\n  // Attempts to parse the number as an integer. If the number is\n  // larger than the maximum supported value of an integer then\n  // we decode the number as a double.\n  Location current = token.start_;\n  bool isNegative = *current == '-';\n  if (isNegative)\n    ++current;\n  // TODO: Help the compiler do the div and mod at compile time or get rid of them.\n  Value::LargestUInt maxIntegerValue =\n      isNegative ? Value::LargestUInt(Value::maxLargestInt) + 1\n                 : Value::maxLargestUInt;\n  Value::LargestUInt threshold = maxIntegerValue / 10;\n  Value::LargestUInt value = 0;\n  while (current < token.end_)\n  {\n    Char c = *current++;\n    if (c < '0' || c > '9')\n      return decodeDouble(token, decoded);\n    Value::UInt digit(static_cast<Value::UInt>(c - '0'));\n    if (value >= threshold)\n    {\n      // We've hit or exceeded the max value divided by 10 (rounded down). If\n      // a) we've only just touched the limit, b) this is the last digit, and\n      // c) it's small enough to fit in that rounding delta, we're okay.\n      // Otherwise treat this number as a double to avoid overflow.\n      if (value > threshold || current != token.end_ ||\n          digit > maxIntegerValue % 10)\n      {\n        return decodeDouble(token, decoded);\n      }\n    }\n    value = value * 10 + digit;\n  }\n  if (isNegative && value == maxIntegerValue)\n    decoded = Value::minLargestInt;\n  else if (isNegative)\n    decoded = -Value::LargestInt(value);\n  else if (value <= Value::LargestUInt(Value::maxInt))\n    decoded = Value::LargestInt(value);\n  else\n    decoded = value;\n  return true;\n}\n\nbool Reader::decodeDouble(Token &token)\n{\n  Value decoded;\n  if (!decodeDouble(token, decoded))\n    return false;\n  currentValue().swapPayload(decoded);\n  currentValue().setOffsetStart(token.start_ - begin_);\n  currentValue().setOffsetLimit(token.end_ - begin_);\n  return true;\n}\n\nbool Reader::decodeDouble(Token &token, Value &decoded)\n{\n  double value = 0;\n  JSONCPP_STRING buffer(token.start_, token.end_);\n  JSONCPP_ISTRINGSTREAM is(buffer);\n  if (!(is >> value))\n    return addError(\"'\" + JSONCPP_STRING(token.start_, token.end_) +\n                        \"' is not a number.\",\n                    token);\n  decoded = value;\n  return true;\n}\n\nbool Reader::decodeString(Token &token)\n{\n  JSONCPP_STRING decoded_string;\n  if (!decodeString(token, decoded_string))\n    return false;\n  Value decoded(decoded_string);\n  currentValue().swapPayload(decoded);\n  currentValue().setOffsetStart(token.start_ - begin_);\n  currentValue().setOffsetLimit(token.end_ - begin_);\n  return true;\n}\n\nbool Reader::decodeString(Token &token, JSONCPP_STRING &decoded)\n{\n  decoded.reserve(static_cast<size_t>(token.end_ - token.start_ - 2));\n  Location current = token.start_ + 1; // skip '\"'\n  Location end = token.end_ - 1;       // do not include '\"'\n  while (current != end)\n  {\n    Char c = *current++;\n    if (c == '\"')\n      break;\n    else if (c == '\\\\')\n    {\n      if (current == end)\n        return addError(\"Empty escape sequence in string\", token, current);\n      Char escape = *current++;\n      switch (escape)\n      {\n      case '\"':\n        decoded += '\"';\n        break;\n      case '/':\n        decoded += '/';\n        break;\n      case '\\\\':\n        decoded += '\\\\';\n        break;\n      case 'b':\n        decoded += '\\b';\n        break;\n      case 'f':\n        decoded += '\\f';\n        break;\n      case 'n':\n        decoded += '\\n';\n        break;\n      case 'r':\n        decoded += '\\r';\n        break;\n      case 't':\n        decoded += '\\t';\n        break;\n      case 'u':\n      {\n        unsigned int unicode;\n        if (!decodeUnicodeCodePoint(token, current, end, unicode))\n          return false;\n        decoded += codePointToUTF8(unicode);\n      }\n      break;\n      default:\n        return addError(\"Bad escape sequence in string\", token, current);\n      }\n    }\n    else\n    {\n      decoded += c;\n    }\n  }\n  return true;\n}\n\nbool Reader::decodeUnicodeCodePoint(Token &token,\n                                    Location &current,\n                                    Location end,\n                                    unsigned int &unicode)\n{\n\n  if (!decodeUnicodeEscapeSequence(token, current, end, unicode))\n    return false;\n  if (unicode >= 0xD800 && unicode <= 0xDBFF)\n  {\n    // surrogate pairs\n    if (end - current < 6)\n      return addError(\n          \"additional six characters expected to parse unicode surrogate pair.\",\n          token,\n          current);\n    unsigned int surrogatePair;\n    if (*(current++) == '\\\\' && *(current++) == 'u')\n    {\n      if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair))\n      {\n        unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);\n      }\n      else\n        return false;\n    }\n    else\n      return addError(\"expecting another \\\\u token to begin the second half of \"\n                      \"a unicode surrogate pair\",\n                      token,\n                      current);\n  }\n  return true;\n}\n\nbool Reader::decodeUnicodeEscapeSequence(Token &token,\n                                         Location &current,\n                                         Location end,\n                                         unsigned int &ret_unicode)\n{\n  if (end - current < 4)\n    return addError(\n        \"Bad unicode escape sequence in string: four digits expected.\",\n        token,\n        current);\n  int unicode = 0;\n  for (int index = 0; index < 4; ++index)\n  {\n    Char c = *current++;\n    unicode *= 16;\n    if (c >= '0' && c <= '9')\n      unicode += c - '0';\n    else if (c >= 'a' && c <= 'f')\n      unicode += c - 'a' + 10;\n    else if (c >= 'A' && c <= 'F')\n      unicode += c - 'A' + 10;\n    else\n      return addError(\n          \"Bad unicode escape sequence in string: hexadecimal digit expected.\",\n          token,\n          current);\n  }\n  ret_unicode = static_cast<unsigned int>(unicode);\n  return true;\n}\n\nbool Reader::addError(const JSONCPP_STRING &message, Token &token, Location extra)\n{\n  ErrorInfo info;\n  info.token_ = token;\n  info.message_ = message;\n  info.extra_ = extra;\n  errors_.push_back(info);\n  return false;\n}\n\nbool Reader::recoverFromError(TokenType skipUntilToken)\n{\n  size_t const errorCount = errors_.size();\n  Token skip;\n  for (;;)\n  {\n    if (!readToken(skip))\n      errors_.resize(errorCount); // discard errors caused by recovery\n    if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)\n      break;\n  }\n  errors_.resize(errorCount);\n  return false;\n}\n\nbool Reader::addErrorAndRecover(const JSONCPP_STRING &message,\n                                Token &token,\n                                TokenType skipUntilToken)\n{\n  addError(message, token);\n  return recoverFromError(skipUntilToken);\n}\n\nValue &Reader::currentValue() { return *(nodes_.top()); }\n\nReader::Char Reader::getNextChar()\n{\n  if (current_ == end_)\n    return 0;\n  return *current_++;\n}\n\nvoid Reader::getLocationLineAndColumn(Location location,\n                                      int &line,\n                                      int &column) const\n{\n  Location current = begin_;\n  Location lastLineStart = current;\n  line = 0;\n  while (current < location && current != end_)\n  {\n    Char c = *current++;\n    if (c == '\\r')\n    {\n      if (*current == '\\n')\n        ++current;\n      lastLineStart = current;\n      ++line;\n    }\n    else if (c == '\\n')\n    {\n      lastLineStart = current;\n      ++line;\n    }\n  }\n  // column & line start at 1\n  column = int(location - lastLineStart) + 1;\n  ++line;\n}\n\nJSONCPP_STRING Reader::getLocationLineAndColumn(Location location) const\n{\n  int line, column;\n  getLocationLineAndColumn(location, line, column);\n  char buffer[18 + 16 + 16 + 1];\n  snprintf(buffer, sizeof(buffer), \"Line %d, Column %d\", line, column);\n  return buffer;\n}\n\n// Deprecated. Preserved for backward compatibility\nJSONCPP_STRING Reader::getFormatedErrorMessages() const\n{\n  return getFormattedErrorMessages();\n}\n\nJSONCPP_STRING Reader::getFormattedErrorMessages() const\n{\n  JSONCPP_STRING formattedMessage;\n  for (Errors::const_iterator itError = errors_.begin();\n       itError != errors_.end();\n       ++itError)\n  {\n    const ErrorInfo &error = *itError;\n    formattedMessage +=\n        \"* \" + getLocationLineAndColumn(error.token_.start_) + \"\\n\";\n    formattedMessage += \"  \" + error.message_ + \"\\n\";\n    if (error.extra_)\n      formattedMessage +=\n          \"See \" + getLocationLineAndColumn(error.extra_) + \" for detail.\\n\";\n  }\n  return formattedMessage;\n}\n\nstd::vector<Reader::StructuredError> Reader::getStructuredErrors() const\n{\n  std::vector<Reader::StructuredError> allErrors;\n  for (Errors::const_iterator itError = errors_.begin();\n       itError != errors_.end();\n       ++itError)\n  {\n    const ErrorInfo &error = *itError;\n    Reader::StructuredError structured;\n    structured.offset_start = error.token_.start_ - begin_;\n    structured.offset_limit = error.token_.end_ - begin_;\n    structured.message = error.message_;\n    allErrors.push_back(structured);\n  }\n  return allErrors;\n}\n\nbool Reader::pushError(const Value &value, const JSONCPP_STRING &message)\n{\n  ptrdiff_t const length = end_ - begin_;\n  if (value.getOffsetStart() > length || value.getOffsetLimit() > length)\n    return false;\n  Token token;\n  token.type_ = tokenError;\n  token.start_ = begin_ + value.getOffsetStart();\n  token.end_ = end_ + value.getOffsetLimit();\n  ErrorInfo info;\n  info.token_ = token;\n  info.message_ = message;\n  info.extra_ = 0;\n  errors_.push_back(info);\n  return true;\n}\n\nbool Reader::pushError(const Value &value, const JSONCPP_STRING &message, const Value &extra)\n{\n  ptrdiff_t const length = end_ - begin_;\n  if (value.getOffsetStart() > length || value.getOffsetLimit() > length || extra.getOffsetLimit() > length)\n    return false;\n  Token token;\n  token.type_ = tokenError;\n  token.start_ = begin_ + value.getOffsetStart();\n  token.end_ = begin_ + value.getOffsetLimit();\n  ErrorInfo info;\n  info.token_ = token;\n  info.message_ = message;\n  info.extra_ = begin_ + extra.getOffsetStart();\n  errors_.push_back(info);\n  return true;\n}\n\nbool Reader::good() const\n{\n  return !errors_.size();\n}\n\n// exact copy of Features\nclass OurFeatures\n{\npublic:\n  static OurFeatures all();\n  bool allowComments_;\n  bool strictRoot_;\n  bool allowDroppedNullPlaceholders_;\n  bool allowNumericKeys_;\n  bool allowSingleQuotes_;\n  bool failIfExtra_;\n  bool rejectDupKeys_;\n  bool allowSpecialFloats_;\n  int stackLimit_;\n}; // OurFeatures\n\n// exact copy of Implementation of class Features\n// ////////////////////////////////\n\nOurFeatures OurFeatures::all() { return OurFeatures(); }\n\n// Implementation of class Reader\n// ////////////////////////////////\n\n// exact copy of Reader, renamed to OurReader\nclass OurReader\n{\npublic:\n  typedef char Char;\n  typedef const Char *Location;\n  struct StructuredError\n  {\n    ptrdiff_t offset_start;\n    ptrdiff_t offset_limit;\n    JSONCPP_STRING message;\n  };\n\n  OurReader(OurFeatures const &features);\n  bool parse(const char *beginDoc,\n             const char *endDoc,\n             Value &root,\n             bool collectComments = true);\n  JSONCPP_STRING getFormattedErrorMessages() const;\n  std::vector<StructuredError> getStructuredErrors() const;\n  bool pushError(const Value &value, const JSONCPP_STRING &message);\n  bool pushError(const Value &value, const JSONCPP_STRING &message, const Value &extra);\n  bool good() const;\n\nprivate:\n  OurReader(OurReader const &);      // no impl\n  void operator=(OurReader const &); // no impl\n\n  enum TokenType\n  {\n    tokenEndOfStream = 0,\n    tokenObjectBegin,\n    tokenObjectEnd,\n    tokenArrayBegin,\n    tokenArrayEnd,\n    tokenString,\n    tokenNumber,\n    tokenTrue,\n    tokenFalse,\n    tokenNull,\n    tokenNaN,\n    tokenPosInf,\n    tokenNegInf,\n    tokenArraySeparator,\n    tokenMemberSeparator,\n    tokenComment,\n    tokenError\n  };\n\n  class Token\n  {\n  public:\n    TokenType type_;\n    Location start_;\n    Location end_;\n  };\n\n  class ErrorInfo\n  {\n  public:\n    Token token_;\n    JSONCPP_STRING message_;\n    Location extra_;\n  };\n\n  typedef std::deque<ErrorInfo> Errors;\n\n  bool readToken(Token &token);\n  void skipSpaces();\n  bool match(Location pattern, int patternLength);\n  bool readComment();\n  bool readCStyleComment();\n  bool readCppStyleComment();\n  bool readString();\n  bool readStringSingleQuote();\n  bool readNumber(bool checkInf);\n  bool readValue();\n  bool readObject(Token &token);\n  bool readArray(Token &token);\n  bool decodeNumber(Token &token);\n  bool decodeNumber(Token &token, Value &decoded);\n  bool decodeString(Token &token);\n  bool decodeString(Token &token, JSONCPP_STRING &decoded);\n  bool decodeDouble(Token &token);\n  bool decodeDouble(Token &token, Value &decoded);\n  bool decodeUnicodeCodePoint(Token &token,\n                              Location &current,\n                              Location end,\n                              unsigned int &unicode);\n  bool decodeUnicodeEscapeSequence(Token &token,\n                                   Location &current,\n                                   Location end,\n                                   unsigned int &unicode);\n  bool addError(const JSONCPP_STRING &message, Token &token, Location extra = 0);\n  bool recoverFromError(TokenType skipUntilToken);\n  bool addErrorAndRecover(const JSONCPP_STRING &message,\n                          Token &token,\n                          TokenType skipUntilToken);\n  void skipUntilSpace();\n  Value &currentValue();\n  Char getNextChar();\n  void\n  getLocationLineAndColumn(Location location, int &line, int &column) const;\n  JSONCPP_STRING getLocationLineAndColumn(Location location) const;\n  void addComment(Location begin, Location end, CommentPlacement placement);\n  void skipCommentTokens(Token &token);\n\n  static JSONCPP_STRING normalizeEOL(Location begin, Location end);\n  static bool containsNewLine(Location begin, Location end);\n\n  typedef std::stack<Value *> Nodes;\n  Nodes nodes_;\n  Errors errors_;\n  JSONCPP_STRING document_;\n  Location begin_;\n  Location end_;\n  Location current_;\n  Location lastValueEnd_;\n  Value *lastValue_;\n  JSONCPP_STRING commentsBefore_;\n\n  OurFeatures const features_;\n  bool collectComments_;\n}; // OurReader\n\n// complete copy of Read impl, for OurReader\n\nbool OurReader::containsNewLine(OurReader::Location begin, OurReader::Location end)\n{\n  for (; begin < end; ++begin)\n    if (*begin == '\\n' || *begin == '\\r')\n      return true;\n  return false;\n}\n\nOurReader::OurReader(OurFeatures const &features)\n    : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),\n      lastValue_(), commentsBefore_(),\n      features_(features), collectComments_()\n{\n}\n\nbool OurReader::parse(const char *beginDoc,\n                      const char *endDoc,\n                      Value &root,\n                      bool collectComments)\n{\n  if (!features_.allowComments_)\n  {\n    collectComments = false;\n  }\n\n  begin_ = beginDoc;\n  end_ = endDoc;\n  collectComments_ = collectComments;\n  current_ = begin_;\n  lastValueEnd_ = 0;\n  lastValue_ = 0;\n  commentsBefore_.clear();\n  errors_.clear();\n  while (!nodes_.empty())\n    nodes_.pop();\n  nodes_.push(&root);\n\n  bool successful = readValue();\n  Token token;\n  skipCommentTokens(token);\n  if (features_.failIfExtra_)\n  {\n    if ((features_.strictRoot_ || token.type_ != tokenError) && token.type_ != tokenEndOfStream)\n    {\n      addError(\"Extra non-whitespace after JSON value.\", token);\n      return false;\n    }\n  }\n  if (collectComments_ && !commentsBefore_.empty())\n    root.setComment(commentsBefore_, commentAfter);\n  if (features_.strictRoot_)\n  {\n    if (!root.isArray() && !root.isObject())\n    {\n      // Set error location to start of doc, ideally should be first token found\n      // in doc\n      token.type_ = tokenError;\n      token.start_ = beginDoc;\n      token.end_ = endDoc;\n      addError(\n          \"A valid JSON document must be either an array or an object value.\",\n          token);\n      return false;\n    }\n  }\n  return successful;\n}\n\nbool OurReader::readValue()\n{\n  //  To preserve the old behaviour we cast size_t to int.\n  if (static_cast<int>(nodes_.size()) > features_.stackLimit_)\n    throwRuntimeError(\"Exceeded stackLimit in readValue().\");\n  Token token;\n  skipCommentTokens(token);\n  bool successful = true;\n\n  if (collectComments_ && !commentsBefore_.empty())\n  {\n    currentValue().setComment(commentsBefore_, commentBefore);\n    commentsBefore_.clear();\n  }\n\n  switch (token.type_)\n  {\n  case tokenObjectBegin:\n    successful = readObject(token);\n    currentValue().setOffsetLimit(current_ - begin_);\n    break;\n  case tokenArrayBegin:\n    successful = readArray(token);\n    currentValue().setOffsetLimit(current_ - begin_);\n    break;\n  case tokenNumber:\n    successful = decodeNumber(token);\n    break;\n  case tokenString:\n    successful = decodeString(token);\n    break;\n  case tokenTrue:\n  {\n    Value v(true);\n    currentValue().swapPayload(v);\n    currentValue().setOffsetStart(token.start_ - begin_);\n    currentValue().setOffsetLimit(token.end_ - begin_);\n  }\n  break;\n  case tokenFalse:\n  {\n    Value v(false);\n    currentValue().swapPayload(v);\n    currentValue().setOffsetStart(token.start_ - begin_);\n    currentValue().setOffsetLimit(token.end_ - begin_);\n  }\n  break;\n  case tokenNull:\n  {\n    Value v;\n    currentValue().swapPayload(v);\n    currentValue().setOffsetStart(token.start_ - begin_);\n    currentValue().setOffsetLimit(token.end_ - begin_);\n  }\n  break;\n  case tokenNaN:\n  {\n    Value v(std::numeric_limits<double>::quiet_NaN());\n    currentValue().swapPayload(v);\n    currentValue().setOffsetStart(token.start_ - begin_);\n    currentValue().setOffsetLimit(token.end_ - begin_);\n  }\n  break;\n  case tokenPosInf:\n  {\n    Value v(std::numeric_limits<double>::infinity());\n    currentValue().swapPayload(v);\n    currentValue().setOffsetStart(token.start_ - begin_);\n    currentValue().setOffsetLimit(token.end_ - begin_);\n  }\n  break;\n  case tokenNegInf:\n  {\n    Value v(-std::numeric_limits<double>::infinity());\n    currentValue().swapPayload(v);\n    currentValue().setOffsetStart(token.start_ - begin_);\n    currentValue().setOffsetLimit(token.end_ - begin_);\n  }\n  break;\n  case tokenArraySeparator:\n  case tokenObjectEnd:\n  case tokenArrayEnd:\n    if (features_.allowDroppedNullPlaceholders_)\n    {\n      // \"Un-read\" the current token and mark the current value as a null\n      // token.\n      current_--;\n      Value v;\n      currentValue().swapPayload(v);\n      currentValue().setOffsetStart(current_ - begin_ - 1);\n      currentValue().setOffsetLimit(current_ - begin_);\n      break;\n    } // else, fall through ...\n  default:\n    currentValue().setOffsetStart(token.start_ - begin_);\n    currentValue().setOffsetLimit(token.end_ - begin_);\n    return addError(\"Syntax error: value, object or array expected.\", token);\n  }\n\n  if (collectComments_)\n  {\n    lastValueEnd_ = current_;\n    lastValue_ = &currentValue();\n  }\n\n  return successful;\n}\n\nvoid OurReader::skipCommentTokens(Token &token)\n{\n  if (features_.allowComments_)\n  {\n    do\n    {\n      readToken(token);\n    } while (token.type_ == tokenComment);\n  }\n  else\n  {\n    readToken(token);\n  }\n}\n\nbool OurReader::readToken(Token &token)\n{\n  skipSpaces();\n  token.start_ = current_;\n  Char c = getNextChar();\n  bool ok = true;\n  switch (c)\n  {\n  case '{':\n    token.type_ = tokenObjectBegin;\n    break;\n  case '}':\n    token.type_ = tokenObjectEnd;\n    break;\n  case '[':\n    token.type_ = tokenArrayBegin;\n    break;\n  case ']':\n    token.type_ = tokenArrayEnd;\n    break;\n  case '\"':\n    token.type_ = tokenString;\n    ok = readString();\n    break;\n  case '\\'':\n    if (features_.allowSingleQuotes_)\n    {\n      token.type_ = tokenString;\n      ok = readStringSingleQuote();\n      break;\n    } // else continue\n  case '/':\n    token.type_ = tokenComment;\n    ok = readComment();\n    break;\n  case '0':\n  case '1':\n  case '2':\n  case '3':\n  case '4':\n  case '5':\n  case '6':\n  case '7':\n  case '8':\n  case '9':\n    token.type_ = tokenNumber;\n    readNumber(false);\n    break;\n  case '-':\n    if (readNumber(true))\n    {\n      token.type_ = tokenNumber;\n    }\n    else\n    {\n      token.type_ = tokenNegInf;\n      ok = features_.allowSpecialFloats_ && match(\"nfinity\", 7);\n    }\n    break;\n  case 't':\n    token.type_ = tokenTrue;\n    ok = match(\"rue\", 3);\n    break;\n  case 'f':\n    token.type_ = tokenFalse;\n    ok = match(\"alse\", 4);\n    break;\n  case 'n':\n    token.type_ = tokenNull;\n    ok = match(\"ull\", 3);\n    break;\n  case 'N':\n    if (features_.allowSpecialFloats_)\n    {\n      token.type_ = tokenNaN;\n      ok = match(\"aN\", 2);\n    }\n    else\n    {\n      ok = false;\n    }\n    break;\n  case 'I':\n    if (features_.allowSpecialFloats_)\n    {\n      token.type_ = tokenPosInf;\n      ok = match(\"nfinity\", 7);\n    }\n    else\n    {\n      ok = false;\n    }\n    break;\n  case ',':\n    token.type_ = tokenArraySeparator;\n    break;\n  case ':':\n    token.type_ = tokenMemberSeparator;\n    break;\n  case 0:\n    token.type_ = tokenEndOfStream;\n    break;\n  default:\n    ok = false;\n    break;\n  }\n  if (!ok)\n    token.type_ = tokenError;\n  token.end_ = current_;\n  return true;\n}\n\nvoid OurReader::skipSpaces()\n{\n  while (current_ != end_)\n  {\n    Char c = *current_;\n    if (c == ' ' || c == '\\t' || c == '\\r' || c == '\\n')\n      ++current_;\n    else\n      break;\n  }\n}\n\nbool OurReader::match(Location pattern, int patternLength)\n{\n  if (end_ - current_ < patternLength)\n    return false;\n  int index = patternLength;\n  while (index--)\n    if (current_[index] != pattern[index])\n      return false;\n  current_ += patternLength;\n  return true;\n}\n\nbool OurReader::readComment()\n{\n  Location commentBegin = current_ - 1;\n  Char c = getNextChar();\n  bool successful = false;\n  if (c == '*')\n    successful = readCStyleComment();\n  else if (c == '/')\n    successful = readCppStyleComment();\n  if (!successful)\n    return false;\n\n  if (collectComments_)\n  {\n    CommentPlacement placement = commentBefore;\n    if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin))\n    {\n      if (c != '*' || !containsNewLine(commentBegin, current_))\n        placement = commentAfterOnSameLine;\n    }\n\n    addComment(commentBegin, current_, placement);\n  }\n  return true;\n}\n\nJSONCPP_STRING OurReader::normalizeEOL(OurReader::Location begin, OurReader::Location end)\n{\n  JSONCPP_STRING normalized;\n  normalized.reserve(static_cast<size_t>(end - begin));\n  OurReader::Location current = begin;\n  while (current != end)\n  {\n    char c = *current++;\n    if (c == '\\r')\n    {\n      if (current != end && *current == '\\n')\n        // convert dos EOL\n        ++current;\n      // convert Mac EOL\n      normalized += '\\n';\n    }\n    else\n    {\n      normalized += c;\n    }\n  }\n  return normalized;\n}\n\nvoid OurReader::addComment(Location begin, Location end, CommentPlacement placement)\n{\n  assert(collectComments_);\n  const JSONCPP_STRING &normalized = normalizeEOL(begin, end);\n  if (placement == commentAfterOnSameLine)\n  {\n    assert(lastValue_ != 0);\n    lastValue_->setComment(normalized, placement);\n  }\n  else\n  {\n    commentsBefore_ += normalized;\n  }\n}\n\nbool OurReader::readCStyleComment()\n{\n  while ((current_ + 1) < end_)\n  {\n    Char c = getNextChar();\n    if (c == '*' && *current_ == '/')\n      break;\n  }\n  return getNextChar() == '/';\n}\n\nbool OurReader::readCppStyleComment()\n{\n  while (current_ != end_)\n  {\n    Char c = getNextChar();\n    if (c == '\\n')\n      break;\n    if (c == '\\r')\n    {\n      // Consume DOS EOL. It will be normalized in addComment.\n      if (current_ != end_ && *current_ == '\\n')\n        getNextChar();\n      // Break on Moc OS 9 EOL.\n      break;\n    }\n  }\n  return true;\n}\n\nbool OurReader::readNumber(bool checkInf)\n{\n  const char *p = current_;\n  if (checkInf && p != end_ && *p == 'I')\n  {\n    current_ = ++p;\n    return false;\n  }\n  char c = '0'; // stopgap for already consumed character\n  // integral part\n  while (c >= '0' && c <= '9')\n    c = (current_ = p) < end_ ? *p++ : '\\0';\n  // fractional part\n  if (c == '.')\n  {\n    c = (current_ = p) < end_ ? *p++ : '\\0';\n    while (c >= '0' && c <= '9')\n      c = (current_ = p) < end_ ? *p++ : '\\0';\n  }\n  // exponential part\n  if (c == 'e' || c == 'E')\n  {\n    c = (current_ = p) < end_ ? *p++ : '\\0';\n    if (c == '+' || c == '-')\n      c = (current_ = p) < end_ ? *p++ : '\\0';\n    while (c >= '0' && c <= '9')\n      c = (current_ = p) < end_ ? *p++ : '\\0';\n  }\n  return true;\n}\nbool OurReader::readString()\n{\n  Char c = 0;\n  while (current_ != end_)\n  {\n    c = getNextChar();\n    if (c == '\\\\')\n      getNextChar();\n    else if (c == '\"')\n      break;\n  }\n  return c == '\"';\n}\n\nbool OurReader::readStringSingleQuote()\n{\n  Char c = 0;\n  while (current_ != end_)\n  {\n    c = getNextChar();\n    if (c == '\\\\')\n      getNextChar();\n    else if (c == '\\'')\n      break;\n  }\n  return c == '\\'';\n}\n\nbool OurReader::readObject(Token &tokenStart)\n{\n  Token tokenName;\n  JSONCPP_STRING name;\n  Value init(objectValue);\n  currentValue().swapPayload(init);\n  currentValue().setOffsetStart(tokenStart.start_ - begin_);\n  while (readToken(tokenName))\n  {\n    bool initialTokenOk = true;\n    while (tokenName.type_ == tokenComment && initialTokenOk)\n      initialTokenOk = readToken(tokenName);\n    if (!initialTokenOk)\n      break;\n    if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object\n      return true;\n    name.clear();\n    if (tokenName.type_ == tokenString)\n    {\n      if (!decodeString(tokenName, name))\n        return recoverFromError(tokenObjectEnd);\n    }\n    else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_)\n    {\n      Value numberName;\n      if (!decodeNumber(tokenName, numberName))\n        return recoverFromError(tokenObjectEnd);\n      name = numberName.asString();\n    }\n    else\n    {\n      break;\n    }\n\n    Token colon;\n    if (!readToken(colon) || colon.type_ != tokenMemberSeparator)\n    {\n      return addErrorAndRecover(\n          \"Missing ':' after object member name\", colon, tokenObjectEnd);\n    }\n    if (name.length() >= (1U << 30))\n      throwRuntimeError(\"keylength >= 2^30\");\n    if (features_.rejectDupKeys_ && currentValue().isMember(name))\n    {\n      JSONCPP_STRING msg = \"Duplicate key: '\" + name + \"'\";\n      return addErrorAndRecover(\n          msg, tokenName, tokenObjectEnd);\n    }\n    Value &value = currentValue()[name];\n    nodes_.push(&value);\n    bool ok = readValue();\n    nodes_.pop();\n    if (!ok) // error already set\n      return recoverFromError(tokenObjectEnd);\n\n    Token comma;\n    if (!readToken(comma) ||\n        (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&\n         comma.type_ != tokenComment))\n    {\n      return addErrorAndRecover(\n          \"Missing ',' or '}' in object declaration\", comma, tokenObjectEnd);\n    }\n    bool finalizeTokenOk = true;\n    while (comma.type_ == tokenComment && finalizeTokenOk)\n      finalizeTokenOk = readToken(comma);\n    if (comma.type_ == tokenObjectEnd)\n      return true;\n  }\n  return addErrorAndRecover(\n      \"Missing '}' or object member name\", tokenName, tokenObjectEnd);\n}\n\nbool OurReader::readArray(Token &tokenStart)\n{\n  Value init(arrayValue);\n  currentValue().swapPayload(init);\n  currentValue().setOffsetStart(tokenStart.start_ - begin_);\n  skipSpaces();\n  if (current_ != end_ && *current_ == ']') // empty array\n  {\n    Token endArray;\n    readToken(endArray);\n    return true;\n  }\n  int index = 0;\n  for (;;)\n  {\n    Value &value = currentValue()[index++];\n    nodes_.push(&value);\n    bool ok = readValue();\n    nodes_.pop();\n    if (!ok) // error already set\n      return recoverFromError(tokenArrayEnd);\n\n    Token token;\n    // Accept Comment after last item in the array.\n    ok = readToken(token);\n    while (token.type_ == tokenComment && ok)\n    {\n      ok = readToken(token);\n    }\n    bool badTokenType =\n        (token.type_ != tokenArraySeparator && token.type_ != tokenArrayEnd);\n    if (!ok || badTokenType)\n    {\n      return addErrorAndRecover(\n          \"Missing ',' or ']' in array declaration\", token, tokenArrayEnd);\n    }\n    if (token.type_ == tokenArrayEnd)\n      break;\n  }\n  return true;\n}\n\nbool OurReader::decodeNumber(Token &token)\n{\n  Value decoded;\n  if (!decodeNumber(token, decoded))\n    return false;\n  currentValue().swapPayload(decoded);\n  currentValue().setOffsetStart(token.start_ - begin_);\n  currentValue().setOffsetLimit(token.end_ - begin_);\n  return true;\n}\n\nbool OurReader::decodeNumber(Token &token, Value &decoded)\n{\n  // Attempts to parse the number as an integer. If the number is\n  // larger than the maximum supported value of an integer then\n  // we decode the number as a double.\n  Location current = token.start_;\n  bool isNegative = *current == '-';\n  if (isNegative)\n    ++current;\n  // TODO: Help the compiler do the div and mod at compile time or get rid of them.\n  Value::LargestUInt maxIntegerValue =\n      isNegative ? Value::LargestUInt(-Value::minLargestInt)\n                 : Value::maxLargestUInt;\n  Value::LargestUInt threshold = maxIntegerValue / 10;\n  Value::LargestUInt value = 0;\n  while (current < token.end_)\n  {\n    Char c = *current++;\n    if (c < '0' || c > '9')\n      return decodeDouble(token, decoded);\n    Value::UInt digit(static_cast<Value::UInt>(c - '0'));\n    if (value >= threshold)\n    {\n      // We've hit or exceeded the max value divided by 10 (rounded down). If\n      // a) we've only just touched the limit, b) this is the last digit, and\n      // c) it's small enough to fit in that rounding delta, we're okay.\n      // Otherwise treat this number as a double to avoid overflow.\n      if (value > threshold || current != token.end_ ||\n          digit > maxIntegerValue % 10)\n      {\n        return decodeDouble(token, decoded);\n      }\n    }\n    value = value * 10 + digit;\n  }\n  if (isNegative)\n    decoded = -Value::LargestInt(value);\n  else if (value <= Value::LargestUInt(Value::maxInt))\n    decoded = Value::LargestInt(value);\n  else\n    decoded = value;\n  return true;\n}\n\nbool OurReader::decodeDouble(Token &token)\n{\n  Value decoded;\n  if (!decodeDouble(token, decoded))\n    return false;\n  currentValue().swapPayload(decoded);\n  currentValue().setOffsetStart(token.start_ - begin_);\n  currentValue().setOffsetLimit(token.end_ - begin_);\n  return true;\n}\n\nbool OurReader::decodeDouble(Token &token, Value &decoded)\n{\n  double value = 0;\n  const int bufferSize = 32;\n  int count;\n  ptrdiff_t const length = token.end_ - token.start_;\n\n  // Sanity check to avoid buffer overflow exploits.\n  if (length < 0)\n  {\n    return addError(\"Unable to parse token length\", token);\n  }\n  size_t const ulength = static_cast<size_t>(length);\n\n  // Avoid using a string constant for the format control string given to\n  // sscanf, as this can cause hard to debug crashes on OS X. See here for more\n  // info:\n  //\n  //     http://developer.apple.com/library/mac/#DOCUMENTATION/DeveloperTools/gcc-4.0.1/gcc/Incompatibilities.html\n  char format[] = \"%lf\";\n\n  if (length <= bufferSize)\n  {\n    Char buffer[bufferSize + 1];\n    memcpy(buffer, token.start_, ulength);\n    buffer[length] = 0;\n    fixNumericLocaleInput(buffer, buffer + length);\n    count = sscanf(buffer, format, &value);\n  }\n  else\n  {\n    JSONCPP_STRING buffer(token.start_, token.end_);\n    count = sscanf(buffer.c_str(), format, &value);\n  }\n\n  if (count != 1)\n    return addError(\"'\" + JSONCPP_STRING(token.start_, token.end_) +\n                        \"' is not a number.\",\n                    token);\n  decoded = value;\n  return true;\n}\n\nbool OurReader::decodeString(Token &token)\n{\n  JSONCPP_STRING decoded_string;\n  if (!decodeString(token, decoded_string))\n    return false;\n  Value decoded(decoded_string);\n  currentValue().swapPayload(decoded);\n  currentValue().setOffsetStart(token.start_ - begin_);\n  currentValue().setOffsetLimit(token.end_ - begin_);\n  return true;\n}\n\nbool OurReader::decodeString(Token &token, JSONCPP_STRING &decoded)\n{\n  decoded.reserve(static_cast<size_t>(token.end_ - token.start_ - 2));\n  Location current = token.start_ + 1; // skip '\"'\n  Location end = token.end_ - 1;       // do not include '\"'\n  while (current != end)\n  {\n    Char c = *current++;\n    if (c == '\"')\n      break;\n    else if (c == '\\\\')\n    {\n      if (current == end)\n        return addError(\"Empty escape sequence in string\", token, current);\n      Char escape = *current++;\n      switch (escape)\n      {\n      case '\"':\n        decoded += '\"';\n        break;\n      case '/':\n        decoded += '/';\n        break;\n      case '\\\\':\n        decoded += '\\\\';\n        break;\n      case 'b':\n        decoded += '\\b';\n        break;\n      case 'f':\n        decoded += '\\f';\n        break;\n      case 'n':\n        decoded += '\\n';\n        break;\n      case 'r':\n        decoded += '\\r';\n        break;\n      case 't':\n        decoded += '\\t';\n        break;\n      case 'u':\n      {\n        unsigned int unicode;\n        if (!decodeUnicodeCodePoint(token, current, end, unicode))\n          return false;\n        decoded += codePointToUTF8(unicode);\n      }\n      break;\n      default:\n        return addError(\"Bad escape sequence in string\", token, current);\n      }\n    }\n    else\n    {\n      decoded += c;\n    }\n  }\n  return true;\n}\n\nbool OurReader::decodeUnicodeCodePoint(Token &token,\n                                       Location &current,\n                                       Location end,\n                                       unsigned int &unicode)\n{\n\n  if (!decodeUnicodeEscapeSequence(token, current, end, unicode))\n    return false;\n  if (unicode >= 0xD800 && unicode <= 0xDBFF)\n  {\n    // surrogate pairs\n    if (end - current < 6)\n      return addError(\n          \"additional six characters expected to parse unicode surrogate pair.\",\n          token,\n          current);\n    unsigned int surrogatePair;\n    if (*(current++) == '\\\\' && *(current++) == 'u')\n    {\n      if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair))\n      {\n        unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);\n      }\n      else\n        return false;\n    }\n    else\n      return addError(\"expecting another \\\\u token to begin the second half of \"\n                      \"a unicode surrogate pair\",\n                      token,\n                      current);\n  }\n  return true;\n}\n\nbool OurReader::decodeUnicodeEscapeSequence(Token &token,\n                                            Location &current,\n                                            Location end,\n                                            unsigned int &ret_unicode)\n{\n  if (end - current < 4)\n    return addError(\n        \"Bad unicode escape sequence in string: four digits expected.\",\n        token,\n        current);\n  int unicode = 0;\n  for (int index = 0; index < 4; ++index)\n  {\n    Char c = *current++;\n    unicode *= 16;\n    if (c >= '0' && c <= '9')\n      unicode += c - '0';\n    else if (c >= 'a' && c <= 'f')\n      unicode += c - 'a' + 10;\n    else if (c >= 'A' && c <= 'F')\n      unicode += c - 'A' + 10;\n    else\n      return addError(\n          \"Bad unicode escape sequence in string: hexadecimal digit expected.\",\n          token,\n          current);\n  }\n  ret_unicode = static_cast<unsigned int>(unicode);\n  return true;\n}\n\nbool OurReader::addError(const JSONCPP_STRING &message, Token &token, Location extra)\n{\n  ErrorInfo info;\n  info.token_ = token;\n  info.message_ = message;\n  info.extra_ = extra;\n  errors_.push_back(info);\n  return false;\n}\n\nbool OurReader::recoverFromError(TokenType skipUntilToken)\n{\n  size_t errorCount = errors_.size();\n  Token skip;\n  for (;;)\n  {\n    if (!readToken(skip))\n      errors_.resize(errorCount); // discard errors caused by recovery\n    if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)\n      break;\n  }\n  errors_.resize(errorCount);\n  return false;\n}\n\nbool OurReader::addErrorAndRecover(const JSONCPP_STRING &message,\n                                   Token &token,\n                                   TokenType skipUntilToken)\n{\n  addError(message, token);\n  return recoverFromError(skipUntilToken);\n}\n\nValue &OurReader::currentValue() { return *(nodes_.top()); }\n\nOurReader::Char OurReader::getNextChar()\n{\n  if (current_ == end_)\n    return 0;\n  return *current_++;\n}\n\nvoid OurReader::getLocationLineAndColumn(Location location,\n                                         int &line,\n                                         int &column) const\n{\n  Location current = begin_;\n  Location lastLineStart = current;\n  line = 0;\n  while (current < location && current != end_)\n  {\n    Char c = *current++;\n    if (c == '\\r')\n    {\n      if (*current == '\\n')\n        ++current;\n      lastLineStart = current;\n      ++line;\n    }\n    else if (c == '\\n')\n    {\n      lastLineStart = current;\n      ++line;\n    }\n  }\n  // column & line start at 1\n  column = int(location - lastLineStart) + 1;\n  ++line;\n}\n\nJSONCPP_STRING OurReader::getLocationLineAndColumn(Location location) const\n{\n  int line, column;\n  getLocationLineAndColumn(location, line, column);\n  char buffer[18 + 16 + 16 + 1];\n  snprintf(buffer, sizeof(buffer), \"Line %d, Column %d\", line, column);\n  return buffer;\n}\n\nJSONCPP_STRING OurReader::getFormattedErrorMessages() const\n{\n  JSONCPP_STRING formattedMessage;\n  for (Errors::const_iterator itError = errors_.begin();\n       itError != errors_.end();\n       ++itError)\n  {\n    const ErrorInfo &error = *itError;\n    formattedMessage +=\n        \"* \" + getLocationLineAndColumn(error.token_.start_) + \"\\n\";\n    formattedMessage += \"  \" + error.message_ + \"\\n\";\n    if (error.extra_)\n      formattedMessage +=\n          \"See \" + getLocationLineAndColumn(error.extra_) + \" for detail.\\n\";\n  }\n  return formattedMessage;\n}\n\nstd::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const\n{\n  std::vector<OurReader::StructuredError> allErrors;\n  for (Errors::const_iterator itError = errors_.begin();\n       itError != errors_.end();\n       ++itError)\n  {\n    const ErrorInfo &error = *itError;\n    OurReader::StructuredError structured;\n    structured.offset_start = error.token_.start_ - begin_;\n    structured.offset_limit = error.token_.end_ - begin_;\n    structured.message = error.message_;\n    allErrors.push_back(structured);\n  }\n  return allErrors;\n}\n\nbool OurReader::pushError(const Value &value, const JSONCPP_STRING &message)\n{\n  ptrdiff_t length = end_ - begin_;\n  if (value.getOffsetStart() > length || value.getOffsetLimit() > length)\n    return false;\n  Token token;\n  token.type_ = tokenError;\n  token.start_ = begin_ + value.getOffsetStart();\n  token.end_ = end_ + value.getOffsetLimit();\n  ErrorInfo info;\n  info.token_ = token;\n  info.message_ = message;\n  info.extra_ = 0;\n  errors_.push_back(info);\n  return true;\n}\n\nbool OurReader::pushError(const Value &value, const JSONCPP_STRING &message, const Value &extra)\n{\n  ptrdiff_t length = end_ - begin_;\n  if (value.getOffsetStart() > length || value.getOffsetLimit() > length || extra.getOffsetLimit() > length)\n    return false;\n  Token token;\n  token.type_ = tokenError;\n  token.start_ = begin_ + value.getOffsetStart();\n  token.end_ = begin_ + value.getOffsetLimit();\n  ErrorInfo info;\n  info.token_ = token;\n  info.message_ = message;\n  info.extra_ = begin_ + extra.getOffsetStart();\n  errors_.push_back(info);\n  return true;\n}\n\nbool OurReader::good() const\n{\n  return !errors_.size();\n}\n\nclass OurCharReader : public CharReader\n{\n  bool const collectComments_;\n  OurReader reader_;\n\npublic:\n  OurCharReader(\n      bool collectComments,\n      OurFeatures const &features)\n      : collectComments_(collectComments), reader_(features)\n  {\n  }\n  bool parse(\n      char const *beginDoc, char const *endDoc,\n      Value *root, JSONCPP_STRING *errs) JSONCPP_OVERRIDE\n  {\n    bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_);\n    if (errs)\n    {\n      *errs = reader_.getFormattedErrorMessages();\n    }\n    return ok;\n  }\n};\n\nCharReaderBuilder::CharReaderBuilder()\n{\n  setDefaults(&settings_);\n}\nCharReaderBuilder::~CharReaderBuilder()\n{\n}\nCharReader *CharReaderBuilder::newCharReader() const\n{\n  bool collectComments = settings_[\"collectComments\"].asBool();\n  OurFeatures features = OurFeatures::all();\n  features.allowComments_ = settings_[\"allowComments\"].asBool();\n  features.strictRoot_ = settings_[\"strictRoot\"].asBool();\n  features.allowDroppedNullPlaceholders_ = settings_[\"allowDroppedNullPlaceholders\"].asBool();\n  features.allowNumericKeys_ = settings_[\"allowNumericKeys\"].asBool();\n  features.allowSingleQuotes_ = settings_[\"allowSingleQuotes\"].asBool();\n  features.stackLimit_ = settings_[\"stackLimit\"].asInt();\n  features.failIfExtra_ = settings_[\"failIfExtra\"].asBool();\n  features.rejectDupKeys_ = settings_[\"rejectDupKeys\"].asBool();\n  features.allowSpecialFloats_ = settings_[\"allowSpecialFloats\"].asBool();\n  return new OurCharReader(collectComments, features);\n}\nstatic void getValidReaderKeys(std::set<JSONCPP_STRING> *valid_keys)\n{\n  valid_keys->clear();\n  valid_keys->insert(\"collectComments\");\n  valid_keys->insert(\"allowComments\");\n  valid_keys->insert(\"strictRoot\");\n  valid_keys->insert(\"allowDroppedNullPlaceholders\");\n  valid_keys->insert(\"allowNumericKeys\");\n  valid_keys->insert(\"allowSingleQuotes\");\n  valid_keys->insert(\"stackLimit\");\n  valid_keys->insert(\"failIfExtra\");\n  valid_keys->insert(\"rejectDupKeys\");\n  valid_keys->insert(\"allowSpecialFloats\");\n}\nbool CharReaderBuilder::validate(Json::Value *invalid) const\n{\n  Json::Value my_invalid;\n  if (!invalid)\n    invalid = &my_invalid; // so we do not need to test for NULL\n  Json::Value &inv = *invalid;\n  std::set<JSONCPP_STRING> valid_keys;\n  getValidReaderKeys(&valid_keys);\n  Value::Members keys = settings_.getMemberNames();\n  size_t n = keys.size();\n  for (size_t i = 0; i < n; ++i)\n  {\n    JSONCPP_STRING const &key = keys[i];\n    if (valid_keys.find(key) == valid_keys.end())\n    {\n      inv[key] = settings_[key];\n    }\n  }\n  return 0u == inv.size();\n}\nValue &CharReaderBuilder::operator[](JSONCPP_STRING key)\n{\n  return settings_[key];\n}\n// static\nvoid CharReaderBuilder::strictMode(Json::Value *settings)\n{\n  //! [CharReaderBuilderStrictMode]\n  (*settings)[\"allowComments\"] = false;\n  (*settings)[\"strictRoot\"] = true;\n  (*settings)[\"allowDroppedNullPlaceholders\"] = false;\n  (*settings)[\"allowNumericKeys\"] = false;\n  (*settings)[\"allowSingleQuotes\"] = false;\n  (*settings)[\"stackLimit\"] = 1000;\n  (*settings)[\"failIfExtra\"] = true;\n  (*settings)[\"rejectDupKeys\"] = true;\n  (*settings)[\"allowSpecialFloats\"] = false;\n  //! [CharReaderBuilderStrictMode]\n}\n// static\nvoid CharReaderBuilder::setDefaults(Json::Value *settings)\n{\n  //! [CharReaderBuilderDefaults]\n  (*settings)[\"collectComments\"] = true;\n  (*settings)[\"allowComments\"] = true;\n  (*settings)[\"strictRoot\"] = false;\n  (*settings)[\"allowDroppedNullPlaceholders\"] = false;\n  (*settings)[\"allowNumericKeys\"] = false;\n  (*settings)[\"allowSingleQuotes\"] = false;\n  (*settings)[\"stackLimit\"] = 1000;\n  (*settings)[\"failIfExtra\"] = false;\n  (*settings)[\"rejectDupKeys\"] = false;\n  (*settings)[\"allowSpecialFloats\"] = false;\n  //! [CharReaderBuilderDefaults]\n}\n\n//////////////////////////////////\n// global functions\n\nbool parseFromStream(\n    CharReader::Factory const &fact, JSONCPP_ISTREAM &sin,\n    Value *root, JSONCPP_STRING *errs)\n{\n  JSONCPP_OSTRINGSTREAM ssin;\n  ssin << sin.rdbuf();\n  JSONCPP_STRING doc = ssin.str();\n  char const *begin = doc.data();\n  char const *end = begin + doc.size();\n  // Note that we do not actually need a null-terminator.\n  CharReaderPtr const reader(fact.newCharReader());\n  return reader->parse(begin, end, root, errs);\n}\n\nJSONCPP_ISTREAM &operator>>(JSONCPP_ISTREAM &sin, Value &root)\n{\n  CharReaderBuilder b;\n  JSONCPP_STRING errs;\n  bool ok = parseFromStream(b, sin, &root, &errs);\n  if (!ok)\n  {\n    fprintf(stderr,\n            \"Error from reader: %s\",\n            errs.c_str());\n\n    throwRuntimeError(errs);\n  }\n  return sin;\n}\n\n} // namespace Json\n\n// //////////////////////////////////////////////////////////////////////\n// End of content of file: src/lib_json/json_reader.cpp\n// //////////////////////////////////////////////////////////////////////\n\n// //////////////////////////////////////////////////////////////////////\n// Beginning of content of file: src/lib_json/json_valueiterator.inl\n// //////////////////////////////////////////////////////////////////////\n\n// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors\n// Distributed under MIT license, or public domain if desired and\n// recognized in your jurisdiction.\n// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE\n\n// included by json_value.cpp\n\nnamespace Json\n{\n\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n// class ValueIteratorBase\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n\nValueIteratorBase::ValueIteratorBase()\n    : current_(), isNull_(true)\n{\n}\n\nValueIteratorBase::ValueIteratorBase(\n    const Value::ObjectValues::iterator &current)\n    : current_(current), isNull_(false) {}\n\nValue &ValueIteratorBase::deref() const\n{\n  return current_->second;\n}\n\nvoid ValueIteratorBase::increment()\n{\n  ++current_;\n}\n\nvoid ValueIteratorBase::decrement()\n{\n  --current_;\n}\n\nValueIteratorBase::difference_type\nValueIteratorBase::computeDistance(const SelfType &other) const\n{\n#ifdef JSON_USE_CPPTL_SMALLMAP\n  return other.current_ - current_;\n#else\n  // Iterator for null value are initialized using the default\n  // constructor, which initialize current_ to the default\n  // std::map::iterator. As begin() and end() are two instance\n  // of the default std::map::iterator, they can not be compared.\n  // To allow this, we handle this comparison specifically.\n  if (isNull_ && other.isNull_)\n  {\n    return 0;\n  }\n\n  // Usage of std::distance is not portable (does not compile with Sun Studio 12\n  // RogueWave STL,\n  // which is the one used by default).\n  // Using a portable hand-made version for non random iterator instead:\n  //   return difference_type( std::distance( current_, other.current_ ) );\n  difference_type myDistance = 0;\n  for (Value::ObjectValues::iterator it = current_; it != other.current_;\n       ++it)\n  {\n    ++myDistance;\n  }\n  return myDistance;\n#endif\n}\n\nbool ValueIteratorBase::isEqual(const SelfType &other) const\n{\n  if (isNull_)\n  {\n    return other.isNull_;\n  }\n  return current_ == other.current_;\n}\n\nvoid ValueIteratorBase::copy(const SelfType &other)\n{\n  current_ = other.current_;\n  isNull_ = other.isNull_;\n}\n\nValue ValueIteratorBase::key() const\n{\n  const Value::CZString czstring = (*current_).first;\n  if (czstring.data())\n  {\n    if (czstring.isStaticString())\n      return Value(StaticString(czstring.data()));\n    return Value(czstring.data(), czstring.data() + czstring.length());\n  }\n  return Value(czstring.index());\n}\n\nUInt ValueIteratorBase::index() const\n{\n  const Value::CZString czstring = (*current_).first;\n  if (!czstring.data())\n    return czstring.index();\n  return Value::UInt(-1);\n}\n\nJSONCPP_STRING ValueIteratorBase::name() const\n{\n  char const *keey;\n  char const *end;\n  keey = memberName(&end);\n  if (!keey)\n    return JSONCPP_STRING();\n  return JSONCPP_STRING(keey, end);\n}\n\nchar const *ValueIteratorBase::memberName() const\n{\n  const char *cname = (*current_).first.data();\n  return cname ? cname : \"\";\n}\n\nchar const *ValueIteratorBase::memberName(char const **end) const\n{\n  const char *cname = (*current_).first.data();\n  if (!cname)\n  {\n    *end = NULL;\n    return NULL;\n  }\n  *end = cname + (*current_).first.length();\n  return cname;\n}\n\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n// class ValueConstIterator\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n\nValueConstIterator::ValueConstIterator() {}\n\nValueConstIterator::ValueConstIterator(\n    const Value::ObjectValues::iterator &current)\n    : ValueIteratorBase(current) {}\n\nValueConstIterator::ValueConstIterator(ValueIterator const &other)\n    : ValueIteratorBase(other) {}\n\nValueConstIterator &ValueConstIterator::\noperator=(const ValueIteratorBase &other)\n{\n  copy(other);\n  return *this;\n}\n\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n// class ValueIterator\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n\nValueIterator::ValueIterator() {}\n\nValueIterator::ValueIterator(const Value::ObjectValues::iterator &current)\n    : ValueIteratorBase(current) {}\n\nValueIterator::ValueIterator(const ValueConstIterator &other)\n    : ValueIteratorBase(other)\n{\n  throwRuntimeError(\"ConstIterator to Iterator should never be allowed.\");\n}\n\nValueIterator::ValueIterator(const ValueIterator &other)\n    : ValueIteratorBase(other) {}\n\nValueIterator &ValueIterator::operator=(const SelfType &other)\n{\n  copy(other);\n  return *this;\n}\n\n} // namespace Json\n\n// //////////////////////////////////////////////////////////////////////\n// End of content of file: src/lib_json/json_valueiterator.inl\n// //////////////////////////////////////////////////////////////////////\n\n// //////////////////////////////////////////////////////////////////////\n// Beginning of content of file: src/lib_json/json_value.cpp\n// //////////////////////////////////////////////////////////////////////\n\n// Copyright 2011 Baptiste Lepilleur and The JsonCpp Authors\n// Distributed under MIT license, or public domain if desired and\n// recognized in your jurisdiction.\n// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE\n\n#if !defined(JSON_IS_AMALGAMATION)\n#include <json/assertions.h>\n#include <json/value.h>\n#include <json/writer.h>\n#endif // if !defined(JSON_IS_AMALGAMATION)\n#include <math.h>\n#include <sstream>\n#include <utility>\n#include <cstring>\n#include <cassert>\n#ifdef JSON_USE_CPPTL\n#include <cpptl/conststring.h>\n#endif\n#include <cstddef>   // size_t\n#include <algorithm> // min()\n\n#define JSON_ASSERT_UNREACHABLE assert(false)\n\nnamespace Json\n{\n\n// This is a walkaround to avoid the static initialization of Value::null.\n// kNull must be word-aligned to avoid crashing on ARM.  We use an alignment of\n// 8 (instead of 4) as a bit of future-proofing.\n#if defined(__ARMEL__)\n#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))\n#else\n#define ALIGNAS(byte_alignment)\n#endif\n//static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 };\n//const unsigned char& kNullRef = kNull[0];\n//const Value& Value::null = reinterpret_cast<const Value&>(kNullRef);\n//const Value& Value::nullRef = null;\n\n// static\nValue const &Value::nullSingleton()\n{\n  static Value const nullStatic;\n  return nullStatic;\n}\n\n// for backwards compatibility, we'll leave these global references around, but DO NOT\n// use them in JSONCPP library code any more!\nValue const &Value::null = Value::nullSingleton();\nValue const &Value::nullRef = Value::nullSingleton();\n\nconst Int Value::minInt = Int(~(UInt(-1) / 2));\nconst Int Value::maxInt = Int(UInt(-1) / 2);\nconst UInt Value::maxUInt = UInt(-1);\n#if defined(JSON_HAS_INT64)\nconst Int64 Value::minInt64 = Int64(~(UInt64(-1) / 2));\nconst Int64 Value::maxInt64 = Int64(UInt64(-1) / 2);\nconst UInt64 Value::maxUInt64 = UInt64(-1);\n// The constant is hard-coded because some compiler have trouble\n// converting Value::maxUInt64 to a double correctly (AIX/xlC).\n// Assumes that UInt64 is a 64 bits integer.\nstatic const double maxUInt64AsDouble = 18446744073709551615.0;\n#endif // defined(JSON_HAS_INT64)\nconst LargestInt Value::minLargestInt = LargestInt(~(LargestUInt(-1) / 2));\nconst LargestInt Value::maxLargestInt = LargestInt(LargestUInt(-1) / 2);\nconst LargestUInt Value::maxLargestUInt = LargestUInt(-1);\n\n#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)\ntemplate <typename T, typename U>\nstatic inline bool InRange(double d, T min, U max)\n{\n  // The casts can lose precision, but we are looking only for\n  // an approximate range. Might fail on edge cases though. ~cdunn\n  //return d >= static_cast<double>(min) && d <= static_cast<double>(max);\n  return d >= min && d <= max;\n}\n#else  // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)\nstatic inline double integerToDouble(Json::UInt64 value)\n{\n  return static_cast<double>(Int64(value / 2)) * 2.0 + static_cast<double>(Int64(value & 1));\n}\n\ntemplate <typename T>\nstatic inline double integerToDouble(T value)\n{\n  return static_cast<double>(value);\n}\n\ntemplate <typename T, typename U>\nstatic inline bool InRange(double d, T min, U max)\n{\n  return d >= integerToDouble(min) && d <= integerToDouble(max);\n}\n#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)\n\n/** Duplicates the specified string value.\n * @param value Pointer to the string to duplicate. Must be zero-terminated if\n *              length is \"unknown\".\n * @param length Length of the value. if equals to unknown, then it will be\n *               computed using strlen(value).\n * @return Pointer on the duplicate instance of string.\n */\nstatic inline char *duplicateStringValue(const char *value,\n                                         size_t length)\n{\n  // Avoid an integer overflow in the call to malloc below by limiting length\n  // to a sane value.\n  if (length >= static_cast<size_t>(Value::maxInt))\n    length = Value::maxInt - 1;\n\n  char *newString = static_cast<char *>(malloc(length + 1));\n  if (newString == NULL)\n  {\n    throwRuntimeError(\n        \"in Json::Value::duplicateStringValue(): \"\n        \"Failed to allocate string value buffer\");\n  }\n  memcpy(newString, value, length);\n  newString[length] = 0;\n  return newString;\n}\n\n/* Record the length as a prefix.\n */\nstatic inline char *duplicateAndPrefixStringValue(\n    const char *value,\n    unsigned int length)\n{\n  // Avoid an integer overflow in the call to malloc below by limiting length\n  // to a sane value.\n  JSON_ASSERT_MESSAGE(length <= static_cast<unsigned>(Value::maxInt) - sizeof(unsigned) - 1U,\n                      \"in Json::Value::duplicateAndPrefixStringValue(): \"\n                      \"length too big for prefixing\");\n  unsigned actualLength = length + static_cast<unsigned>(sizeof(unsigned)) + 1U;\n  char *newString = static_cast<char *>(malloc(actualLength));\n  if (newString == 0)\n  {\n    throwRuntimeError(\n        \"in Json::Value::duplicateAndPrefixStringValue(): \"\n        \"Failed to allocate string value buffer\");\n  }\n  *reinterpret_cast<unsigned *>(newString) = length;\n  memcpy(newString + sizeof(unsigned), value, length);\n  newString[actualLength - 1U] = 0; // to avoid buffer over-run accidents by users later\n  return newString;\n}\ninline static void decodePrefixedString(\n    bool isPrefixed, char const *prefixed,\n    unsigned *length, char const **value)\n{\n  if (!isPrefixed)\n  {\n    *length = static_cast<unsigned>(strlen(prefixed));\n    *value = prefixed;\n  }\n  else\n  {\n    *length = *reinterpret_cast<unsigned const *>(prefixed);\n    *value = prefixed + sizeof(unsigned);\n  }\n}\n/** Free the string duplicated by duplicateStringValue()/duplicateAndPrefixStringValue().\n */\n#if JSONCPP_USING_SECURE_MEMORY\nstatic inline void releasePrefixedStringValue(char *value)\n{\n  unsigned length = 0;\n  char const *valueDecoded;\n  decodePrefixedString(true, value, &length, &valueDecoded);\n  size_t const size = sizeof(unsigned) + length + 1U;\n  memset(value, 0, size);\n  free(value);\n}\nstatic inline void releaseStringValue(char *value, unsigned length)\n{\n  // length==0 => we allocated the strings memory\n  size_t size = (length == 0) ? strlen(value) : length;\n  memset(value, 0, size);\n  free(value);\n}\n#else  // !JSONCPP_USING_SECURE_MEMORY\nstatic inline void releasePrefixedStringValue(char *value)\n{\n  free(value);\n}\nstatic inline void releaseStringValue(char *value, unsigned)\n{\n  free(value);\n}\n#endif // JSONCPP_USING_SECURE_MEMORY\n\n} // namespace Json\n\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n// ValueInternals...\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n#if !defined(JSON_IS_AMALGAMATION)\n\n#include \"json_valueiterator.inl\"\n#endif // if !defined(JSON_IS_AMALGAMATION)\n\nnamespace Json\n{\n\nException::Exception(JSONCPP_STRING const &msg)\n    : msg_(msg)\n{\n}\nException::~Exception() JSONCPP_NOEXCEPT\n{\n}\nchar const *Exception::what() const JSONCPP_NOEXCEPT\n{\n  return msg_.c_str();\n}\nRuntimeError::RuntimeError(JSONCPP_STRING const &msg)\n    : Exception(msg)\n{\n}\nLogicError::LogicError(JSONCPP_STRING const &msg)\n    : Exception(msg)\n{\n}\nJSONCPP_NORETURN void throwRuntimeError(JSONCPP_STRING const &msg)\n{\n  throw RuntimeError(msg);\n}\nJSONCPP_NORETURN void throwLogicError(JSONCPP_STRING const &msg)\n{\n  throw LogicError(msg);\n}\n\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n// class Value::CommentInfo\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n\nValue::CommentInfo::CommentInfo() : comment_(0)\n{\n}\n\nValue::CommentInfo::~CommentInfo()\n{\n  if (comment_)\n    releaseStringValue(comment_, 0u);\n}\n\nvoid Value::CommentInfo::setComment(const char *text, size_t len)\n{\n  if (comment_)\n  {\n    releaseStringValue(comment_, 0u);\n    comment_ = 0;\n  }\n  JSON_ASSERT(text != 0);\n  JSON_ASSERT_MESSAGE(\n      text[0] == '\\0' || text[0] == '/',\n      \"in Json::Value::setComment(): Comments must start with /\");\n  // It seems that /**/ style comments are acceptable as well.\n  comment_ = duplicateStringValue(text, len);\n}\n\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n// class Value::CZString\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n\n// Notes: policy_ indicates if the string was allocated when\n// a string is stored.\n\nValue::CZString::CZString(ArrayIndex aindex) : cstr_(0), index_(aindex) {}\n\nValue::CZString::CZString(char const *str, unsigned ulength, DuplicationPolicy allocate)\n    : cstr_(str)\n{\n  // allocate != duplicate\n  storage_.policy_ = allocate & 0x3;\n  storage_.length_ = ulength & 0x3FFFFFFF;\n}\n\nValue::CZString::CZString(const CZString &other)\n{\n  cstr_ = (other.storage_.policy_ != noDuplication && other.cstr_ != 0\n               ? duplicateStringValue(other.cstr_, other.storage_.length_)\n               : other.cstr_);\n  storage_.policy_ = static_cast<unsigned>(other.cstr_\n                                               ? (static_cast<DuplicationPolicy>(other.storage_.policy_) == noDuplication\n                                                      ? noDuplication\n                                                      : duplicate)\n                                               : static_cast<DuplicationPolicy>(other.storage_.policy_)) &\n                     3U;\n  storage_.length_ = other.storage_.length_;\n}\n\n#if JSON_HAS_RVALUE_REFERENCES\nValue::CZString::CZString(CZString &&other)\n    : cstr_(other.cstr_), index_(other.index_)\n{\n  other.cstr_ = nullptr;\n}\n#endif\n\nValue::CZString::~CZString()\n{\n  if (cstr_ && storage_.policy_ == duplicate)\n  {\n    releaseStringValue(const_cast<char *>(cstr_), storage_.length_ + 1u); //+1 for null terminating character for sake of completeness but not actually necessary\n  }\n}\n\nvoid Value::CZString::swap(CZString &other)\n{\n  std::swap(cstr_, other.cstr_);\n  std::swap(index_, other.index_);\n}\n\nValue::CZString &Value::CZString::operator=(const CZString &other)\n{\n  cstr_ = other.cstr_;\n  index_ = other.index_;\n  return *this;\n}\n\n#if JSON_HAS_RVALUE_REFERENCES\nValue::CZString &Value::CZString::operator=(CZString &&other)\n{\n  cstr_ = other.cstr_;\n  index_ = other.index_;\n  other.cstr_ = nullptr;\n  return *this;\n}\n#endif\n\nbool Value::CZString::operator<(const CZString &other) const\n{\n  if (!cstr_)\n    return index_ < other.index_;\n  //return strcmp(cstr_, other.cstr_) < 0;\n  // Assume both are strings.\n  unsigned this_len = this->storage_.length_;\n  unsigned other_len = other.storage_.length_;\n  unsigned min_len = std::min<unsigned>(this_len, other_len);\n  JSON_ASSERT(this->cstr_ && other.cstr_);\n  int comp = memcmp(this->cstr_, other.cstr_, min_len);\n  if (comp < 0)\n    return true;\n  if (comp > 0)\n    return false;\n  return (this_len < other_len);\n}\n\nbool Value::CZString::operator==(const CZString &other) const\n{\n  if (!cstr_)\n    return index_ == other.index_;\n  //return strcmp(cstr_, other.cstr_) == 0;\n  // Assume both are strings.\n  unsigned this_len = this->storage_.length_;\n  unsigned other_len = other.storage_.length_;\n  if (this_len != other_len)\n    return false;\n  JSON_ASSERT(this->cstr_ && other.cstr_);\n  int comp = memcmp(this->cstr_, other.cstr_, this_len);\n  return comp == 0;\n}\n\nArrayIndex Value::CZString::index() const { return index_; }\n\n//const char* Value::CZString::c_str() const { return cstr_; }\nconst char *Value::CZString::data() const { return cstr_; }\nunsigned Value::CZString::length() const { return storage_.length_; }\nbool Value::CZString::isStaticString() const { return storage_.policy_ == noDuplication; }\n\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n// class Value::Value\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n// //////////////////////////////////////////////////////////////////\n\n/*! \\internal Default constructor initialization must be equivalent to:\n * memset( this, 0, sizeof(Value) )\n * This optimization is used in ValueInternalMap fast allocator.\n */\nValue::Value(ValueType vtype)\n{\n  static char const emptyString[] = \"\";\n  initBasic(vtype);\n  switch (vtype)\n  {\n  case nullValue:\n    break;\n  case intValue:\n  case uintValue:\n    value_.int_ = 0;\n    break;\n  case realValue:\n    value_.real_ = 0.0;\n    break;\n  case stringValue:\n    // allocated_ == false, so this is safe.\n    value_.string_ = const_cast<char *>(static_cast<char const *>(emptyString));\n    break;\n  case arrayValue:\n  case objectValue:\n    value_.map_ = new ObjectValues();\n    break;\n  case booleanValue:\n    value_.bool_ = false;\n    break;\n  default:\n    JSON_ASSERT_UNREACHABLE;\n  }\n}\n\nValue::Value(Int value)\n{\n  initBasic(intValue);\n  value_.int_ = value;\n}\n\nValue::Value(UInt value)\n{\n  initBasic(uintValue);\n  value_.uint_ = value;\n}\n#if defined(JSON_HAS_INT64)\nValue::Value(Int64 value)\n{\n  initBasic(intValue);\n  value_.int_ = value;\n}\nValue::Value(UInt64 value)\n{\n  initBasic(uintValue);\n  value_.uint_ = value;\n}\n#endif // defined(JSON_HAS_INT64)\n\nValue::Value(double value)\n{\n  initBasic(realValue);\n  value_.real_ = value;\n}\n\nValue::Value(const char *value)\n{\n  initBasic(stringValue, true);\n  JSON_ASSERT_MESSAGE(value != NULL, \"Null Value Passed to Value Constructor\");\n  value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(strlen(value)));\n}\n\nValue::Value(const char *beginValue, const char *endValue)\n{\n  initBasic(stringValue, true);\n  value_.string_ =\n      duplicateAndPrefixStringValue(beginValue, static_cast<unsigned>(endValue - beginValue));\n}\n\nValue::Value(const JSONCPP_STRING &value)\n{\n  initBasic(stringValue, true);\n  value_.string_ =\n      duplicateAndPrefixStringValue(value.data(), static_cast<unsigned>(value.length()));\n}\n\nValue::Value(const StaticString &value)\n{\n  initBasic(stringValue);\n  value_.string_ = const_cast<char *>(value.c_str());\n}\n\n#ifdef JSON_USE_CPPTL\nValue::Value(const CppTL::ConstString &value)\n{\n  initBasic(stringValue, true);\n  value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(value.length()));\n}\n#endif\n\nValue::Value(bool value)\n{\n  initBasic(booleanValue);\n  value_.bool_ = value;\n}\n\nValue::Value(Value const &other)\n    : type_(other.type_), allocated_(false),\n      comments_(0), start_(other.start_), limit_(other.limit_)\n{\n  switch (type_)\n  {\n  case nullValue:\n  case intValue:\n  case uintValue:\n  case realValue:\n  case booleanValue:\n    value_ = other.value_;\n    break;\n  case stringValue:\n    if (other.value_.string_ && other.allocated_)\n    {\n      unsigned len;\n      char const *str;\n      decodePrefixedString(other.allocated_, other.value_.string_,\n                           &len, &str);\n      value_.string_ = duplicateAndPrefixStringValue(str, len);\n      allocated_ = true;\n    }\n    else\n    {\n      value_.string_ = other.value_.string_;\n      allocated_ = false;\n    }\n    break;\n  case arrayValue:\n  case objectValue:\n    value_.map_ = new ObjectValues(*other.value_.map_);\n    break;\n  default:\n    JSON_ASSERT_UNREACHABLE;\n  }\n  if (other.comments_)\n  {\n    comments_ = new CommentInfo[numberOfCommentPlacement];\n    for (int comment = 0; comment < numberOfCommentPlacement; ++comment)\n    {\n      const CommentInfo &otherComment = other.comments_[comment];\n      if (otherComment.comment_)\n        comments_[comment].setComment(\n            otherComment.comment_, strlen(otherComment.comment_));\n    }\n  }\n}\n\n#if JSON_HAS_RVALUE_REFERENCES\n// Move constructor\nValue::Value(Value &&other)\n{\n  initBasic(nullValue);\n  swap(other);\n}\n#endif\n\nValue::~Value()\n{\n  switch (type_)\n  {\n  case nullValue:\n  case intValue:\n  case uintValue:\n  case realValue:\n  case booleanValue:\n    break;\n  case stringValue:\n    if (allocated_)\n      releasePrefixedStringValue(value_.string_);\n    break;\n  case arrayValue:\n  case objectValue:\n    delete value_.map_;\n    break;\n  default:\n    JSON_ASSERT_UNREACHABLE;\n  }\n\n  delete[] comments_;\n\n  value_.uint_ = 0;\n}\n\nValue &Value::operator=(Value other)\n{\n  swap(other);\n  return *this;\n}\n\nvoid Value::swapPayload(Value &other)\n{\n  ValueType temp = type_;\n  type_ = other.type_;\n  other.type_ = temp;\n  std::swap(value_, other.value_);\n  int temp2 = allocated_;\n  allocated_ = other.allocated_;\n  other.allocated_ = temp2 & 0x1;\n}\n\nvoid Value::copyPayload(const Value &other)\n{\n  type_ = other.type_;\n  value_ = other.value_;\n  allocated_ = other.allocated_;\n}\n\nvoid Value::swap(Value &other)\n{\n  swapPayload(other);\n  std::swap(comments_, other.comments_);\n  std::swap(start_, other.start_);\n  std::swap(limit_, other.limit_);\n}\n\nvoid Value::copy(const Value &other)\n{\n  copyPayload(other);\n  comments_ = other.comments_;\n  start_ = other.start_;\n  limit_ = other.limit_;\n}\n\nValueType Value::type() const { return type_; }\n\nint Value::compare(const Value &other) const\n{\n  if (*this < other)\n    return -1;\n  if (*this > other)\n    return 1;\n  return 0;\n}\n\nbool Value::operator<(const Value &other) const\n{\n  int typeDelta = type_ - other.type_;\n  if (typeDelta)\n    return typeDelta < 0 ? true : false;\n  switch (type_)\n  {\n  case nullValue:\n    return false;\n  case intValue:\n    return value_.int_ < other.value_.int_;\n  case uintValue:\n    return value_.uint_ < other.value_.uint_;\n  case realValue:\n    return value_.real_ < other.value_.real_;\n  case booleanValue:\n    return value_.bool_ < other.value_.bool_;\n  case stringValue:\n  {\n    if ((value_.string_ == 0) || (other.value_.string_ == 0))\n    {\n      if (other.value_.string_)\n        return true;\n      else\n        return false;\n    }\n    unsigned this_len;\n    unsigned other_len;\n    char const *this_str;\n    char const *other_str;\n    decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);\n    decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str);\n    unsigned min_len = std::min<unsigned>(this_len, other_len);\n    JSON_ASSERT(this_str && other_str);\n    int comp = memcmp(this_str, other_str, min_len);\n    if (comp < 0)\n      return true;\n    if (comp > 0)\n      return false;\n    return (this_len < other_len);\n  }\n  case arrayValue:\n  case objectValue:\n  {\n    int delta = int(value_.map_->size() - other.value_.map_->size());\n    if (delta)\n      return delta < 0;\n    return (*value_.map_) < (*other.value_.map_);\n  }\n  default:\n    JSON_ASSERT_UNREACHABLE;\n  }\n  return false; // unreachable\n}\n\nbool Value::operator<=(const Value &other) const { return !(other < *this); }\n\nbool Value::operator>=(const Value &other) const { return !(*this < other); }\n\nbool Value::operator>(const Value &other) const { return other < *this; }\n\nbool Value::operator==(const Value &other) const\n{\n  // if ( type_ != other.type_ )\n  // GCC 2.95.3 says:\n  // attempt to take address of bit-field structure member `Json::Value::type_'\n  // Beats me, but a temp solves the problem.\n  int temp = other.type_;\n  if (type_ != temp)\n    return false;\n  switch (type_)\n  {\n  case nullValue:\n    return true;\n  case intValue:\n    return value_.int_ == other.value_.int_;\n  case uintValue:\n    return value_.uint_ == other.value_.uint_;\n  case realValue:\n    return value_.real_ == other.value_.real_;\n  case booleanValue:\n    return value_.bool_ == other.value_.bool_;\n  case stringValue:\n  {\n    if ((value_.string_ == 0) || (other.value_.string_ == 0))\n    {\n      return (value_.string_ == other.value_.string_);\n    }\n    unsigned this_len;\n    unsigned other_len;\n    char const *this_str;\n    char const *other_str;\n    decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);\n    decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str);\n    if (this_len != other_len)\n      return false;\n    JSON_ASSERT(this_str && other_str);\n    int comp = memcmp(this_str, other_str, this_len);\n    return comp == 0;\n  }\n  case arrayValue:\n  case objectValue:\n    return value_.map_->size() == other.value_.map_->size() &&\n           (*value_.map_) == (*other.value_.map_);\n  default:\n    JSON_ASSERT_UNREACHABLE;\n  }\n  return false; // unreachable\n}\n\nbool Value::operator!=(const Value &other) const { return !(*this == other); }\n\nconst char *Value::asCString() const\n{\n  JSON_ASSERT_MESSAGE(type_ == stringValue,\n                      \"in Json::Value::asCString(): requires stringValue\");\n  if (value_.string_ == 0)\n    return 0;\n  unsigned this_len;\n  char const *this_str;\n  decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);\n  return this_str;\n}\n\n#if JSONCPP_USING_SECURE_MEMORY\nunsigned Value::getCStringLength() const\n{\n  JSON_ASSERT_MESSAGE(type_ == stringValue,\n                      \"in Json::Value::asCString(): requires stringValue\");\n  if (value_.string_ == 0)\n    return 0;\n  unsigned this_len;\n  char const *this_str;\n  decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);\n  return this_len;\n}\n#endif\n\nbool Value::getString(char const **str, char const **cend) const\n{\n  if (type_ != stringValue)\n    return false;\n  if (value_.string_ == 0)\n    return false;\n  unsigned length;\n  decodePrefixedString(this->allocated_, this->value_.string_, &length, str);\n  *cend = *str + length;\n  return true;\n}\n\nJSONCPP_STRING Value::asString() const\n{\n  switch (type_)\n  {\n  case nullValue:\n    return \"\";\n  case stringValue:\n  {\n    if (value_.string_ == 0)\n      return \"\";\n    unsigned this_len;\n    char const *this_str;\n    decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);\n    return JSONCPP_STRING(this_str, this_len);\n  }\n  case booleanValue:\n    return value_.bool_ ? \"true\" : \"false\";\n  case intValue:\n    return valueToString(value_.int_);\n  case uintValue:\n    return valueToString(value_.uint_);\n  case realValue:\n    return valueToString(value_.real_);\n  default:\n    JSON_FAIL_MESSAGE(\"Type is not convertible to string\");\n  }\n}\n\n#ifdef JSON_USE_CPPTL\nCppTL::ConstString Value::asConstString() const\n{\n  unsigned len;\n  char const *str;\n  decodePrefixedString(allocated_, value_.string_,\n                       &len, &str);\n  return CppTL::ConstString(str, len);\n}\n#endif\n\nValue::Int Value::asInt() const\n{\n  switch (type_)\n  {\n  case intValue:\n    JSON_ASSERT_MESSAGE(isInt(), \"LargestInt out of Int range\");\n    return Int(value_.int_);\n  case uintValue:\n    JSON_ASSERT_MESSAGE(isInt(), \"LargestUInt out of Int range\");\n    return Int(value_.uint_);\n  case realValue:\n    JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt),\n                        \"double out of Int range\");\n    return Int(value_.real_);\n  case nullValue:\n    return 0;\n  case booleanValue:\n    return value_.bool_ ? 1 : 0;\n  default:\n    break;\n  }\n  JSON_FAIL_MESSAGE(\"Value is not convertible to Int.\");\n}\n\nValue::UInt Value::asUInt() const\n{\n  switch (type_)\n  {\n  case intValue:\n    JSON_ASSERT_MESSAGE(isUInt(), \"LargestInt out of UInt range\");\n    return UInt(value_.int_);\n  case uintValue:\n    JSON_ASSERT_MESSAGE(isUInt(), \"LargestUInt out of UInt range\");\n    return UInt(value_.uint_);\n  case realValue:\n    JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt),\n                        \"double out of UInt range\");\n    return UInt(value_.real_);\n  case nullValue:\n    return 0;\n  case booleanValue:\n    return value_.bool_ ? 1 : 0;\n  default:\n    break;\n  }\n  JSON_FAIL_MESSAGE(\"Value is not convertible to UInt.\");\n}\n\n#if defined(JSON_HAS_INT64)\n\nValue::Int64 Value::asInt64() const\n{\n  switch (type_)\n  {\n  case intValue:\n    return Int64(value_.int_);\n  case uintValue:\n    JSON_ASSERT_MESSAGE(isInt64(), \"LargestUInt out of Int64 range\");\n    return Int64(value_.uint_);\n  case realValue:\n    JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64),\n                        \"double out of Int64 range\");\n    return Int64(value_.real_);\n  case nullValue:\n    return 0;\n  case booleanValue:\n    return value_.bool_ ? 1 : 0;\n  default:\n    break;\n  }\n  JSON_FAIL_MESSAGE(\"Value is not convertible to Int64.\");\n}\n\nValue::UInt64 Value::asUInt64() const\n{\n  switch (type_)\n  {\n  case intValue:\n    JSON_ASSERT_MESSAGE(isUInt64(), \"LargestInt out of UInt64 range\");\n    return UInt64(value_.int_);\n  case uintValue:\n    return UInt64(value_.uint_);\n  case realValue:\n    JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64),\n                        \"double out of UInt64 range\");\n    return UInt64(value_.real_);\n  case nullValue:\n    return 0;\n  case booleanValue:\n    return value_.bool_ ? 1 : 0;\n  default:\n    break;\n  }\n  JSON_FAIL_MESSAGE(\"Value is not convertible to UInt64.\");\n}\n#endif // if defined(JSON_HAS_INT64)\n\nLargestInt Value::asLargestInt() const\n{\n#if defined(JSON_NO_INT64)\n  return asInt();\n#else\n  return asInt64();\n#endif\n}\n\nLargestUInt Value::asLargestUInt() const\n{\n#if defined(JSON_NO_INT64)\n  return asUInt();\n#else\n  return asUInt64();\n#endif\n}\n\ndouble Value::asDouble() const\n{\n  switch (type_)\n  {\n  case intValue:\n    return static_cast<double>(value_.int_);\n  case uintValue:\n#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)\n    return static_cast<double>(value_.uint_);\n#else  // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)\n    return integerToDouble(value_.uint_);\n#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)\n  case realValue:\n    return value_.real_;\n  case nullValue:\n    return 0.0;\n  case booleanValue:\n    return value_.bool_ ? 1.0 : 0.0;\n  default:\n    break;\n  }\n  JSON_FAIL_MESSAGE(\"Value is not convertible to double.\");\n}\n\nfloat Value::asFloat() const\n{\n  switch (type_)\n  {\n  case intValue:\n    return static_cast<float>(value_.int_);\n  case uintValue:\n#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)\n    return static_cast<float>(value_.uint_);\n#else  // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)\n    // This can fail (silently?) if the value is bigger than MAX_FLOAT.\n    return static_cast<float>(integerToDouble(value_.uint_));\n#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)\n  case realValue:\n    return static_cast<float>(value_.real_);\n  case nullValue:\n    return 0.0;\n  case booleanValue:\n    return value_.bool_ ? 1.0f : 0.0f;\n  default:\n    break;\n  }\n  JSON_FAIL_MESSAGE(\"Value is not convertible to float.\");\n}\n\nbool Value::asBool() const\n{\n  switch (type_)\n  {\n  case booleanValue:\n    return value_.bool_;\n  case nullValue:\n    return false;\n  case intValue:\n    return value_.int_ ? true : false;\n  case uintValue:\n    return value_.uint_ ? true : false;\n  case realValue:\n    // This is kind of strange. Not recommended.\n    return (value_.real_ != 0.0) ? true : false;\n  default:\n    break;\n  }\n  JSON_FAIL_MESSAGE(\"Value is not convertible to bool.\");\n}\n\nbool Value::isConvertibleTo(ValueType other) const\n{\n  switch (other)\n  {\n  case nullValue:\n    return (isNumeric() && asDouble() == 0.0) ||\n           (type_ == booleanValue && value_.bool_ == false) ||\n           (type_ == stringValue && asString().empty()) ||\n           (type_ == arrayValue && value_.map_->size() == 0) ||\n           (type_ == objectValue && value_.map_->size() == 0) ||\n           type_ == nullValue;\n  case intValue:\n    return isInt() ||\n           (type_ == realValue && InRange(value_.real_, minInt, maxInt)) ||\n           type_ == booleanValue || type_ == nullValue;\n  case uintValue:\n    return isUInt() ||\n           (type_ == realValue && InRange(value_.real_, 0, maxUInt)) ||\n           type_ == booleanValue || type_ == nullValue;\n  case realValue:\n    return isNumeric() || type_ == booleanValue || type_ == nullValue;\n  case booleanValue:\n    return isNumeric() || type_ == booleanValue || type_ == nullValue;\n  case stringValue:\n    return isNumeric() || type_ == booleanValue || type_ == stringValue ||\n           type_ == nullValue;\n  case arrayValue:\n    return type_ == arrayValue || type_ == nullValue;\n  case objectValue:\n    return type_ == objectValue || type_ == nullValue;\n  }\n  JSON_ASSERT_UNREACHABLE;\n  return false;\n}\n\n/// Number of values in array or object\nArrayIndex Value::size() const\n{\n  switch (type_)\n  {\n  case nullValue:\n  case intValue:\n  case uintValue:\n  case realValue:\n  case booleanValue:\n  case stringValue:\n    return 0;\n  case arrayValue: // size of the array is highest index + 1\n    if (!value_.map_->empty())\n    {\n      ObjectValues::const_iterator itLast = value_.map_->end();\n      --itLast;\n      return (*itLast).first.index() + 1;\n    }\n    return 0;\n  case objectValue:\n    return ArrayIndex(value_.map_->size());\n  }\n  JSON_ASSERT_UNREACHABLE;\n  return 0; // unreachable;\n}\n\nbool Value::empty() const\n{\n  if (isNull() || isArray() || isObject())\n    return size() == 0u;\n  else\n    return false;\n}\n\nbool Value::operator!() const { return isNull(); }\n\nvoid Value::clear()\n{\n  JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue ||\n                          type_ == objectValue,\n                      \"in Json::Value::clear(): requires complex value\");\n  start_ = 0;\n  limit_ = 0;\n  switch (type_)\n  {\n  case arrayValue:\n  case objectValue:\n    value_.map_->clear();\n    break;\n  default:\n    break;\n  }\n}\n\nvoid Value::resize(ArrayIndex newSize)\n{\n  JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == arrayValue,\n                      \"in Json::Value::resize(): requires arrayValue\");\n  if (type_ == nullValue)\n    *this = Value(arrayValue);\n  ArrayIndex oldSize = size();\n  if (newSize == 0)\n    clear();\n  else if (newSize > oldSize)\n    (*this)[newSize - 1];\n  else\n  {\n    for (ArrayIndex index = newSize; index < oldSize; ++index)\n    {\n      value_.map_->erase(index);\n    }\n    JSON_ASSERT(size() == newSize);\n  }\n}\n\nValue &Value::operator[](ArrayIndex index)\n{\n  JSON_ASSERT_MESSAGE(\n      type_ == nullValue || type_ == arrayValue,\n      \"in Json::Value::operator[](ArrayIndex): requires arrayValue\");\n  if (type_ == nullValue)\n    *this = Value(arrayValue);\n  CZString key(index);\n  ObjectValues::iterator it = value_.map_->lower_bound(key);\n  if (it != value_.map_->end() && (*it).first == key)\n    return (*it).second;\n\n  ObjectValues::value_type defaultValue(key, nullSingleton());\n  it = value_.map_->insert(it, defaultValue);\n  return (*it).second;\n}\n\nValue &Value::operator[](int index)\n{\n  JSON_ASSERT_MESSAGE(\n      index >= 0,\n      \"in Json::Value::operator[](int index): index cannot be negative\");\n  return (*this)[ArrayIndex(index)];\n}\n\nconst Value &Value::operator[](ArrayIndex index) const\n{\n  JSON_ASSERT_MESSAGE(\n      type_ == nullValue || type_ == arrayValue,\n      \"in Json::Value::operator[](ArrayIndex)const: requires arrayValue\");\n  if (type_ == nullValue)\n    return nullSingleton();\n  CZString key(index);\n  ObjectValues::const_iterator it = value_.map_->find(key);\n  if (it == value_.map_->end())\n    return nullSingleton();\n  return (*it).second;\n}\n\nconst Value &Value::operator[](int index) const\n{\n  JSON_ASSERT_MESSAGE(\n      index >= 0,\n      \"in Json::Value::operator[](int index) const: index cannot be negative\");\n  return (*this)[ArrayIndex(index)];\n}\n\nvoid Value::initBasic(ValueType vtype, bool allocated)\n{\n  type_ = vtype;\n  allocated_ = allocated;\n  comments_ = 0;\n  start_ = 0;\n  limit_ = 0;\n}\n\n// Access an object value by name, create a null member if it does not exist.\n// @pre Type of '*this' is object or null.\n// @param key is null-terminated.\nValue &Value::resolveReference(const char *key)\n{\n  JSON_ASSERT_MESSAGE(\n      type_ == nullValue || type_ == objectValue,\n      \"in Json::Value::resolveReference(): requires objectValue\");\n  if (type_ == nullValue)\n    *this = Value(objectValue);\n  CZString actualKey(\n      key, static_cast<unsigned>(strlen(key)), CZString::noDuplication); // NOTE!\n  ObjectValues::iterator it = value_.map_->lower_bound(actualKey);\n  if (it != value_.map_->end() && (*it).first == actualKey)\n    return (*it).second;\n\n  ObjectValues::value_type defaultValue(actualKey, nullSingleton());\n  it = value_.map_->insert(it, defaultValue);\n  Value &value = (*it).second;\n  return value;\n}\n\n// @param key is not null-terminated.\nValue &Value::resolveReference(char const *key, char const *cend)\n{\n  std::string info(\"in Json::Value::resolveReference(key, end): requires objectValue. \");\n  info += \"key: \";\n  info += key;\n  info += \", cend: \";\n  info += cend;\n\n  JSON_ASSERT_MESSAGE(\n      type_ == nullValue || type_ == objectValue,\n      info);\n  if (type_ == nullValue)\n    *this = Value(objectValue);\n  CZString actualKey(\n      key, static_cast<unsigned>(cend - key), CZString::duplicateOnCopy);\n  ObjectValues::iterator it = value_.map_->lower_bound(actualKey);\n  if (it != value_.map_->end() && (*it).first == actualKey)\n    return (*it).second;\n\n  ObjectValues::value_type defaultValue(actualKey, nullSingleton());\n  it = value_.map_->insert(it, defaultValue);\n  Value &value = (*it).second;\n  return value;\n}\n\nValue Value::get(ArrayIndex index, const Value &defaultValue) const\n{\n  const Value *value = &((*this)[index]);\n  return value == &nullSingleton() ? defaultValue : *value;\n}\n\nbool Value::isValidIndex(ArrayIndex index) const { return index < size(); }\n\nValue const *Value::find(char const *key, char const *cend) const\n{\n  JSON_ASSERT_MESSAGE(\n      type_ == nullValue || type_ == objectValue,\n      \"in Json::Value::find(key, end, found): requires objectValue or nullValue\");\n  if (type_ == nullValue)\n    return NULL;\n  CZString actualKey(key, static_cast<unsigned>(cend - key), CZString::noDuplication);\n  ObjectValues::const_iterator it = value_.map_->find(actualKey);\n  if (it == value_.map_->end())\n    return NULL;\n  return &(*it).second;\n}\nconst Value &Value::operator[](const char *key) const\n{\n  Value const *found = find(key, key + strlen(key));\n  if (!found)\n    return nullSingleton();\n  return *found;\n}\nValue const &Value::operator[](JSONCPP_STRING const &key) const\n{\n  Value const *found = find(key.data(), key.data() + key.length());\n  if (!found)\n    return nullSingleton();\n  return *found;\n}\n\nValue &Value::operator[](const char *key)\n{\n  return resolveReference(key, key + strlen(key));\n}\n\nValue &Value::operator[](const JSONCPP_STRING &key)\n{\n  return resolveReference(key.data(), key.data() + key.length());\n}\n\nValue &Value::operator[](const StaticString &key)\n{\n  return resolveReference(key.c_str());\n}\n\n#ifdef JSON_USE_CPPTL\nValue &Value::operator[](const CppTL::ConstString &key)\n{\n  return resolveReference(key.c_str(), key.end_c_str());\n}\nValue const &Value::operator[](CppTL::ConstString const &key) const\n{\n  Value const *found = find(key.c_str(), key.end_c_str());\n  if (!found)\n    return nullSingleton();\n  return *found;\n}\n#endif\n\nValue &Value::append(const Value &value)\n{\n  return (*this)[size()] = value;\n}\n\n#if JSON_HAS_RVALUE_REFERENCES\nValue &Value::append(Value &&value)\n{\n  return (*this)[size()] = value;\n}\n#endif\n\nValue Value::get(char const *key, char const *cend, Value const &defaultValue) const\n{\n  Value const *found = find(key, cend);\n  return !found ? defaultValue : *found;\n}\nValue Value::get(char const *key, Value const &defaultValue) const\n{\n  return get(key, key + strlen(key), defaultValue);\n}\nValue Value::get(JSONCPP_STRING const &key, Value const &defaultValue) const\n{\n  return get(key.data(), key.data() + key.length(), defaultValue);\n}\n\nbool Value::removeMember(const char *key, const char *cend, Value *removed)\n{\n  if (type_ != objectValue)\n  {\n    return false;\n  }\n  CZString actualKey(key, static_cast<unsigned>(cend - key), CZString::noDuplication);\n  ObjectValues::iterator it = value_.map_->find(actualKey);\n  if (it == value_.map_->end())\n    return false;\n  *removed = it->second;\n  value_.map_->erase(it);\n  return true;\n}\nbool Value::removeMember(const char *key, Value *removed)\n{\n  return removeMember(key, key + strlen(key), removed);\n}\nbool Value::removeMember(JSONCPP_STRING const &key, Value *removed)\n{\n  return removeMember(key.data(), key.data() + key.length(), removed);\n}\nValue Value::removeMember(const char *key)\n{\n  JSON_ASSERT_MESSAGE(type_ == nullValue || type_ == objectValue,\n                      \"in Json::Value::removeMember(): requires objectValue\");\n  if (type_ == nullValue)\n    return nullSingleton();\n\n  Value removed; // null\n  removeMember(key, key + strlen(key), &removed);\n  return removed; // still null if removeMember() did nothing\n}\nValue Value::removeMember(const JSONCPP_STRING &key)\n{\n  return removeMember(key.c_str());\n}\n\nbool Value::removeIndex(ArrayIndex index, Value *removed)\n{\n  if (type_ != arrayValue)\n  {\n    return false;\n  }\n  CZString key(index);\n  ObjectValues::iterator it = value_.map_->find(key);\n  if (it == value_.map_->end())\n  {\n    return false;\n  }\n  *removed = it->second;\n  ArrayIndex oldSize = size();\n  // shift left all items left, into the place of the \"removed\"\n  for (ArrayIndex i = index; i < (oldSize - 1); ++i)\n  {\n    CZString keey(i);\n    (*value_.map_)[keey] = (*this)[i + 1];\n  }\n  // erase the last one (\"leftover\")\n  CZString keyLast(oldSize - 1);\n  ObjectValues::iterator itLast = value_.map_->find(keyLast);\n  value_.map_->erase(itLast);\n  return true;\n}\n\n#ifdef JSON_USE_CPPTL\nValue Value::get(const CppTL::ConstString &key,\n                 const Value &defaultValue) const\n{\n  return get(key.c_str(), key.end_c_str(), defaultValue);\n}\n#endif\n\nbool Value::isMember(char const *key, char const *cend) const\n{\n  Value const *value = find(key, cend);\n  return NULL != value;\n}\nbool Value::isMember(char const *key) const\n{\n  return isMember(key, key + strlen(key));\n}\nbool Value::isMember(JSONCPP_STRING const &key) const\n{\n  return isMember(key.data(), key.data() + key.length());\n}\n\n#ifdef JSON_USE_CPPTL\nbool Value::isMember(const CppTL::ConstString &key) const\n{\n  return isMember(key.c_str(), key.end_c_str());\n}\n#endif\n\nValue::Members Value::getMemberNames() const\n{\n  JSON_ASSERT_MESSAGE(\n      type_ == nullValue || type_ == objectValue,\n      \"in Json::Value::getMemberNames(), value must be objectValue\");\n  if (type_ == nullValue)\n    return Value::Members();\n  Members members;\n  members.reserve(value_.map_->size());\n  ObjectValues::const_iterator it = value_.map_->begin();\n  ObjectValues::const_iterator itEnd = value_.map_->end();\n  for (; it != itEnd; ++it)\n  {\n    members.push_back(JSONCPP_STRING((*it).first.data(),\n                                     (*it).first.length()));\n  }\n  return members;\n}\n//\n//# ifdef JSON_USE_CPPTL\n// EnumMemberNames\n// Value::enumMemberNames() const\n//{\n//   if ( type_ == objectValue )\n//   {\n//      return CppTL::Enum::any(  CppTL::Enum::transform(\n//         CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ),\n//         MemberNamesTransform() ) );\n//   }\n//   return EnumMemberNames();\n//}\n//\n//\n// EnumValues\n// Value::enumValues() const\n//{\n//   if ( type_ == objectValue  ||  type_ == arrayValue )\n//      return CppTL::Enum::anyValues( *(value_.map_),\n//                                     CppTL::Type<const Value &>() );\n//   return EnumValues();\n//}\n//\n//# endif\n\nstatic bool IsIntegral(double d)\n{\n  double integral_part;\n  return modf(d, &integral_part) == 0.0;\n}\n\nbool Value::isNull() const { return type_ == nullValue; }\n\nbool Value::isBool() const { return type_ == booleanValue; }\n\nbool Value::isInt() const\n{\n  switch (type_)\n  {\n  case intValue:\n#if defined(JSON_HAS_INT64)\n    return value_.int_ >= minInt && value_.int_ <= maxInt;\n#else\n    return true;\n#endif\n  case uintValue:\n    return value_.uint_ <= UInt(maxInt);\n  case realValue:\n    return value_.real_ >= minInt && value_.real_ <= maxInt &&\n           IsIntegral(value_.real_);\n  default:\n    break;\n  }\n  return false;\n}\n\nbool Value::isUInt() const\n{\n  switch (type_)\n  {\n  case intValue:\n#if defined(JSON_HAS_INT64)\n    return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt);\n#else\n    return value_.int_ >= 0;\n#endif\n  case uintValue:\n#if defined(JSON_HAS_INT64)\n    return value_.uint_ <= maxUInt;\n#else\n    return true;\n#endif\n  case realValue:\n    return value_.real_ >= 0 && value_.real_ <= maxUInt &&\n           IsIntegral(value_.real_);\n  default:\n    break;\n  }\n  return false;\n}\n\nbool Value::isInt64() const\n{\n#if defined(JSON_HAS_INT64)\n  switch (type_)\n  {\n  case intValue:\n    return true;\n  case uintValue:\n    return value_.uint_ <= UInt64(maxInt64);\n  case realValue:\n    // Note that maxInt64 (= 2^63 - 1) is not exactly representable as a\n    // double, so double(maxInt64) will be rounded up to 2^63. Therefore we\n    // require the value to be strictly less than the limit.\n    return value_.real_ >= double(minInt64) &&\n           value_.real_ < double(maxInt64) && IsIntegral(value_.real_);\n  default:\n    break;\n  }\n#endif // JSON_HAS_INT64\n  return false;\n}\n\nbool Value::isUInt64() const\n{\n#if defined(JSON_HAS_INT64)\n  switch (type_)\n  {\n  case intValue:\n    return value_.int_ >= 0;\n  case uintValue:\n    return true;\n  case realValue:\n    // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a\n    // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we\n    // require the value to be strictly less than the limit.\n    return value_.real_ >= 0 && value_.real_ < maxUInt64AsDouble &&\n           IsIntegral(value_.real_);\n  default:\n    break;\n  }\n#endif // JSON_HAS_INT64\n  return false;\n}\n\nbool Value::isIntegral() const\n{\n  switch (type_)\n  {\n  case intValue:\n  case uintValue:\n    return true;\n  case realValue:\n#if defined(JSON_HAS_INT64)\n    // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a\n    // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we\n    // require the value to be strictly less than the limit.\n    return value_.real_ >= double(minInt64) && value_.real_ < maxUInt64AsDouble && IsIntegral(value_.real_);\n#else\n    return value_.real_ >= minInt && value_.real_ <= maxUInt && IsIntegral(value_.real_);\n#endif // JSON_HAS_INT64\n  default:\n    break;\n  }\n  return false;\n}\n\nbool Value::isDouble() const { return type_ == intValue || type_ == uintValue || type_ == realValue; }\n\nbool Value::isNumeric() const { return isDouble(); }\n\nbool Value::isString() const { return type_ == stringValue; }\n\nbool Value::isArray() const { return type_ == arrayValue; }\n\nbool Value::isObject() const { return type_ == objectValue; }\n\nvoid Value::setComment(const char *comment, size_t len, CommentPlacement placement)\n{\n  if (!comments_)\n    comments_ = new CommentInfo[numberOfCommentPlacement];\n  if ((len > 0) && (comment[len - 1] == '\\n'))\n  {\n    // Always discard trailing newline, to aid indentation.\n    len -= 1;\n  }\n  comments_[placement].setComment(comment, len);\n}\n\nvoid Value::setComment(const char *comment, CommentPlacement placement)\n{\n  setComment(comment, strlen(comment), placement);\n}\n\nvoid Value::setComment(const JSONCPP_STRING &comment, CommentPlacement placement)\n{\n  setComment(comment.c_str(), comment.length(), placement);\n}\n\nbool Value::hasComment(CommentPlacement placement) const\n{\n  return comments_ != 0 && comments_[placement].comment_ != 0;\n}\n\nJSONCPP_STRING Value::getComment(CommentPlacement placement) const\n{\n  if (hasComment(placement))\n    return comments_[placement].comment_;\n  return \"\";\n}\n\nvoid Value::setOffsetStart(ptrdiff_t start) { start_ = start; }\n\nvoid Value::setOffsetLimit(ptrdiff_t limit) { limit_ = limit; }\n\nptrdiff_t Value::getOffsetStart() const { return start_; }\n\nptrdiff_t Value::getOffsetLimit() const { return limit_; }\n\nJSONCPP_STRING Value::toStyledString() const\n{\n  StreamWriterBuilder builder;\n\n  JSONCPP_STRING out = this->hasComment(commentBefore) ? \"\\n\" : \"\";\n  out += Json::writeString(builder, *this);\n  out += \"\\n\";\n\n  return out;\n}\n\nValue::const_iterator Value::begin() const\n{\n  switch (type_)\n  {\n  case arrayValue:\n  case objectValue:\n    if (value_.map_)\n      return const_iterator(value_.map_->begin());\n    break;\n  default:\n    break;\n  }\n  return const_iterator();\n}\n\nValue::const_iterator Value::end() const\n{\n  switch (type_)\n  {\n  case arrayValue:\n  case objectValue:\n    if (value_.map_)\n      return const_iterator(value_.map_->end());\n    break;\n  default:\n    break;\n  }\n  return const_iterator();\n}\n\nValue::iterator Value::begin()\n{\n  switch (type_)\n  {\n  case arrayValue:\n  case objectValue:\n    if (value_.map_)\n      return iterator(value_.map_->begin());\n    break;\n  default:\n    break;\n  }\n  return iterator();\n}\n\nValue::iterator Value::end()\n{\n  switch (type_)\n  {\n  case arrayValue:\n  case objectValue:\n    if (value_.map_)\n      return iterator(value_.map_->end());\n    break;\n  default:\n    break;\n  }\n  return iterator();\n}\n\n// class PathArgument\n// //////////////////////////////////////////////////////////////////\n\nPathArgument::PathArgument() : key_(), index_(), kind_(kindNone) {}\n\nPathArgument::PathArgument(ArrayIndex index)\n    : key_(), index_(index), kind_(kindIndex) {}\n\nPathArgument::PathArgument(const char *key)\n    : key_(key), index_(), kind_(kindKey) {}\n\nPathArgument::PathArgument(const JSONCPP_STRING &key)\n    : key_(key.c_str()), index_(), kind_(kindKey) {}\n\n// class Path\n// //////////////////////////////////////////////////////////////////\n\nPath::Path(const JSONCPP_STRING &path,\n           const PathArgument &a1,\n           const PathArgument &a2,\n           const PathArgument &a3,\n           const PathArgument &a4,\n           const PathArgument &a5)\n{\n  InArgs in;\n  in.reserve(5);\n  in.push_back(&a1);\n  in.push_back(&a2);\n  in.push_back(&a3);\n  in.push_back(&a4);\n  in.push_back(&a5);\n  makePath(path, in);\n}\n\nvoid Path::makePath(const JSONCPP_STRING &path, const InArgs &in)\n{\n  const char *current = path.c_str();\n  const char *end = current + path.length();\n  InArgs::const_iterator itInArg = in.begin();\n  while (current != end)\n  {\n    if (*current == '[')\n    {\n      ++current;\n      if (*current == '%')\n        addPathInArg(path, in, itInArg, PathArgument::kindIndex);\n      else\n      {\n        ArrayIndex index = 0;\n        for (; current != end && *current >= '0' && *current <= '9'; ++current)\n          index = index * 10 + ArrayIndex(*current - '0');\n        args_.push_back(index);\n      }\n      if (current == end || *++current != ']')\n        invalidPath(path, int(current - path.c_str()));\n    }\n    else if (*current == '%')\n    {\n      addPathInArg(path, in, itInArg, PathArgument::kindKey);\n      ++current;\n    }\n    else if (*current == '.' || *current == ']')\n    {\n      ++current;\n    }\n    else\n    {\n      const char *beginName = current;\n      while (current != end && !strchr(\"[.\", *current))\n        ++current;\n      args_.push_back(JSONCPP_STRING(beginName, current));\n    }\n  }\n}\n\nvoid Path::addPathInArg(const JSONCPP_STRING & /*path*/,\n                        const InArgs &in,\n                        InArgs::const_iterator &itInArg,\n                        PathArgument::Kind kind)\n{\n  if (itInArg == in.end())\n  {\n    // Error: missing argument %d\n  }\n  else if ((*itInArg)->kind_ != kind)\n  {\n    // Error: bad argument type\n  }\n  else\n  {\n    args_.push_back(**itInArg++);\n  }\n}\n\nvoid Path::invalidPath(const JSONCPP_STRING & /*path*/, int /*location*/)\n{\n  // Error: invalid path.\n}\n\nconst Value &Path::resolve(const Value &root) const\n{\n  const Value *node = &root;\n  for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it)\n  {\n    const PathArgument &arg = *it;\n    if (arg.kind_ == PathArgument::kindIndex)\n    {\n      if (!node->isArray() || !node->isValidIndex(arg.index_))\n      {\n        // Error: unable to resolve path (array value expected at position...\n        return Value::null;\n      }\n      node = &((*node)[arg.index_]);\n    }\n    else if (arg.kind_ == PathArgument::kindKey)\n    {\n      if (!node->isObject())\n      {\n        // Error: unable to resolve path (object value expected at position...)\n        return Value::null;\n      }\n      node = &((*node)[arg.key_]);\n      if (node == &Value::nullSingleton())\n      {\n        // Error: unable to resolve path (object has no member named '' at\n        // position...)\n        return Value::null;\n      }\n    }\n  }\n  return *node;\n}\n\nValue Path::resolve(const Value &root, const Value &defaultValue) const\n{\n  const Value *node = &root;\n  for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it)\n  {\n    const PathArgument &arg = *it;\n    if (arg.kind_ == PathArgument::kindIndex)\n    {\n      if (!node->isArray() || !node->isValidIndex(arg.index_))\n        return defaultValue;\n      node = &((*node)[arg.index_]);\n    }\n    else if (arg.kind_ == PathArgument::kindKey)\n    {\n      if (!node->isObject())\n        return defaultValue;\n      node = &((*node)[arg.key_]);\n      if (node == &Value::nullSingleton())\n        return defaultValue;\n    }\n  }\n  return *node;\n}\n\nValue &Path::make(Value &root) const\n{\n  Value *node = &root;\n  for (Args::const_iterator it = args_.begin(); it != args_.end(); ++it)\n  {\n    const PathArgument &arg = *it;\n    if (arg.kind_ == PathArgument::kindIndex)\n    {\n      if (!node->isArray())\n      {\n        // Error: node is not an array at position ...\n      }\n      node = &((*node)[arg.index_]);\n    }\n    else if (arg.kind_ == PathArgument::kindKey)\n    {\n      if (!node->isObject())\n      {\n        // Error: node is not an object at position...\n      }\n      node = &((*node)[arg.key_]);\n    }\n  }\n  return *node;\n}\n\n} // namespace Json\n\n// //////////////////////////////////////////////////////////////////////\n// End of content of file: src/lib_json/json_value.cpp\n// //////////////////////////////////////////////////////////////////////\n\n// //////////////////////////////////////////////////////////////////////\n// Beginning of content of file: src/lib_json/json_writer.cpp\n// //////////////////////////////////////////////////////////////////////\n\n// Copyright 2011 Baptiste Lepilleur and The JsonCpp Authors\n// Distributed under MIT license, or public domain if desired and\n// recognized in your jurisdiction.\n// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE\n\n#if !defined(JSON_IS_AMALGAMATION)\n#include <json/writer.h>\n#include \"json_tool.h\"\n#endif // if !defined(JSON_IS_AMALGAMATION)\n#include <iomanip>\n#include <memory>\n#include <sstream>\n#include <utility>\n#include <set>\n#include <cassert>\n#include <cstring>\n#include <cstdio>\n\n#if defined(_MSC_VER) && _MSC_VER >= 1200 && _MSC_VER < 1800 // Between VC++ 6.0 and VC++ 11.0\n#include <float.h>\n#define isfinite _finite\n#elif defined(__sun) && defined(__SVR4) //Solaris\n#if !defined(isfinite)\n#include <ieeefp.h>\n#define isfinite finite\n#endif\n#elif defined(_AIX)\n#if !defined(isfinite)\n#include <math.h>\n#define isfinite finite\n#endif\n#elif defined(__hpux)\n#if !defined(isfinite)\n#if defined(__ia64) && !defined(finite)\n#define isfinite(x) ((sizeof(x) == sizeof(float) ? _Isfinitef(x) : _IsFinite(x)))\n#else\n#include <math.h>\n#define isfinite finite\n#endif\n#endif\n#else\n#include <cmath>\n#if !(defined(__QNXNTO__)) // QNX already defines isfinite\n#define isfinite std::isfinite\n#endif\n#endif\n\n#if defined(_MSC_VER)\n#if !defined(WINCE) && defined(__STDC_SECURE_LIB__) && _MSC_VER >= 1500 // VC++ 9.0 and above\n#define snprintf sprintf_s\n#elif _MSC_VER >= 1900 // VC++ 14.0 and above\n#define snprintf std::snprintf\n#else\n#define snprintf _snprintf\n#endif\n#elif defined(__ANDROID__) || defined(__QNXNTO__)\n#define snprintf snprintf\n#elif __cplusplus >= 201103L\n#if !defined(__MINGW32__) && !defined(__CYGWIN__)\n#define snprintf std::snprintf\n#endif\n#endif\n\n#if defined(__BORLANDC__)\n#include <float.h>\n#define isfinite _finite\n#define snprintf _snprintf\n#endif\n\n#if defined(_MSC_VER) && _MSC_VER >= 1400 // VC++ 8.0\n// Disable warning about strdup being deprecated.\n#pragma warning(disable : 4996)\n#endif\n\nnamespace Json\n{\n\n#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520)\ntypedef std::unique_ptr<StreamWriter> StreamWriterPtr;\n#else\ntypedef std::auto_ptr<StreamWriter> StreamWriterPtr;\n#endif\n\nstatic bool containsControlCharacter(const char *str)\n{\n  while (*str)\n  {\n    if (isControlCharacter(*(str++)))\n      return true;\n  }\n  return false;\n}\n\nstatic bool containsControlCharacter0(const char *str, unsigned len)\n{\n  char const *end = str + len;\n  while (end != str)\n  {\n    if (isControlCharacter(*str) || 0 == *str)\n      return true;\n    ++str;\n  }\n  return false;\n}\n\nJSONCPP_STRING valueToString(LargestInt value)\n{\n  UIntToStringBuffer buffer;\n  char *current = buffer + sizeof(buffer);\n  if (value == Value::minLargestInt)\n  {\n    uintToString(LargestUInt(Value::maxLargestInt) + 1, current);\n    *--current = '-';\n  }\n  else if (value < 0)\n  {\n    uintToString(LargestUInt(-value), current);\n    *--current = '-';\n  }\n  else\n  {\n    uintToString(LargestUInt(value), current);\n  }\n  assert(current >= buffer);\n  return current;\n}\n\nJSONCPP_STRING valueToString(LargestUInt value)\n{\n  UIntToStringBuffer buffer;\n  char *current = buffer + sizeof(buffer);\n  uintToString(value, current);\n  assert(current >= buffer);\n  return current;\n}\n\n#if defined(JSON_HAS_INT64)\n\nJSONCPP_STRING valueToString(Int value)\n{\n  return valueToString(LargestInt(value));\n}\n\nJSONCPP_STRING valueToString(UInt value)\n{\n  return valueToString(LargestUInt(value));\n}\n\n#endif // # if defined(JSON_HAS_INT64)\n\nnamespace\n{\nJSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int precision)\n{\n  // Allocate a buffer that is more than large enough to store the 16 digits of\n  // precision requested below.\n  char buffer[36];\n  int len = -1;\n\n  char formatString[15];\n  snprintf(formatString, sizeof(formatString), \"%%.%dg\", precision);\n\n  // Print into the buffer. We need not request the alternative representation\n  // that always has a decimal point because JSON doesn't distingish the\n  // concepts of reals and integers.\n  if (isfinite(value))\n  {\n    len = snprintf(buffer, sizeof(buffer), formatString, value);\n    fixNumericLocale(buffer, buffer + len);\n\n    // try to ensure we preserve the fact that this was given to us as a double on input\n    if (!strchr(buffer, '.') && !strchr(buffer, 'e'))\n    {\n      strcat(buffer, \".0\");\n    }\n  }\n  else\n  {\n    // IEEE standard states that NaN values will not compare to themselves\n    if (value != value)\n    {\n      len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? \"NaN\" : \"null\");\n    }\n    else if (value < 0)\n    {\n      len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? \"-Infinity\" : \"-1e+9999\");\n    }\n    else\n    {\n      len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? \"Infinity\" : \"1e+9999\");\n    }\n  }\n  assert(len >= 0);\n  return buffer;\n}\n} // namespace\n\nJSONCPP_STRING valueToString(double value) { return valueToString(value, false, 17); }\n\nJSONCPP_STRING valueToString(bool value) { return value ? \"true\" : \"false\"; }\n\nJSONCPP_STRING valueToQuotedString(const char *value)\n{\n  if (value == NULL)\n    return \"\";\n  // Not sure how to handle unicode...\n  if (strpbrk(value, \"\\\"\\\\\\b\\f\\n\\r\\t\") == NULL &&\n      !containsControlCharacter(value))\n    return JSONCPP_STRING(\"\\\"\") + value + \"\\\"\";\n  // We have to walk value and escape any special characters.\n  // Appending to JSONCPP_STRING is not efficient, but this should be rare.\n  // (Note: forward slashes are *not* rare, but I am not escaping them.)\n  JSONCPP_STRING::size_type maxsize =\n      strlen(value) * 2 + 3; // allescaped+quotes+NULL\n  JSONCPP_STRING result;\n  result.reserve(maxsize); // to avoid lots of mallocs\n  result += \"\\\"\";\n  for (const char *c = value; *c != 0; ++c)\n  {\n    switch (*c)\n    {\n    case '\\\"':\n      result += \"\\\\\\\"\";\n      break;\n    case '\\\\':\n      result += \"\\\\\\\\\";\n      break;\n    case '\\b':\n      result += \"\\\\b\";\n      break;\n    case '\\f':\n      result += \"\\\\f\";\n      break;\n    case '\\n':\n      result += \"\\\\n\";\n      break;\n    case '\\r':\n      result += \"\\\\r\";\n      break;\n    case '\\t':\n      result += \"\\\\t\";\n      break;\n    // case '/':\n    // Even though \\/ is considered a legal escape in JSON, a bare\n    // slash is also legal, so I see no reason to escape it.\n    // (I hope I am not misunderstanding something.\n    // blep notes: actually escaping \\/ may be useful in javascript to avoid </\n    // sequence.\n    // Should add a flag to allow this compatibility mode and prevent this\n    // sequence from occurring.\n    default:\n      if (isControlCharacter(*c))\n      {\n        JSONCPP_OSTRINGSTREAM oss;\n        oss << \"\\\\u\" << std::hex << std::uppercase << std::setfill('0')\n            << std::setw(4) << static_cast<int>(*c);\n        result += oss.str();\n      }\n      else\n      {\n        result += *c;\n      }\n      break;\n    }\n  }\n  result += \"\\\"\";\n  return result;\n}\n\n// https://github.com/upcaste/upcaste/blob/master/src/upcore/src/cstring/strnpbrk.cpp\nstatic char const *strnpbrk(char const *s, char const *accept, size_t n)\n{\n  assert((s || !n) && accept);\n\n  char const *const end = s + n;\n  for (char const *cur = s; cur < end; ++cur)\n  {\n    int const c = *cur;\n    for (char const *a = accept; *a; ++a)\n    {\n      if (*a == c)\n      {\n        return cur;\n      }\n    }\n  }\n  return NULL;\n}\nstatic JSONCPP_STRING valueToQuotedStringN(const char *value, unsigned length)\n{\n  if (value == NULL)\n    return \"\";\n  // Not sure how to handle unicode...\n  if (strnpbrk(value, \"\\\"\\\\\\b\\f\\n\\r\\t\", length) == NULL &&\n      !containsControlCharacter0(value, length))\n    return JSONCPP_STRING(\"\\\"\") + value + \"\\\"\";\n  // We have to walk value and escape any special characters.\n  // Appending to JSONCPP_STRING is not efficient, but this should be rare.\n  // (Note: forward slashes are *not* rare, but I am not escaping them.)\n  JSONCPP_STRING::size_type maxsize =\n      length * 2 + 3; // allescaped+quotes+NULL\n  JSONCPP_STRING result;\n  result.reserve(maxsize); // to avoid lots of mallocs\n  result += \"\\\"\";\n  char const *end = value + length;\n  for (const char *c = value; c != end; ++c)\n  {\n    switch (*c)\n    {\n    case '\\\"':\n      result += \"\\\\\\\"\";\n      break;\n    case '\\\\':\n      result += \"\\\\\\\\\";\n      break;\n    case '\\b':\n      result += \"\\\\b\";\n      break;\n    case '\\f':\n      result += \"\\\\f\";\n      break;\n    case '\\n':\n      result += \"\\\\n\";\n      break;\n    case '\\r':\n      result += \"\\\\r\";\n      break;\n    case '\\t':\n      result += \"\\\\t\";\n      break;\n    // case '/':\n    // Even though \\/ is considered a legal escape in JSON, a bare\n    // slash is also legal, so I see no reason to escape it.\n    // (I hope I am not misunderstanding something.)\n    // blep notes: actually escaping \\/ may be useful in javascript to avoid </\n    // sequence.\n    // Should add a flag to allow this compatibility mode and prevent this\n    // sequence from occurring.\n    default:\n      if ((isControlCharacter(*c)) || (*c == 0))\n      {\n        JSONCPP_OSTRINGSTREAM oss;\n        oss << \"\\\\u\" << std::hex << std::uppercase << std::setfill('0')\n            << std::setw(4) << static_cast<int>(*c);\n        result += oss.str();\n      }\n      else\n      {\n        result += *c;\n      }\n      break;\n    }\n  }\n  result += \"\\\"\";\n  return result;\n}\n\n// Class Writer\n// //////////////////////////////////////////////////////////////////\nWriter::~Writer() {}\n\n// Class FastWriter\n// //////////////////////////////////////////////////////////////////\n\nFastWriter::FastWriter()\n    : yamlCompatiblityEnabled_(false), dropNullPlaceholders_(false),\n      omitEndingLineFeed_(false) {}\n\nvoid FastWriter::enableYAMLCompatibility() { yamlCompatiblityEnabled_ = true; }\n\nvoid FastWriter::dropNullPlaceholders() { dropNullPlaceholders_ = true; }\n\nvoid FastWriter::omitEndingLineFeed() { omitEndingLineFeed_ = true; }\n\nJSONCPP_STRING FastWriter::write(const Value &root)\n{\n  document_.clear();\n  writeValue(root);\n  if (!omitEndingLineFeed_)\n    document_ += \"\\n\";\n  return document_;\n}\n\nvoid FastWriter::writeValue(const Value &value)\n{\n  switch (value.type())\n  {\n  case nullValue:\n    if (!dropNullPlaceholders_)\n      document_ += \"null\";\n    break;\n  case intValue:\n    document_ += valueToString(value.asLargestInt());\n    break;\n  case uintValue:\n    document_ += valueToString(value.asLargestUInt());\n    break;\n  case realValue:\n    document_ += valueToString(value.asDouble());\n    break;\n  case stringValue:\n  {\n    // Is NULL possible for value.string_? No.\n    char const *str;\n    char const *end;\n    bool ok = value.getString(&str, &end);\n    if (ok)\n      document_ += valueToQuotedStringN(str, static_cast<unsigned>(end - str));\n    break;\n  }\n  case booleanValue:\n    document_ += valueToString(value.asBool());\n    break;\n  case arrayValue:\n  {\n    document_ += '[';\n    ArrayIndex size = value.size();\n    for (ArrayIndex index = 0; index < size; ++index)\n    {\n      if (index > 0)\n        document_ += ',';\n      writeValue(value[index]);\n    }\n    document_ += ']';\n  }\n  break;\n  case objectValue:\n  {\n    Value::Members members(value.getMemberNames());\n    document_ += '{';\n    for (Value::Members::iterator it = members.begin(); it != members.end();\n         ++it)\n    {\n      const JSONCPP_STRING &name = *it;\n      if (it != members.begin())\n        document_ += ',';\n      document_ += valueToQuotedStringN(name.data(), static_cast<unsigned>(name.length()));\n      document_ += yamlCompatiblityEnabled_ ? \": \" : \":\";\n      writeValue(value[name]);\n    }\n    document_ += '}';\n  }\n  break;\n  }\n}\n\n// Class StyledWriter\n// //////////////////////////////////////////////////////////////////\n\nStyledWriter::StyledWriter()\n    : rightMargin_(74), indentSize_(3), addChildValues_() {}\n\nJSONCPP_STRING StyledWriter::write(const Value &root)\n{\n  document_.clear();\n  addChildValues_ = false;\n  indentString_.clear();\n  writeCommentBeforeValue(root);\n  writeValue(root);\n  writeCommentAfterValueOnSameLine(root);\n  document_ += \"\\n\";\n  return document_;\n}\n\nvoid StyledWriter::writeValue(const Value &value)\n{\n  switch (value.type())\n  {\n  case nullValue:\n    pushValue(\"null\");\n    break;\n  case intValue:\n    pushValue(valueToString(value.asLargestInt()));\n    break;\n  case uintValue:\n    pushValue(valueToString(value.asLargestUInt()));\n    break;\n  case realValue:\n    pushValue(valueToString(value.asDouble()));\n    break;\n  case stringValue:\n  {\n    // Is NULL possible for value.string_? No.\n    char const *str;\n    char const *end;\n    bool ok = value.getString(&str, &end);\n    if (ok)\n      pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str)));\n    else\n      pushValue(\"\");\n    break;\n  }\n  case booleanValue:\n    pushValue(valueToString(value.asBool()));\n    break;\n  case arrayValue:\n    writeArrayValue(value);\n    break;\n  case objectValue:\n  {\n    Value::Members members(value.getMemberNames());\n    if (members.empty())\n      pushValue(\"{}\");\n    else\n    {\n      writeWithIndent(\"{\");\n      indent();\n      Value::Members::iterator it = members.begin();\n      for (;;)\n      {\n        const JSONCPP_STRING &name = *it;\n        const Value &childValue = value[name];\n        writeCommentBeforeValue(childValue);\n        writeWithIndent(valueToQuotedString(name.c_str()));\n        document_ += \" : \";\n        writeValue(childValue);\n        if (++it == members.end())\n        {\n          writeCommentAfterValueOnSameLine(childValue);\n          break;\n        }\n        document_ += ',';\n        writeCommentAfterValueOnSameLine(childValue);\n      }\n      unindent();\n      writeWithIndent(\"}\");\n    }\n  }\n  break;\n  }\n}\n\nvoid StyledWriter::writeArrayValue(const Value &value)\n{\n  unsigned size = value.size();\n  if (size == 0)\n    pushValue(\"[]\");\n  else\n  {\n    bool isArrayMultiLine = isMultineArray(value);\n    if (isArrayMultiLine)\n    {\n      writeWithIndent(\"[\");\n      indent();\n      bool hasChildValue = !childValues_.empty();\n      unsigned index = 0;\n      for (;;)\n      {\n        const Value &childValue = value[index];\n        writeCommentBeforeValue(childValue);\n        if (hasChildValue)\n          writeWithIndent(childValues_[index]);\n        else\n        {\n          writeIndent();\n          writeValue(childValue);\n        }\n        if (++index == size)\n        {\n          writeCommentAfterValueOnSameLine(childValue);\n          break;\n        }\n        document_ += ',';\n        writeCommentAfterValueOnSameLine(childValue);\n      }\n      unindent();\n      writeWithIndent(\"]\");\n    }\n    else // output on a single line\n    {\n      assert(childValues_.size() == size);\n      document_ += \"[ \";\n      for (unsigned index = 0; index < size; ++index)\n      {\n        if (index > 0)\n          document_ += \", \";\n        document_ += childValues_[index];\n      }\n      document_ += \" ]\";\n    }\n  }\n}\n\nbool StyledWriter::isMultineArray(const Value &value)\n{\n  ArrayIndex const size = value.size();\n  bool isMultiLine = size * 3 >= rightMargin_;\n  childValues_.clear();\n  for (ArrayIndex index = 0; index < size && !isMultiLine; ++index)\n  {\n    const Value &childValue = value[index];\n    isMultiLine = ((childValue.isArray() || childValue.isObject()) &&\n                   childValue.size() > 0);\n  }\n  if (!isMultiLine) // check if line length > max line length\n  {\n    childValues_.reserve(size);\n    addChildValues_ = true;\n    ArrayIndex lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'\n    for (ArrayIndex index = 0; index < size; ++index)\n    {\n      if (hasCommentForValue(value[index]))\n      {\n        isMultiLine = true;\n      }\n      writeValue(value[index]);\n      lineLength += static_cast<ArrayIndex>(childValues_[index].length());\n    }\n    addChildValues_ = false;\n    isMultiLine = isMultiLine || lineLength >= rightMargin_;\n  }\n  return isMultiLine;\n}\n\nvoid StyledWriter::pushValue(const JSONCPP_STRING &value)\n{\n  if (addChildValues_)\n    childValues_.push_back(value);\n  else\n    document_ += value;\n}\n\nvoid StyledWriter::writeIndent()\n{\n  if (!document_.empty())\n  {\n    char last = document_[document_.length() - 1];\n    if (last == ' ') // already indented\n      return;\n    if (last != '\\n') // Comments may add new-line\n      document_ += '\\n';\n  }\n  document_ += indentString_;\n}\n\nvoid StyledWriter::writeWithIndent(const JSONCPP_STRING &value)\n{\n  writeIndent();\n  document_ += value;\n}\n\nvoid StyledWriter::indent() { indentString_ += JSONCPP_STRING(indentSize_, ' '); }\n\nvoid StyledWriter::unindent()\n{\n  assert(indentString_.size() >= indentSize_);\n  indentString_.resize(indentString_.size() - indentSize_);\n}\n\nvoid StyledWriter::writeCommentBeforeValue(const Value &root)\n{\n  if (!root.hasComment(commentBefore))\n    return;\n\n  document_ += \"\\n\";\n  writeIndent();\n  const JSONCPP_STRING &comment = root.getComment(commentBefore);\n  JSONCPP_STRING::const_iterator iter = comment.begin();\n  while (iter != comment.end())\n  {\n    document_ += *iter;\n    if (*iter == '\\n' &&\n        ((iter + 1) != comment.end() && *(iter + 1) == '/'))\n      writeIndent();\n    ++iter;\n  }\n\n  // Comments are stripped of trailing newlines, so add one here\n  document_ += \"\\n\";\n}\n\nvoid StyledWriter::writeCommentAfterValueOnSameLine(const Value &root)\n{\n  if (root.hasComment(commentAfterOnSameLine))\n    document_ += \" \" + root.getComment(commentAfterOnSameLine);\n\n  if (root.hasComment(commentAfter))\n  {\n    document_ += \"\\n\";\n    document_ += root.getComment(commentAfter);\n    document_ += \"\\n\";\n  }\n}\n\nbool StyledWriter::hasCommentForValue(const Value &value)\n{\n  return value.hasComment(commentBefore) ||\n         value.hasComment(commentAfterOnSameLine) ||\n         value.hasComment(commentAfter);\n}\n\n// Class StyledStreamWriter\n// //////////////////////////////////////////////////////////////////\n\nStyledStreamWriter::StyledStreamWriter(JSONCPP_STRING indentation)\n    : document_(NULL), rightMargin_(74), indentation_(indentation),\n      addChildValues_() {}\n\nvoid StyledStreamWriter::write(JSONCPP_OSTREAM &out, const Value &root)\n{\n  document_ = &out;\n  addChildValues_ = false;\n  indentString_.clear();\n  indented_ = true;\n  writeCommentBeforeValue(root);\n  if (!indented_)\n    writeIndent();\n  indented_ = true;\n  writeValue(root);\n  writeCommentAfterValueOnSameLine(root);\n  *document_ << \"\\n\";\n  document_ = NULL; // Forget the stream, for safety.\n}\n\nvoid StyledStreamWriter::writeValue(const Value &value)\n{\n  switch (value.type())\n  {\n  case nullValue:\n    pushValue(\"null\");\n    break;\n  case intValue:\n    pushValue(valueToString(value.asLargestInt()));\n    break;\n  case uintValue:\n    pushValue(valueToString(value.asLargestUInt()));\n    break;\n  case realValue:\n    pushValue(valueToString(value.asDouble()));\n    break;\n  case stringValue:\n  {\n    // Is NULL possible for value.string_? No.\n    char const *str;\n    char const *end;\n    bool ok = value.getString(&str, &end);\n    if (ok)\n      pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str)));\n    else\n      pushValue(\"\");\n    break;\n  }\n  case booleanValue:\n    pushValue(valueToString(value.asBool()));\n    break;\n  case arrayValue:\n    writeArrayValue(value);\n    break;\n  case objectValue:\n  {\n    Value::Members members(value.getMemberNames());\n    if (members.empty())\n      pushValue(\"{}\");\n    else\n    {\n      writeWithIndent(\"{\");\n      indent();\n      Value::Members::iterator it = members.begin();\n      for (;;)\n      {\n        const JSONCPP_STRING &name = *it;\n        const Value &childValue = value[name];\n        writeCommentBeforeValue(childValue);\n        writeWithIndent(valueToQuotedString(name.c_str()));\n        *document_ << \" : \";\n        writeValue(childValue);\n        if (++it == members.end())\n        {\n          writeCommentAfterValueOnSameLine(childValue);\n          break;\n        }\n        *document_ << \",\";\n        writeCommentAfterValueOnSameLine(childValue);\n      }\n      unindent();\n      writeWithIndent(\"}\");\n    }\n  }\n  break;\n  }\n}\n\nvoid StyledStreamWriter::writeArrayValue(const Value &value)\n{\n  unsigned size = value.size();\n  if (size == 0)\n    pushValue(\"[]\");\n  else\n  {\n    bool isArrayMultiLine = isMultineArray(value);\n    if (isArrayMultiLine)\n    {\n      writeWithIndent(\"[\");\n      indent();\n      bool hasChildValue = !childValues_.empty();\n      unsigned index = 0;\n      for (;;)\n      {\n        const Value &childValue = value[index];\n        writeCommentBeforeValue(childValue);\n        if (hasChildValue)\n          writeWithIndent(childValues_[index]);\n        else\n        {\n          if (!indented_)\n            writeIndent();\n          indented_ = true;\n          writeValue(childValue);\n          indented_ = false;\n        }\n        if (++index == size)\n        {\n          writeCommentAfterValueOnSameLine(childValue);\n          break;\n        }\n        *document_ << \",\";\n        writeCommentAfterValueOnSameLine(childValue);\n      }\n      unindent();\n      writeWithIndent(\"]\");\n    }\n    else // output on a single line\n    {\n      assert(childValues_.size() == size);\n      *document_ << \"[ \";\n      for (unsigned index = 0; index < size; ++index)\n      {\n        if (index > 0)\n          *document_ << \", \";\n        *document_ << childValues_[index];\n      }\n      *document_ << \" ]\";\n    }\n  }\n}\n\nbool StyledStreamWriter::isMultineArray(const Value &value)\n{\n  ArrayIndex const size = value.size();\n  bool isMultiLine = size * 3 >= rightMargin_;\n  childValues_.clear();\n  for (ArrayIndex index = 0; index < size && !isMultiLine; ++index)\n  {\n    const Value &childValue = value[index];\n    isMultiLine = ((childValue.isArray() || childValue.isObject()) &&\n                   childValue.size() > 0);\n  }\n  if (!isMultiLine) // check if line length > max line length\n  {\n    childValues_.reserve(size);\n    addChildValues_ = true;\n    ArrayIndex lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'\n    for (ArrayIndex index = 0; index < size; ++index)\n    {\n      if (hasCommentForValue(value[index]))\n      {\n        isMultiLine = true;\n      }\n      writeValue(value[index]);\n      lineLength += static_cast<ArrayIndex>(childValues_[index].length());\n    }\n    addChildValues_ = false;\n    isMultiLine = isMultiLine || lineLength >= rightMargin_;\n  }\n  return isMultiLine;\n}\n\nvoid StyledStreamWriter::pushValue(const JSONCPP_STRING &value)\n{\n  if (addChildValues_)\n    childValues_.push_back(value);\n  else\n    *document_ << value;\n}\n\nvoid StyledStreamWriter::writeIndent()\n{\n  // blep intended this to look at the so-far-written string\n  // to determine whether we are already indented, but\n  // with a stream we cannot do that. So we rely on some saved state.\n  // The caller checks indented_.\n  *document_ << '\\n'\n             << indentString_;\n}\n\nvoid StyledStreamWriter::writeWithIndent(const JSONCPP_STRING &value)\n{\n  if (!indented_)\n    writeIndent();\n  *document_ << value;\n  indented_ = false;\n}\n\nvoid StyledStreamWriter::indent() { indentString_ += indentation_; }\n\nvoid StyledStreamWriter::unindent()\n{\n  assert(indentString_.size() >= indentation_.size());\n  indentString_.resize(indentString_.size() - indentation_.size());\n}\n\nvoid StyledStreamWriter::writeCommentBeforeValue(const Value &root)\n{\n  if (!root.hasComment(commentBefore))\n    return;\n\n  if (!indented_)\n    writeIndent();\n  const JSONCPP_STRING &comment = root.getComment(commentBefore);\n  JSONCPP_STRING::const_iterator iter = comment.begin();\n  while (iter != comment.end())\n  {\n    *document_ << *iter;\n    if (*iter == '\\n' &&\n        ((iter + 1) != comment.end() && *(iter + 1) == '/'))\n      // writeIndent();  // would include newline\n      *document_ << indentString_;\n    ++iter;\n  }\n  indented_ = false;\n}\n\nvoid StyledStreamWriter::writeCommentAfterValueOnSameLine(const Value &root)\n{\n  if (root.hasComment(commentAfterOnSameLine))\n    *document_ << ' ' << root.getComment(commentAfterOnSameLine);\n\n  if (root.hasComment(commentAfter))\n  {\n    writeIndent();\n    *document_ << root.getComment(commentAfter);\n  }\n  indented_ = false;\n}\n\nbool StyledStreamWriter::hasCommentForValue(const Value &value)\n{\n  return value.hasComment(commentBefore) ||\n         value.hasComment(commentAfterOnSameLine) ||\n         value.hasComment(commentAfter);\n}\n\n//////////////////////////\n// BuiltStyledStreamWriter\n\n/// Scoped enums are not available until C++11.\nstruct CommentStyle\n{\n  /// Decide whether to write comments.\n  enum Enum\n  {\n    None, ///< Drop all comments.\n    Most, ///< Recover odd behavior of previous versions (not implemented yet).\n    All   ///< Keep all comments.\n  };\n};\n\nstruct BuiltStyledStreamWriter : public StreamWriter\n{\n  BuiltStyledStreamWriter(\n      JSONCPP_STRING const &indentation,\n      CommentStyle::Enum cs,\n      JSONCPP_STRING const &colonSymbol,\n      JSONCPP_STRING const &nullSymbol,\n      JSONCPP_STRING const &endingLineFeedSymbol,\n      bool useSpecialFloats,\n      unsigned int precision);\n  int write(Value const &root, JSONCPP_OSTREAM *sout) JSONCPP_OVERRIDE;\n\nprivate:\n  void writeValue(Value const &value);\n  void writeArrayValue(Value const &value);\n  bool isMultineArray(Value const &value);\n  void pushValue(JSONCPP_STRING const &value);\n  void writeIndent();\n  void writeWithIndent(JSONCPP_STRING const &value);\n  void indent();\n  void unindent();\n  void writeCommentBeforeValue(Value const &root);\n  void writeCommentAfterValueOnSameLine(Value const &root);\n  static bool hasCommentForValue(const Value &value);\n\n  typedef std::vector<JSONCPP_STRING> ChildValues;\n\n  ChildValues childValues_;\n  JSONCPP_STRING indentString_;\n  unsigned int rightMargin_;\n  JSONCPP_STRING indentation_;\n  CommentStyle::Enum cs_;\n  JSONCPP_STRING colonSymbol_;\n  JSONCPP_STRING nullSymbol_;\n  JSONCPP_STRING endingLineFeedSymbol_;\n  bool addChildValues_ : 1;\n  bool indented_ : 1;\n  bool useSpecialFloats_ : 1;\n  unsigned int precision_;\n};\nBuiltStyledStreamWriter::BuiltStyledStreamWriter(\n    JSONCPP_STRING const &indentation,\n    CommentStyle::Enum cs,\n    JSONCPP_STRING const &colonSymbol,\n    JSONCPP_STRING const &nullSymbol,\n    JSONCPP_STRING const &endingLineFeedSymbol,\n    bool useSpecialFloats,\n    unsigned int precision)\n    : rightMargin_(74), indentation_(indentation), cs_(cs), colonSymbol_(colonSymbol), nullSymbol_(nullSymbol), endingLineFeedSymbol_(endingLineFeedSymbol), addChildValues_(false), indented_(false), useSpecialFloats_(useSpecialFloats), precision_(precision)\n{\n}\nint BuiltStyledStreamWriter::write(Value const &root, JSONCPP_OSTREAM *sout)\n{\n  sout_ = sout;\n  addChildValues_ = false;\n  indented_ = true;\n  indentString_.clear();\n  writeCommentBeforeValue(root);\n  if (!indented_)\n    writeIndent();\n  indented_ = true;\n  writeValue(root);\n  writeCommentAfterValueOnSameLine(root);\n  *sout_ << endingLineFeedSymbol_;\n  sout_ = NULL;\n  return 0;\n}\nvoid BuiltStyledStreamWriter::writeValue(Value const &value)\n{\n  switch (value.type())\n  {\n  case nullValue:\n    pushValue(nullSymbol_);\n    break;\n  case intValue:\n    pushValue(valueToString(value.asLargestInt()));\n    break;\n  case uintValue:\n    pushValue(valueToString(value.asLargestUInt()));\n    break;\n  case realValue:\n    pushValue(valueToString(value.asDouble(), useSpecialFloats_, precision_));\n    break;\n  case stringValue:\n  {\n    // Is NULL is possible for value.string_? No.\n    char const *str;\n    char const *end;\n    bool ok = value.getString(&str, &end);\n    if (ok)\n      pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str)));\n    else\n      pushValue(\"\");\n    break;\n  }\n  case booleanValue:\n    pushValue(valueToString(value.asBool()));\n    break;\n  case arrayValue:\n    writeArrayValue(value);\n    break;\n  case objectValue:\n  {\n    Value::Members members(value.getMemberNames());\n    if (members.empty())\n      pushValue(\"{}\");\n    else\n    {\n      writeWithIndent(\"{\");\n      indent();\n      Value::Members::iterator it = members.begin();\n      for (;;)\n      {\n        JSONCPP_STRING const &name = *it;\n        Value const &childValue = value[name];\n        writeCommentBeforeValue(childValue);\n        writeWithIndent(valueToQuotedStringN(name.data(), static_cast<unsigned>(name.length())));\n        *sout_ << colonSymbol_;\n        writeValue(childValue);\n        if (++it == members.end())\n        {\n          writeCommentAfterValueOnSameLine(childValue);\n          break;\n        }\n        *sout_ << \",\";\n        writeCommentAfterValueOnSameLine(childValue);\n      }\n      unindent();\n      writeWithIndent(\"}\");\n    }\n  }\n  break;\n  }\n}\n\nvoid BuiltStyledStreamWriter::writeArrayValue(Value const &value)\n{\n  unsigned size = value.size();\n  if (size == 0)\n    pushValue(\"[]\");\n  else\n  {\n    bool isMultiLine = (cs_ == CommentStyle::All) || isMultineArray(value);\n    if (isMultiLine)\n    {\n      writeWithIndent(\"[\");\n      indent();\n      bool hasChildValue = !childValues_.empty();\n      unsigned index = 0;\n      for (;;)\n      {\n        Value const &childValue = value[index];\n        writeCommentBeforeValue(childValue);\n        if (hasChildValue)\n          writeWithIndent(childValues_[index]);\n        else\n        {\n          if (!indented_)\n            writeIndent();\n          indented_ = true;\n          writeValue(childValue);\n          indented_ = false;\n        }\n        if (++index == size)\n        {\n          writeCommentAfterValueOnSameLine(childValue);\n          break;\n        }\n        *sout_ << \",\";\n        writeCommentAfterValueOnSameLine(childValue);\n      }\n      unindent();\n      writeWithIndent(\"]\");\n    }\n    else // output on a single line\n    {\n      assert(childValues_.size() == size);\n      *sout_ << \"[\";\n      if (!indentation_.empty())\n        *sout_ << \" \";\n      for (unsigned index = 0; index < size; ++index)\n      {\n        if (index > 0)\n          *sout_ << ((!indentation_.empty()) ? \", \" : \",\");\n        *sout_ << childValues_[index];\n      }\n      if (!indentation_.empty())\n        *sout_ << \" \";\n      *sout_ << \"]\";\n    }\n  }\n}\n\nbool BuiltStyledStreamWriter::isMultineArray(Value const &value)\n{\n  ArrayIndex const size = value.size();\n  bool isMultiLine = size * 3 >= rightMargin_;\n  childValues_.clear();\n  for (ArrayIndex index = 0; index < size && !isMultiLine; ++index)\n  {\n    Value const &childValue = value[index];\n    isMultiLine = ((childValue.isArray() || childValue.isObject()) &&\n                   childValue.size() > 0);\n  }\n  if (!isMultiLine) // check if line length > max line length\n  {\n    childValues_.reserve(size);\n    addChildValues_ = true;\n    ArrayIndex lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'\n    for (ArrayIndex index = 0; index < size; ++index)\n    {\n      if (hasCommentForValue(value[index]))\n      {\n        isMultiLine = true;\n      }\n      writeValue(value[index]);\n      lineLength += static_cast<ArrayIndex>(childValues_[index].length());\n    }\n    addChildValues_ = false;\n    isMultiLine = isMultiLine || lineLength >= rightMargin_;\n  }\n  return isMultiLine;\n}\n\nvoid BuiltStyledStreamWriter::pushValue(JSONCPP_STRING const &value)\n{\n  if (addChildValues_)\n    childValues_.push_back(value);\n  else\n    *sout_ << value;\n}\n\nvoid BuiltStyledStreamWriter::writeIndent()\n{\n  // blep intended this to look at the so-far-written string\n  // to determine whether we are already indented, but\n  // with a stream we cannot do that. So we rely on some saved state.\n  // The caller checks indented_.\n\n  if (!indentation_.empty())\n  {\n    // In this case, drop newlines too.\n    *sout_ << '\\n'\n           << indentString_;\n  }\n}\n\nvoid BuiltStyledStreamWriter::writeWithIndent(JSONCPP_STRING const &value)\n{\n  if (!indented_)\n    writeIndent();\n  *sout_ << value;\n  indented_ = false;\n}\n\nvoid BuiltStyledStreamWriter::indent() { indentString_ += indentation_; }\n\nvoid BuiltStyledStreamWriter::unindent()\n{\n  assert(indentString_.size() >= indentation_.size());\n  indentString_.resize(indentString_.size() - indentation_.size());\n}\n\nvoid BuiltStyledStreamWriter::writeCommentBeforeValue(Value const &root)\n{\n  if (cs_ == CommentStyle::None)\n    return;\n  if (!root.hasComment(commentBefore))\n    return;\n\n  if (!indented_)\n    writeIndent();\n  const JSONCPP_STRING &comment = root.getComment(commentBefore);\n  JSONCPP_STRING::const_iterator iter = comment.begin();\n  while (iter != comment.end())\n  {\n    *sout_ << *iter;\n    if (*iter == '\\n' &&\n        ((iter + 1) != comment.end() && *(iter + 1) == '/'))\n      // writeIndent();  // would write extra newline\n      *sout_ << indentString_;\n    ++iter;\n  }\n  indented_ = false;\n}\n\nvoid BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(Value const &root)\n{\n  if (cs_ == CommentStyle::None)\n    return;\n  if (root.hasComment(commentAfterOnSameLine))\n    *sout_ << \" \" + root.getComment(commentAfterOnSameLine);\n\n  if (root.hasComment(commentAfter))\n  {\n    writeIndent();\n    *sout_ << root.getComment(commentAfter);\n  }\n}\n\n// static\nbool BuiltStyledStreamWriter::hasCommentForValue(const Value &value)\n{\n  return value.hasComment(commentBefore) ||\n         value.hasComment(commentAfterOnSameLine) ||\n         value.hasComment(commentAfter);\n}\n\n///////////////\n// StreamWriter\n\nStreamWriter::StreamWriter()\n    : sout_(NULL)\n{\n}\nStreamWriter::~StreamWriter()\n{\n}\nStreamWriter::Factory::~Factory()\n{\n}\nStreamWriterBuilder::StreamWriterBuilder()\n{\n  setDefaults(&settings_);\n}\nStreamWriterBuilder::~StreamWriterBuilder()\n{\n}\nStreamWriter *StreamWriterBuilder::newStreamWriter() const\n{\n  JSONCPP_STRING indentation = settings_[\"indentation\"].asString();\n  JSONCPP_STRING cs_str = settings_[\"commentStyle\"].asString();\n  bool eyc = settings_[\"enableYAMLCompatibility\"].asBool();\n  bool dnp = settings_[\"dropNullPlaceholders\"].asBool();\n  bool usf = settings_[\"useSpecialFloats\"].asBool();\n  unsigned int pre = settings_[\"precision\"].asUInt();\n  CommentStyle::Enum cs = CommentStyle::All;\n  if (cs_str == \"All\")\n  {\n    cs = CommentStyle::All;\n  }\n  else if (cs_str == \"None\")\n  {\n    cs = CommentStyle::None;\n  }\n  else\n  {\n    throwRuntimeError(\"commentStyle must be 'All' or 'None'\");\n  }\n  JSONCPP_STRING colonSymbol = \" : \";\n  if (eyc)\n  {\n    colonSymbol = \": \";\n  }\n  else if (indentation.empty())\n  {\n    colonSymbol = \":\";\n  }\n  JSONCPP_STRING nullSymbol = \"null\";\n  if (dnp)\n  {\n    nullSymbol.clear();\n  }\n  if (pre > 17)\n    pre = 17;\n  JSONCPP_STRING endingLineFeedSymbol;\n  return new BuiltStyledStreamWriter(\n      indentation, cs,\n      colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre);\n}\nstatic void getValidWriterKeys(std::set<JSONCPP_STRING> *valid_keys)\n{\n  valid_keys->clear();\n  valid_keys->insert(\"indentation\");\n  valid_keys->insert(\"commentStyle\");\n  valid_keys->insert(\"enableYAMLCompatibility\");\n  valid_keys->insert(\"dropNullPlaceholders\");\n  valid_keys->insert(\"useSpecialFloats\");\n  valid_keys->insert(\"precision\");\n}\nbool StreamWriterBuilder::validate(Json::Value *invalid) const\n{\n  Json::Value my_invalid;\n  if (!invalid)\n    invalid = &my_invalid; // so we do not need to test for NULL\n  Json::Value &inv = *invalid;\n  std::set<JSONCPP_STRING> valid_keys;\n  getValidWriterKeys(&valid_keys);\n  Value::Members keys = settings_.getMemberNames();\n  size_t n = keys.size();\n  for (size_t i = 0; i < n; ++i)\n  {\n    JSONCPP_STRING const &key = keys[i];\n    if (valid_keys.find(key) == valid_keys.end())\n    {\n      inv[key] = settings_[key];\n    }\n  }\n  return 0u == inv.size();\n}\nValue &StreamWriterBuilder::operator[](JSONCPP_STRING key)\n{\n  return settings_[key];\n}\n// static\nvoid StreamWriterBuilder::setDefaults(Json::Value *settings)\n{\n  //! [StreamWriterBuilderDefaults]\n  (*settings)[\"commentStyle\"] = \"All\";\n  (*settings)[\"indentation\"] = \"\\t\";\n  (*settings)[\"enableYAMLCompatibility\"] = false;\n  (*settings)[\"dropNullPlaceholders\"] = false;\n  (*settings)[\"useSpecialFloats\"] = false;\n  (*settings)[\"precision\"] = 17;\n  //! [StreamWriterBuilderDefaults]\n}\n\nJSONCPP_STRING writeString(StreamWriter::Factory const &builder, Value const &root)\n{\n  JSONCPP_OSTRINGSTREAM sout;\n  StreamWriterPtr const writer(builder.newStreamWriter());\n  writer->write(root, &sout);\n  return sout.str();\n}\n\nJSONCPP_OSTREAM &operator<<(JSONCPP_OSTREAM &sout, Value const &root)\n{\n  StreamWriterBuilder builder;\n  StreamWriterPtr const writer(builder.newStreamWriter());\n  writer->write(root, &sout);\n  return sout;\n}\n\n} // namespace Json\n\n// //////////////////////////////////////////////////////////////////////\n// End of content of file: src/lib_json/json_writer.cpp\n// //////////////////////////////////////////////////////////////////////\n"
  },
  {
    "path": "thirdparty/mongoose/CMakeLists.txt",
    "content": "FILE(GLOB_RECURSE mongoose_SOURCES \"*.c\")\n#aux_source_directory(${CMAKE_CURRENT_LIST_DIR})\n#SET(mongoose_SOURCES ${CMAKE_CURRENT_LIST_DIR})\n\n# Mongoose does not compile with strict aliasing.\nSET(CMAKE_C_FLAGS \"${CMAKE_C_FLAGS} -fno-strict-aliasing\")\nIF(MG_ENABLE_DEBUG)\nADD_DEFINITIONS(-DMG_ENABLE_DEBUG)\nELSE()\n  ADD_DEFINITIONS(-DMG_DISABLE_STDIO)\nENDIF()\n                                                                                \nADD_LIBRARY(mongoose_static STATIC ${mongoose_SOURCES})\nSET_TARGET_PROPERTIES(mongoose_static PROPERTIES OUTPUT_NAME mongoose)\nTARGET_LINK_LIBRARIES(mongoose_static)\nINSTALL(TARGETS mongoose_static DESTINATION lib)\n\nIF(ENABLE_SHARED_LIBS)\n  ADD_LIBRARY(mongoose_shared SHARED ${mongoose_SOURCES})\n  SET_TARGET_PROPERTIES(mongoose_shared PROPERTIES OUTPUT_NAME mongoose)\n  TARGET_LINK_LIBRARIES(mongoose_shared)\n  INSTALL(TARGETS mongoose_shared DESTINATION lib)\nENDIF()\n"
  },
  {
    "path": "thirdparty/mongoose/mongoose.c",
    "content": "#include \"mongoose.h\"\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/internal.h\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_MONGOOSE_SRC_INTERNAL_H_\n#define CS_MONGOOSE_SRC_INTERNAL_H_\n\n#ifndef MG_MALLOC\n#define MG_MALLOC malloc\n#endif\n\n#ifndef MG_CALLOC\n#define MG_CALLOC calloc\n#endif\n\n#ifndef MG_REALLOC\n#define MG_REALLOC realloc\n#endif\n\n#ifndef MG_FREE\n#define MG_FREE free\n#endif\n\n#ifndef MBUF_REALLOC\n#define MBUF_REALLOC MG_REALLOC\n#endif\n\n#ifndef MBUF_FREE\n#define MBUF_FREE MG_FREE\n#endif\n\n#define MG_SET_PTRPTR(_ptr, _v) \\\n  do                            \\\n  {                             \\\n    if (_ptr)                   \\\n      *(_ptr) = _v;             \\\n  } while (0)\n\n#ifndef MG_INTERNAL\n#define MG_INTERNAL static\n#endif\n\n#ifdef PICOTCP\n#define NO_LIBC\n#define MG_DISABLE_PFS\n#endif\n\n/* Amalgamated: #include \"mongoose/src/net.h\" */\n/* Amalgamated: #include \"mongoose/src/http.h\" */\n/* Amalgamated: #include \"common/cs_dbg.h\" */\n\n#define MG_CTL_MSG_MESSAGE_SIZE 8192\n\n/* internals that need to be accessible in unit tests */\nMG_INTERNAL struct mg_connection *mg_do_connect(struct mg_connection *nc,\n                                                int proto,\n                                                union socket_address *sa);\n\nMG_INTERNAL int mg_parse_address(const char *str, union socket_address *sa,\n                                 int *proto, char *host, size_t host_len);\nMG_INTERNAL void mg_call(struct mg_connection *nc,\n                         mg_event_handler_t ev_handler, int ev, void *ev_data);\nvoid mg_forward(struct mg_connection *from, struct mg_connection *to);\nvoid mg_add_conn(struct mg_mgr *mgr, struct mg_connection *c);\nvoid mg_remove_conn(struct mg_connection *c);\nMG_INTERNAL struct mg_connection *mg_create_connection(\n    struct mg_mgr *mgr, mg_event_handler_t callback,\n    struct mg_add_sock_opts opts);\n#ifdef _WIN32\n/* Retur value is the same as for MultiByteToWideChar. */\nint to_wchar(const char *path, wchar_t *wbuf, size_t wbuf_len);\n#endif\n\nstruct ctl_msg\n{\n  mg_event_handler_t callback;\n  char message[MG_CTL_MSG_MESSAGE_SIZE];\n};\n\n#if MG_ENABLE_MQTT\nstruct mg_mqtt_message;\nMG_INTERNAL int parse_mqtt(struct mbuf *io, struct mg_mqtt_message *mm);\n#endif\n\n/* Forward declarations for testing. */\nextern void *(*test_malloc)(size_t size);\nextern void *(*test_calloc)(size_t count, size_t size);\n\n#ifndef MIN\n#define MIN(a, b) ((a) < (b) ? (a) : (b))\n#endif\n\n#if MG_ENABLE_HTTP\nstruct mg_serve_http_opts;\n\n/*\n * Reassemble the content of the buffer (buf, blen) which should be\n * in the HTTP chunked encoding, by collapsing data chunks to the\n * beginning of the buffer.\n *\n * If chunks get reassembled, modify hm->body to point to the reassembled\n * body and fire MG_EV_HTTP_CHUNK event. If handler sets MG_F_DELETE_CHUNK\n * in nc->flags, delete reassembled body from the mbuf.\n *\n * Return reassembled body size.\n */\nMG_INTERNAL size_t mg_handle_chunked(struct mg_connection *nc,\n                                     struct http_message *hm, char *buf,\n                                     size_t blen);\n\nMG_INTERNAL int mg_http_common_url_parse(const char *url, const char *schema,\n                                         const char *schema_tls, int *use_ssl,\n                                         char **user, char **pass, char **addr,\n                                         int *port_i, const char **path);\n\n#if MG_ENABLE_FILESYSTEM\nMG_INTERNAL int mg_uri_to_local_path(struct http_message *hm,\n                                     const struct mg_serve_http_opts *opts,\n                                     char **local_path,\n                                     struct mg_str *remainder);\nMG_INTERNAL time_t mg_parse_date_string(const char *datetime);\nMG_INTERNAL int mg_is_not_modified(struct http_message *hm, cs_stat_t *st);\n#endif\n#if MG_ENABLE_HTTP_CGI\nMG_INTERNAL void mg_handle_cgi(struct mg_connection *nc, const char *prog,\n                               const struct mg_str *path_info,\n                               const struct http_message *hm,\n                               const struct mg_serve_http_opts *opts);\nstruct mg_http_proto_data_cgi;\nMG_INTERNAL void mg_http_free_proto_data_cgi(struct mg_http_proto_data_cgi *d);\n#endif\n#if MG_ENABLE_HTTP_SSI\nMG_INTERNAL void mg_handle_ssi_request(struct mg_connection *nc,\n                                       struct http_message *hm,\n                                       const char *path,\n                                       const struct mg_serve_http_opts *opts);\n#endif\n#if MG_ENABLE_HTTP_WEBDAV\nMG_INTERNAL int mg_is_dav_request(const struct mg_str *s);\nMG_INTERNAL void mg_handle_propfind(struct mg_connection *nc, const char *path,\n                                    cs_stat_t *stp, struct http_message *hm,\n                                    struct mg_serve_http_opts *opts);\nMG_INTERNAL void mg_handle_lock(struct mg_connection *nc, const char *path);\nMG_INTERNAL void mg_handle_mkcol(struct mg_connection *nc, const char *path,\n                                 struct http_message *hm);\nMG_INTERNAL void mg_handle_move(struct mg_connection *c,\n                                const struct mg_serve_http_opts *opts,\n                                const char *path, struct http_message *hm);\nMG_INTERNAL void mg_handle_delete(struct mg_connection *nc,\n                                  const struct mg_serve_http_opts *opts,\n                                  const char *path);\nMG_INTERNAL void mg_handle_put(struct mg_connection *nc, const char *path,\n                               struct http_message *hm);\n#endif\n#if MG_ENABLE_HTTP_WEBSOCKET\nMG_INTERNAL void mg_ws_handler(struct mg_connection *nc, int ev, void *ev_data);\nMG_INTERNAL void mg_ws_handshake(struct mg_connection *nc,\n                                 const struct mg_str *key);\n#endif\n#endif /* MG_ENABLE_HTTP */\n\nMG_INTERNAL int mg_get_errno(void);\n\nMG_INTERNAL void mg_close_conn(struct mg_connection *conn);\n\nMG_INTERNAL int mg_http_common_url_parse(const char *url, const char *schema,\n                                         const char *schema_tls, int *use_ssl,\n                                         char **user, char **pass, char **addr,\n                                         int *port_i, const char **path);\n\n#if MG_ENABLE_SNTP\nMG_INTERNAL int mg_sntp_parse_reply(const char *buf, int len,\n                                    struct mg_sntp_message *msg);\n#endif\n\n#endif /* CS_MONGOOSE_SRC_INTERNAL_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/cs_dbg.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_COMMON_CS_DBG_H_\n#define CS_COMMON_CS_DBG_H_\n\n/* Amalgamated: #include \"common/platform.h\" */\n\n#if CS_ENABLE_STDIO\n#include <stdio.h>\n#endif\n\n#ifndef CS_ENABLE_DEBUG\n#define CS_ENABLE_DEBUG 0\n#endif\n\n#ifndef CS_LOG_ENABLE_TS_DIFF\n#define CS_LOG_ENABLE_TS_DIFF 0\n#endif\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif /* __cplusplus */\n\n  enum cs_log_level\n  {\n    LL_NONE = -1,\n    LL_ERROR = 0,\n    LL_WARN = 1,\n    LL_INFO = 2,\n    LL_DEBUG = 3,\n    LL_VERBOSE_DEBUG = 4,\n\n    _LL_MIN = -2,\n    _LL_MAX = 5,\n  };\n\n  void cs_log_set_level(enum cs_log_level level);\n\n#if CS_ENABLE_STDIO\n\n  void cs_log_set_file(FILE *file);\n\n  extern enum cs_log_level cs_log_level;\n  void cs_log_print_prefix(const char *func);\n  void cs_log_printf(const char *fmt, ...);\n\n#define LOG(l, x)                    \\\n  do                                 \\\n  {                                  \\\n    if (cs_log_level >= l)           \\\n    {                                \\\n      cs_log_print_prefix(__func__); \\\n      cs_log_printf x;               \\\n    }                                \\\n  } while (0)\n\n#ifndef CS_NDEBUG\n\n#define DBG(x)                            \\\n  do                                      \\\n  {                                       \\\n    if (cs_log_level >= LL_VERBOSE_DEBUG) \\\n    {                                     \\\n      cs_log_print_prefix(__func__);      \\\n      cs_log_printf x;                    \\\n    }                                     \\\n  } while (0)\n\n#else /* NDEBUG */\n\n#define DBG(x)\n\n#endif\n\n#else /* CS_ENABLE_STDIO */\n\n#define LOG(l, x)\n#define DBG(x)\n\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif /* CS_COMMON_CS_DBG_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/cs_dbg.c\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n/* Amalgamated: #include \"common/cs_dbg.h\" */\n\n#include <stdarg.h>\n#include <stdio.h>\n\n/* Amalgamated: #include \"common/cs_time.h\" */\n\nenum cs_log_level cs_log_level =\n#if CS_ENABLE_DEBUG\n    LL_VERBOSE_DEBUG;\n#else\n    LL_ERROR;\n#endif\n\n#if CS_ENABLE_STDIO\n\nFILE *cs_log_file = NULL;\n\n#if CS_LOG_ENABLE_TS_DIFF\ndouble cs_log_ts;\n#endif\n\nvoid cs_log_print_prefix(const char *func)\n{\n  if (cs_log_file == NULL)\n    cs_log_file = stderr;\n  fprintf(cs_log_file, \"%-20s \", func);\n#if CS_LOG_ENABLE_TS_DIFF\n  {\n    double now = cs_time();\n    fprintf(cs_log_file, \"%7u \", (unsigned int)((now - cs_log_ts) * 1000000));\n    cs_log_ts = now;\n  }\n#endif\n}\n\nvoid cs_log_printf(const char *fmt, ...)\n{\n  va_list ap;\n  va_start(ap, fmt);\n  vfprintf(cs_log_file, fmt, ap);\n  va_end(ap);\n  fputc('\\n', cs_log_file);\n  fflush(cs_log_file);\n}\n\nvoid cs_log_set_file(FILE *file)\n{\n  cs_log_file = file;\n}\n\n#endif /* CS_ENABLE_STDIO */\n\nvoid cs_log_set_level(enum cs_log_level level)\n{\n  cs_log_level = level;\n#if CS_LOG_ENABLE_TS_DIFF && CS_ENABLE_STDIO\n  cs_log_ts = cs_time();\n#endif\n}\n#ifdef MG_MODULE_LINES\n#line 1 \"common/base64.c\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef EXCLUDE_COMMON\n\n/* Amalgamated: #include \"common/base64.h\" */\n\n#include <string.h>\n\n/* Amalgamated: #include \"common/cs_dbg.h\" */\n\n/* ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ */\n\n#define NUM_UPPERCASES ('Z' - 'A' + 1)\n#define NUM_LETTERS (NUM_UPPERCASES * 2)\n#define NUM_DIGITS ('9' - '0' + 1)\n\n/*\n * Emit a base64 code char.\n *\n * Doesn't use memory, thus it's safe to use to safely dump memory in crashdumps\n */\nstatic void cs_base64_emit_code(struct cs_base64_ctx *ctx, int v)\n{\n  if (v < NUM_UPPERCASES)\n  {\n    ctx->b64_putc(v + 'A', ctx->user_data);\n  }\n  else if (v < (NUM_LETTERS))\n  {\n    ctx->b64_putc(v - NUM_UPPERCASES + 'a', ctx->user_data);\n  }\n  else if (v < (NUM_LETTERS + NUM_DIGITS))\n  {\n    ctx->b64_putc(v - NUM_LETTERS + '0', ctx->user_data);\n  }\n  else\n  {\n    ctx->b64_putc(v - NUM_LETTERS - NUM_DIGITS == 0 ? '+' : '/',\n                  ctx->user_data);\n  }\n}\n\nstatic void cs_base64_emit_chunk(struct cs_base64_ctx *ctx)\n{\n  int a, b, c;\n\n  a = ctx->chunk[0];\n  b = ctx->chunk[1];\n  c = ctx->chunk[2];\n\n  cs_base64_emit_code(ctx, a >> 2);\n  cs_base64_emit_code(ctx, ((a & 3) << 4) | (b >> 4));\n  if (ctx->chunk_size > 1)\n  {\n    cs_base64_emit_code(ctx, (b & 15) << 2 | (c >> 6));\n  }\n  if (ctx->chunk_size > 2)\n  {\n    cs_base64_emit_code(ctx, c & 63);\n  }\n}\n\nvoid cs_base64_init(struct cs_base64_ctx *ctx, cs_base64_putc_t b64_putc,\n                    void *user_data)\n{\n  ctx->chunk_size = 0;\n  ctx->b64_putc = b64_putc;\n  ctx->user_data = user_data;\n}\n\nvoid cs_base64_update(struct cs_base64_ctx *ctx, const char *str, size_t len)\n{\n  const unsigned char *src = (const unsigned char *)str;\n  size_t i;\n  for (i = 0; i < len; i++)\n  {\n    ctx->chunk[ctx->chunk_size++] = src[i];\n    if (ctx->chunk_size == 3)\n    {\n      cs_base64_emit_chunk(ctx);\n      ctx->chunk_size = 0;\n    }\n  }\n}\n\nvoid cs_base64_finish(struct cs_base64_ctx *ctx)\n{\n  if (ctx->chunk_size > 0)\n  {\n    int i;\n    memset(&ctx->chunk[ctx->chunk_size], 0, 3 - ctx->chunk_size);\n    cs_base64_emit_chunk(ctx);\n    for (i = 0; i < (3 - ctx->chunk_size); i++)\n    {\n      ctx->b64_putc('=', ctx->user_data);\n    }\n  }\n}\n\n#define BASE64_ENCODE_BODY                                                \\\n  static const char *b64 =                                                \\\n      \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\"; \\\n  int i, j, a, b, c;                                                      \\\n                                                                          \\\n  for (i = j = 0; i < src_len; i += 3)                                    \\\n  {                                                                       \\\n    a = src[i];                                                           \\\n    b = i + 1 >= src_len ? 0 : src[i + 1];                                \\\n    c = i + 2 >= src_len ? 0 : src[i + 2];                                \\\n                                                                          \\\n    BASE64_OUT(b64[a >> 2]);                                              \\\n    BASE64_OUT(b64[((a & 3) << 4) | (b >> 4)]);                           \\\n    if (i + 1 < src_len)                                                  \\\n    {                                                                     \\\n      BASE64_OUT(b64[(b & 15) << 2 | (c >> 6)]);                          \\\n    }                                                                     \\\n    if (i + 2 < src_len)                                                  \\\n    {                                                                     \\\n      BASE64_OUT(b64[c & 63]);                                            \\\n    }                                                                     \\\n  }                                                                       \\\n                                                                          \\\n  while (j % 4 != 0)                                                      \\\n  {                                                                       \\\n    BASE64_OUT('=');                                                      \\\n  }                                                                       \\\n  BASE64_FLUSH()\n\n#define BASE64_OUT(ch) \\\n  do                   \\\n  {                    \\\n    dst[j++] = (ch);   \\\n  } while (0)\n\n#define BASE64_FLUSH() \\\n  do                   \\\n  {                    \\\n    dst[j++] = '\\0';   \\\n  } while (0)\n\nvoid cs_base64_encode(const unsigned char *src, int src_len, char *dst)\n{\n  BASE64_ENCODE_BODY;\n}\n\n#undef BASE64_OUT\n#undef BASE64_FLUSH\n\n#if CS_ENABLE_STDIO\n#define BASE64_OUT(ch)      \\\n  do                        \\\n  {                         \\\n    fprintf(f, \"%c\", (ch)); \\\n    j++;                    \\\n  } while (0)\n\n#define BASE64_FLUSH()\n\nvoid cs_fprint_base64(FILE *f, const unsigned char *src, int src_len)\n{\n  BASE64_ENCODE_BODY;\n}\n\n#undef BASE64_OUT\n#undef BASE64_FLUSH\n#endif /* CS_ENABLE_STDIO */\n\n/* Convert one byte of encoded base64 input stream to 6-bit chunk */\nstatic unsigned char from_b64(unsigned char ch)\n{\n  /* Inverse lookup map */\n  static const unsigned char tab[128] = {\n      255, 255, 255, 255,\n      255, 255, 255, 255, /*  0 */\n      255, 255, 255, 255,\n      255, 255, 255, 255, /*  8 */\n      255, 255, 255, 255,\n      255, 255, 255, 255, /*  16 */\n      255, 255, 255, 255,\n      255, 255, 255, 255, /*  24 */\n      255, 255, 255, 255,\n      255, 255, 255, 255, /*  32 */\n      255, 255, 255, 62,\n      255, 255, 255, 63, /*  40 */\n      52, 53, 54, 55,\n      56, 57, 58, 59, /*  48 */\n      60, 61, 255, 255,\n      255, 200, 255, 255, /*  56   '=' is 200, on index 61 */\n      255, 0, 1, 2,\n      3, 4, 5, 6, /*  64 */\n      7, 8, 9, 10,\n      11, 12, 13, 14, /*  72 */\n      15, 16, 17, 18,\n      19, 20, 21, 22, /*  80 */\n      23, 24, 25, 255,\n      255, 255, 255, 255, /*  88 */\n      255, 26, 27, 28,\n      29, 30, 31, 32, /*  96 */\n      33, 34, 35, 36,\n      37, 38, 39, 40, /*  104 */\n      41, 42, 43, 44,\n      45, 46, 47, 48, /*  112 */\n      49, 50, 51, 255,\n      255, 255, 255, 255, /*  120 */\n  };\n  return tab[ch & 127];\n}\n\nint cs_base64_decode(const unsigned char *s, int len, char *dst)\n{\n  unsigned char a, b, c, d;\n  int orig_len = len;\n  while (len >= 4 && (a = from_b64(s[0])) != 255 &&\n         (b = from_b64(s[1])) != 255 && (c = from_b64(s[2])) != 255 &&\n         (d = from_b64(s[3])) != 255)\n  {\n    s += 4;\n    len -= 4;\n    if (a == 200 || b == 200)\n      break; /* '=' can't be there */\n    *dst++ = a << 2 | b >> 4;\n    if (c == 200)\n      break;\n    *dst++ = b << 4 | c >> 2;\n    if (d == 200)\n      break;\n    *dst++ = c << 6 | d;\n  }\n  *dst = 0;\n  return orig_len - len;\n}\n\n#endif /* EXCLUDE_COMMON */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/cs_dirent.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_COMMON_CS_DIRENT_H_\n#define CS_COMMON_CS_DIRENT_H_\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif /* __cplusplus */\n\n#ifndef CS_ENABLE_SPIFFS\n#define CS_ENABLE_SPIFFS 0\n#endif\n\n#if CS_ENABLE_SPIFFS\n\n#include <spiffs.h>\n\n  typedef struct\n  {\n    spiffs_DIR dh;\n    struct spiffs_dirent de;\n  } DIR;\n\n#define d_name name\n#define dirent spiffs_dirent\n\n  int rmdir(const char *path);\n  int mkdir(const char *path, mode_t mode);\n\n#endif\n\n#if defined(_WIN32)\n  struct dirent\n  {\n    char d_name[MAX_PATH];\n  };\n\n  typedef struct DIR\n  {\n    HANDLE handle;\n    WIN32_FIND_DATAW info;\n    struct dirent result;\n  } DIR;\n#endif\n\n#if defined(_WIN32) || CS_ENABLE_SPIFFS\n  DIR *opendir(const char *dir_name);\n  int closedir(DIR *dir);\n  struct dirent *readdir(DIR *dir);\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif /* CS_COMMON_CS_DIRENT_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/cs_dirent.c\"\n#endif\n/*\n * Copyright (c) 2015 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef EXCLUDE_COMMON\n\n/* Amalgamated: #include \"common/cs_dirent.h\" */\n\n/*\n * This file contains POSIX opendir/closedir/readdir API implementation\n * for systems which do not natively support it (e.g. Windows).\n */\n\n#ifndef MG_FREE\n#define MG_FREE free\n#endif\n\n#ifndef MG_MALLOC\n#define MG_MALLOC malloc\n#endif\n\n#ifdef _WIN32\nDIR *opendir(const char *name)\n{\n  DIR *dir = NULL;\n  wchar_t wpath[MAX_PATH];\n  DWORD attrs;\n\n  if (name == NULL)\n  {\n    SetLastError(ERROR_BAD_ARGUMENTS);\n  }\n  else if ((dir = (DIR *)MG_MALLOC(sizeof(*dir))) == NULL)\n  {\n    SetLastError(ERROR_NOT_ENOUGH_MEMORY);\n  }\n  else\n  {\n    to_wchar(name, wpath, ARRAY_SIZE(wpath));\n    attrs = GetFileAttributesW(wpath);\n    if (attrs != 0xFFFFFFFF && (attrs & FILE_ATTRIBUTE_DIRECTORY))\n    {\n      (void)wcscat(wpath, L\"\\\\*\");\n      dir->handle = FindFirstFileW(wpath, &dir->info);\n      dir->result.d_name[0] = '\\0';\n    }\n    else\n    {\n      MG_FREE(dir);\n      dir = NULL;\n    }\n  }\n\n  return dir;\n}\n\nint closedir(DIR *dir)\n{\n  int result = 0;\n\n  if (dir != NULL)\n  {\n    if (dir->handle != INVALID_HANDLE_VALUE)\n      result = FindClose(dir->handle) ? 0 : -1;\n    MG_FREE(dir);\n  }\n  else\n  {\n    result = -1;\n    SetLastError(ERROR_BAD_ARGUMENTS);\n  }\n\n  return result;\n}\n\nstruct dirent *readdir(DIR *dir)\n{\n  struct dirent *result = NULL;\n\n  if (dir)\n  {\n    if (dir->handle != INVALID_HANDLE_VALUE)\n    {\n      result = &dir->result;\n      (void)WideCharToMultiByte(CP_UTF8, 0, dir->info.cFileName, -1,\n                                result->d_name, sizeof(result->d_name), NULL,\n                                NULL);\n\n      if (!FindNextFileW(dir->handle, &dir->info))\n      {\n        (void)FindClose(dir->handle);\n        dir->handle = INVALID_HANDLE_VALUE;\n      }\n    }\n    else\n    {\n      SetLastError(ERROR_FILE_NOT_FOUND);\n    }\n  }\n  else\n  {\n    SetLastError(ERROR_BAD_ARGUMENTS);\n  }\n\n  return result;\n}\n#endif\n\n#if CS_ENABLE_SPIFFS\n\nDIR *opendir(const char *dir_name)\n{\n  DIR *dir = NULL;\n  extern spiffs fs;\n\n  if (dir_name != NULL && (dir = (DIR *)malloc(sizeof(*dir))) != NULL &&\n      SPIFFS_opendir(&fs, (char *)dir_name, &dir->dh) == NULL)\n  {\n    free(dir);\n    dir = NULL;\n  }\n\n  return dir;\n}\n\nint closedir(DIR *dir)\n{\n  if (dir != NULL)\n  {\n    SPIFFS_closedir(&dir->dh);\n    free(dir);\n  }\n  return 0;\n}\n\nstruct dirent *readdir(DIR *dir)\n{\n  return SPIFFS_readdir(&dir->dh, &dir->de);\n}\n\n/* SPIFFs doesn't support directory operations */\nint rmdir(const char *path)\n{\n  (void)path;\n  return ENOTDIR;\n}\n\nint mkdir(const char *path, mode_t mode)\n{\n  (void)path;\n  (void)mode;\n  /* for spiffs supports only root dir, which comes from mongoose as '.' */\n  return (strlen(path) == 1 && *path == '.') ? 0 : ENOTDIR;\n}\n\n#endif /* CS_ENABLE_SPIFFS */\n\n#endif /* EXCLUDE_COMMON */\n\n/* ISO C requires a translation unit to contain at least one declaration */\ntypedef int cs_dirent_dummy;\n#ifdef MG_MODULE_LINES\n#line 1 \"common/cs_time.c\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n/* Amalgamated: #include \"common/cs_time.h\" */\n\n#ifndef _WIN32\n#include <stddef.h>\n/*\n * There is no sys/time.h on ARMCC.\n */\n#if !(defined(__ARMCC_VERSION) || defined(__ICCARM__)) && \\\n    !defined(__TI_COMPILER_VERSION__) &&                  \\\n    (!defined(CS_PLATFORM) || CS_PLATFORM != CS_P_NXP_LPC)\n#include <sys/time.h>\n#endif\n#else\n#include <windows.h>\n#endif\n\ndouble cs_time(void)\n{\n  double now;\n#ifndef _WIN32\n  struct timeval tv;\n  if (gettimeofday(&tv, NULL /* tz */) != 0)\n    return 0;\n  now = (double)tv.tv_sec + (((double)tv.tv_usec) / 1000000.0);\n#else\n  SYSTEMTIME sysnow;\n  FILETIME ftime;\n  GetLocalTime(&sysnow);\n  SystemTimeToFileTime(&sysnow, &ftime);\n  /*\n   * 1. VC 6.0 doesn't support conversion uint64 -> double, so, using int64\n   * This should not cause a problems in this (21th) century\n   * 2. Windows FILETIME is a number of 100-nanosecond intervals since January\n   * 1, 1601 while time_t is a number of _seconds_ since January 1, 1970 UTC,\n   * thus, we need to convert to seconds and adjust amount (subtract 11644473600\n   * seconds)\n   */\n  now = (double)(((int64_t)ftime.dwLowDateTime +\n                  ((int64_t)ftime.dwHighDateTime << 32)) /\n                 10000000.0) -\n        11644473600;\n#endif /* _WIN32 */\n  return now;\n}\n#ifdef MG_MODULE_LINES\n#line 1 \"common/cs_endian.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_COMMON_CS_ENDIAN_H_\n#define CS_COMMON_CS_ENDIAN_H_\n\n/*\n * clang with std=-c99 uses __LITTLE_ENDIAN, by default\n * while for ex, RTOS gcc - LITTLE_ENDIAN, by default\n * it depends on __USE_BSD, but let's have everything\n */\n#if !defined(BYTE_ORDER) && defined(__BYTE_ORDER)\n#define BYTE_ORDER __BYTE_ORDER\n#ifndef LITTLE_ENDIAN\n#define LITTLE_ENDIAN __LITTLE_ENDIAN\n#endif /* LITTLE_ENDIAN */\n#ifndef BIG_ENDIAN\n#define BIG_ENDIAN __LITTLE_ENDIAN\n#endif /* BIG_ENDIAN */\n#endif /* BYTE_ORDER */\n\n#endif /* CS_COMMON_CS_ENDIAN_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/md5.c\"\n#endif\n/*\n * This code implements the MD5 message-digest algorithm.\n * The algorithm is due to Ron Rivest.  This code was\n * written by Colin Plumb in 1993, no copyright is claimed.\n * This code is in the public domain; do with it what you wish.\n *\n * Equivalent code is available from RSA Data Security, Inc.\n * This code has been tested against that, and is equivalent,\n * except that you don't need to include two pages of legalese\n * with every copy.\n *\n * To compute the message digest of a chunk of bytes, declare an\n * MD5Context structure, pass it to MD5Init, call MD5Update as\n * needed on buffers full of bytes, and then call MD5Final, which\n * will fill a supplied 16-byte array with the digest.\n */\n\n/* Amalgamated: #include \"common/md5.h\" */\n/* Amalgamated: #include \"common/str_util.h\" */\n\n#if !defined(EXCLUDE_COMMON)\n#if !DISABLE_MD5\n\n/* Amalgamated: #include \"common/cs_endian.h\" */\n\nstatic void byteReverse(unsigned char *buf, unsigned longs)\n{\n/* Forrest: MD5 expect LITTLE_ENDIAN, swap if BIG_ENDIAN */\n#if BYTE_ORDER == BIG_ENDIAN\n  do\n  {\n    uint32_t t = (uint32_t)((unsigned)buf[3] << 8 | buf[2]) << 16 |\n                 ((unsigned)buf[1] << 8 | buf[0]);\n    *(uint32_t *)buf = t;\n    buf += 4;\n  } while (--longs);\n#else\n  (void)buf;\n  (void)longs;\n#endif\n}\n\n#define F1(x, y, z) (z ^ (x & (y ^ z)))\n#define F2(x, y, z) F1(z, x, y)\n#define F3(x, y, z) (x ^ y ^ z)\n#define F4(x, y, z) (y ^ (x | ~z))\n\n#define MD5STEP(f, w, x, y, z, data, s) \\\n  (w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x)\n\n/*\n * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious\n * initialization constants.\n */\nvoid MD5_Init(MD5_CTX *ctx)\n{\n  ctx->buf[0] = 0x67452301;\n  ctx->buf[1] = 0xefcdab89;\n  ctx->buf[2] = 0x98badcfe;\n  ctx->buf[3] = 0x10325476;\n\n  ctx->bits[0] = 0;\n  ctx->bits[1] = 0;\n}\n\nstatic void MD5Transform(uint32_t buf[4], uint32_t const in[16])\n{\n  register uint32_t a, b, c, d;\n\n  a = buf[0];\n  b = buf[1];\n  c = buf[2];\n  d = buf[3];\n\n  MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);\n  MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);\n  MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);\n  MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);\n  MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);\n  MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);\n  MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);\n  MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);\n  MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);\n  MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);\n  MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);\n  MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);\n  MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);\n  MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);\n  MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);\n  MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);\n\n  MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);\n  MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);\n  MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);\n  MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);\n  MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);\n  MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);\n  MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);\n  MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);\n  MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);\n  MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);\n  MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);\n  MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);\n  MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);\n  MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);\n  MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);\n  MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);\n\n  MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);\n  MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);\n  MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);\n  MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);\n  MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);\n  MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);\n  MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);\n  MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);\n  MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);\n  MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);\n  MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);\n  MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);\n  MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);\n  MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);\n  MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);\n  MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);\n\n  MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);\n  MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);\n  MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);\n  MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);\n  MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);\n  MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);\n  MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);\n  MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);\n  MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);\n  MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);\n  MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);\n  MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);\n  MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);\n  MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);\n  MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);\n  MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);\n\n  buf[0] += a;\n  buf[1] += b;\n  buf[2] += c;\n  buf[3] += d;\n}\n\nvoid MD5_Update(MD5_CTX *ctx, const unsigned char *buf, size_t len)\n{\n  uint32_t t;\n\n  t = ctx->bits[0];\n  if ((ctx->bits[0] = t + ((uint32_t)len << 3)) < t)\n    ctx->bits[1]++;\n  ctx->bits[1] += (uint32_t)len >> 29;\n\n  t = (t >> 3) & 0x3f;\n\n  if (t)\n  {\n    unsigned char *p = (unsigned char *)ctx->in + t;\n\n    t = 64 - t;\n    if (len < t)\n    {\n      memcpy(p, buf, len);\n      return;\n    }\n    memcpy(p, buf, t);\n    byteReverse(ctx->in, 16);\n    MD5Transform(ctx->buf, (uint32_t *)ctx->in);\n    buf += t;\n    len -= t;\n  }\n\n  while (len >= 64)\n  {\n    memcpy(ctx->in, buf, 64);\n    byteReverse(ctx->in, 16);\n    MD5Transform(ctx->buf, (uint32_t *)ctx->in);\n    buf += 64;\n    len -= 64;\n  }\n\n  memcpy(ctx->in, buf, len);\n}\n\nvoid MD5_Final(unsigned char digest[16], MD5_CTX *ctx)\n{\n  unsigned count;\n  unsigned char *p;\n  uint32_t *a;\n\n  count = (ctx->bits[0] >> 3) & 0x3F;\n\n  p = ctx->in + count;\n  *p++ = 0x80;\n  count = 64 - 1 - count;\n  if (count < 8)\n  {\n    memset(p, 0, count);\n    byteReverse(ctx->in, 16);\n    MD5Transform(ctx->buf, (uint32_t *)ctx->in);\n    memset(ctx->in, 0, 56);\n  }\n  else\n  {\n    memset(p, 0, count - 8);\n  }\n  byteReverse(ctx->in, 14);\n\n  a = (uint32_t *)ctx->in;\n  a[14] = ctx->bits[0];\n  a[15] = ctx->bits[1];\n\n  MD5Transform(ctx->buf, (uint32_t *)ctx->in);\n  byteReverse((unsigned char *)ctx->buf, 4);\n  memcpy(digest, ctx->buf, 16);\n  memset((char *)ctx, 0, sizeof(*ctx));\n}\n#endif /* DISABLE_MD5 */\n\nchar *cs_md5(char buf[33], ...)\n{\n  unsigned char hash[16];\n  const unsigned char *p;\n  va_list ap;\n  MD5_CTX ctx;\n\n  MD5_Init(&ctx);\n\n  va_start(ap, buf);\n  while ((p = va_arg(ap, const unsigned char *)) != NULL)\n  {\n    size_t len = va_arg(ap, size_t);\n    MD5_Update(&ctx, p, len);\n  }\n  va_end(ap);\n\n  MD5_Final(hash, &ctx);\n  cs_to_hex(buf, hash, sizeof(hash));\n\n  return buf;\n}\n\n#endif /* EXCLUDE_COMMON */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/mbuf.c\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef EXCLUDE_COMMON\n\n#include <assert.h>\n#include <string.h>\n/* Amalgamated: #include \"common/mbuf.h\" */\n\n#ifndef MBUF_REALLOC\n#define MBUF_REALLOC realloc\n#endif\n\n#ifndef MBUF_FREE\n#define MBUF_FREE free\n#endif\n\nvoid mbuf_init(struct mbuf *mbuf, size_t initial_size)\n{\n  mbuf->len = mbuf->size = 0;\n  mbuf->buf = NULL;\n  mbuf_resize(mbuf, initial_size);\n}\n\nvoid mbuf_free(struct mbuf *mbuf)\n{\n  if (mbuf->buf != NULL)\n  {\n    MBUF_FREE(mbuf->buf);\n    mbuf_init(mbuf, 0);\n  }\n}\n\nvoid mbuf_resize(struct mbuf *a, size_t new_size)\n{\n  if (new_size > a->size || (new_size < a->size && new_size >= a->len))\n  {\n    char *buf = (char *)MBUF_REALLOC(a->buf, new_size);\n    /*\n     * In case realloc fails, there's not much we can do, except keep things as\n     * they are. Note that NULL is a valid return value from realloc when\n     * size == 0, but that is covered too.\n     */\n    if (buf == NULL && new_size != 0)\n      return;\n    a->buf = buf;\n    a->size = new_size;\n  }\n}\n\nvoid mbuf_trim(struct mbuf *mbuf)\n{\n  mbuf_resize(mbuf, mbuf->len);\n}\n\nsize_t mbuf_insert(struct mbuf *a, size_t off, const void *buf, size_t len)\n{\n  char *p = NULL;\n\n  assert(a != NULL);\n  assert(a->len <= a->size);\n  assert(off <= a->len);\n\n  /* check overflow */\n  if (~(size_t)0 - (size_t)a->buf < len)\n    return 0;\n\n  if (a->len + len <= a->size)\n  {\n    memmove(a->buf + off + len, a->buf + off, a->len - off);\n    if (buf != NULL)\n    {\n      memcpy(a->buf + off, buf, len);\n    }\n    a->len += len;\n  }\n  else\n  {\n    size_t new_size = (size_t)((a->len + len) * MBUF_SIZE_MULTIPLIER);\n    if ((p = (char *)MBUF_REALLOC(a->buf, new_size)) != NULL)\n    {\n      a->buf = p;\n      memmove(a->buf + off + len, a->buf + off, a->len - off);\n      if (buf != NULL)\n        memcpy(a->buf + off, buf, len);\n      a->len += len;\n      a->size = new_size;\n    }\n    else\n    {\n      len = 0;\n    }\n  }\n\n  return len;\n}\n\nsize_t mbuf_append(struct mbuf *a, const void *buf, size_t len)\n{\n  return mbuf_insert(a, a->len, buf, len);\n}\n\nvoid mbuf_remove(struct mbuf *mb, size_t n)\n{\n  if (n > 0 && n <= mb->len)\n  {\n    memmove(mb->buf, mb->buf + n, mb->len - n);\n    mb->len -= n;\n  }\n}\n\n#endif /* EXCLUDE_COMMON */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/mg_str.c\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n/* Amalgamated: #include \"common/mg_str.h\" */\n\n#include <stdlib.h>\n#include <string.h>\n\nint mg_ncasecmp(const char *s1, const char *s2, size_t len);\n\nstruct mg_str mg_mk_str(const char *s)\n{\n  struct mg_str ret = {s, 0};\n  if (s != NULL)\n    ret.len = strlen(s);\n  return ret;\n}\n\nstruct mg_str mg_mk_str_n(const char *s, size_t len)\n{\n  struct mg_str ret = {s, len};\n  return ret;\n}\n\nint mg_vcmp(const struct mg_str *str1, const char *str2)\n{\n  size_t n2 = strlen(str2), n1 = str1->len;\n  int r = memcmp(str1->p, str2, (n1 < n2) ? n1 : n2);\n  if (r == 0)\n  {\n    return n1 - n2;\n  }\n  return r;\n}\n\nint mg_vcasecmp(const struct mg_str *str1, const char *str2)\n{\n  size_t n2 = strlen(str2), n1 = str1->len;\n  int r = mg_ncasecmp(str1->p, str2, (n1 < n2) ? n1 : n2);\n  if (r == 0)\n  {\n    return n1 - n2;\n  }\n  return r;\n}\n\nstruct mg_str mg_strdup(const struct mg_str s)\n{\n  struct mg_str r = {NULL, 0};\n  if (s.len > 0 && s.p != NULL)\n  {\n    r.p = (char *)malloc(s.len);\n    if (r.p != NULL)\n    {\n      memcpy((char *)r.p, s.p, s.len);\n      r.len = s.len;\n    }\n  }\n  return r;\n}\n\nint mg_strcmp(const struct mg_str str1, const struct mg_str str2)\n{\n  size_t i = 0;\n  while (i < str1.len && i < str2.len)\n  {\n    if (str1.p[i] < str2.p[i])\n      return -1;\n    if (str1.p[i] > str2.p[i])\n      return 1;\n    i++;\n  }\n  if (i < str1.len)\n    return 1;\n  if (i < str2.len)\n    return -1;\n  return 0;\n}\n\nint mg_strncmp(const struct mg_str str1, const struct mg_str str2, size_t n)\n{\n  struct mg_str s1 = str1;\n  struct mg_str s2 = str2;\n\n  if (s1.len > n)\n  {\n    s1.len = n;\n  }\n  if (s2.len > n)\n  {\n    s2.len = n;\n  }\n  return mg_strcmp(s1, s2);\n}\n#ifdef MG_MODULE_LINES\n#line 1 \"common/sha1.c\"\n#endif\n/* Copyright(c) By Steve Reid <steve@edmweb.com> */\n/* 100% Public Domain */\n\n/* Amalgamated: #include \"common/sha1.h\" */\n\n#if !DISABLE_SHA1 && !defined(EXCLUDE_COMMON)\n\n/* Amalgamated: #include \"common/cs_endian.h\" */\n\n#define SHA1HANDSOFF\n#if defined(__sun)\n/* Amalgamated: #include \"common/solarisfixes.h\" */\n#endif\n\nunion char64long16 {\n  unsigned char c[64];\n  uint32_t l[16];\n};\n\n#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))\n\nstatic uint32_t blk0(union char64long16 *block, int i)\n{\n/* Forrest: SHA expect BIG_ENDIAN, swap if LITTLE_ENDIAN */\n#if BYTE_ORDER == LITTLE_ENDIAN\n  block->l[i] =\n      (rol(block->l[i], 24) & 0xFF00FF00) | (rol(block->l[i], 8) & 0x00FF00FF);\n#endif\n  return block->l[i];\n}\n\n/* Avoid redefine warning (ARM /usr/include/sys/ucontext.h define R0~R4) */\n#undef blk\n#undef R0\n#undef R1\n#undef R2\n#undef R3\n#undef R4\n\n#define blk(i)                                                               \\\n  (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ block->l[(i + 8) & 15] ^ \\\n                              block->l[(i + 2) & 15] ^ block->l[i & 15],     \\\n                          1))\n#define R0(v, w, x, y, z, i)                                          \\\n  z += ((w & (x ^ y)) ^ y) + blk0(block, i) + 0x5A827999 + rol(v, 5); \\\n  w = rol(w, 30);\n#define R1(v, w, x, y, z, i)                                  \\\n  z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \\\n  w = rol(w, 30);\n#define R2(v, w, x, y, z, i)                          \\\n  z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); \\\n  w = rol(w, 30);\n#define R3(v, w, x, y, z, i)                                        \\\n  z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \\\n  w = rol(w, 30);\n#define R4(v, w, x, y, z, i)                          \\\n  z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \\\n  w = rol(w, 30);\n\nvoid cs_sha1_transform(uint32_t state[5], const unsigned char buffer[64])\n{\n  uint32_t a, b, c, d, e;\n  union char64long16 block[1];\n\n  memcpy(block, buffer, 64);\n  a = state[0];\n  b = state[1];\n  c = state[2];\n  d = state[3];\n  e = state[4];\n  R0(a, b, c, d, e, 0);\n  R0(e, a, b, c, d, 1);\n  R0(d, e, a, b, c, 2);\n  R0(c, d, e, a, b, 3);\n  R0(b, c, d, e, a, 4);\n  R0(a, b, c, d, e, 5);\n  R0(e, a, b, c, d, 6);\n  R0(d, e, a, b, c, 7);\n  R0(c, d, e, a, b, 8);\n  R0(b, c, d, e, a, 9);\n  R0(a, b, c, d, e, 10);\n  R0(e, a, b, c, d, 11);\n  R0(d, e, a, b, c, 12);\n  R0(c, d, e, a, b, 13);\n  R0(b, c, d, e, a, 14);\n  R0(a, b, c, d, e, 15);\n  R1(e, a, b, c, d, 16);\n  R1(d, e, a, b, c, 17);\n  R1(c, d, e, a, b, 18);\n  R1(b, c, d, e, a, 19);\n  R2(a, b, c, d, e, 20);\n  R2(e, a, b, c, d, 21);\n  R2(d, e, a, b, c, 22);\n  R2(c, d, e, a, b, 23);\n  R2(b, c, d, e, a, 24);\n  R2(a, b, c, d, e, 25);\n  R2(e, a, b, c, d, 26);\n  R2(d, e, a, b, c, 27);\n  R2(c, d, e, a, b, 28);\n  R2(b, c, d, e, a, 29);\n  R2(a, b, c, d, e, 30);\n  R2(e, a, b, c, d, 31);\n  R2(d, e, a, b, c, 32);\n  R2(c, d, e, a, b, 33);\n  R2(b, c, d, e, a, 34);\n  R2(a, b, c, d, e, 35);\n  R2(e, a, b, c, d, 36);\n  R2(d, e, a, b, c, 37);\n  R2(c, d, e, a, b, 38);\n  R2(b, c, d, e, a, 39);\n  R3(a, b, c, d, e, 40);\n  R3(e, a, b, c, d, 41);\n  R3(d, e, a, b, c, 42);\n  R3(c, d, e, a, b, 43);\n  R3(b, c, d, e, a, 44);\n  R3(a, b, c, d, e, 45);\n  R3(e, a, b, c, d, 46);\n  R3(d, e, a, b, c, 47);\n  R3(c, d, e, a, b, 48);\n  R3(b, c, d, e, a, 49);\n  R3(a, b, c, d, e, 50);\n  R3(e, a, b, c, d, 51);\n  R3(d, e, a, b, c, 52);\n  R3(c, d, e, a, b, 53);\n  R3(b, c, d, e, a, 54);\n  R3(a, b, c, d, e, 55);\n  R3(e, a, b, c, d, 56);\n  R3(d, e, a, b, c, 57);\n  R3(c, d, e, a, b, 58);\n  R3(b, c, d, e, a, 59);\n  R4(a, b, c, d, e, 60);\n  R4(e, a, b, c, d, 61);\n  R4(d, e, a, b, c, 62);\n  R4(c, d, e, a, b, 63);\n  R4(b, c, d, e, a, 64);\n  R4(a, b, c, d, e, 65);\n  R4(e, a, b, c, d, 66);\n  R4(d, e, a, b, c, 67);\n  R4(c, d, e, a, b, 68);\n  R4(b, c, d, e, a, 69);\n  R4(a, b, c, d, e, 70);\n  R4(e, a, b, c, d, 71);\n  R4(d, e, a, b, c, 72);\n  R4(c, d, e, a, b, 73);\n  R4(b, c, d, e, a, 74);\n  R4(a, b, c, d, e, 75);\n  R4(e, a, b, c, d, 76);\n  R4(d, e, a, b, c, 77);\n  R4(c, d, e, a, b, 78);\n  R4(b, c, d, e, a, 79);\n  state[0] += a;\n  state[1] += b;\n  state[2] += c;\n  state[3] += d;\n  state[4] += e;\n  /* Erase working structures. The order of operations is important,\n   * used to ensure that compiler doesn't optimize those out. */\n  memset(block, 0, sizeof(block));\n  a = b = c = d = e = 0;\n  (void)a;\n  (void)b;\n  (void)c;\n  (void)d;\n  (void)e;\n}\n\nvoid cs_sha1_init(cs_sha1_ctx *context)\n{\n  context->state[0] = 0x67452301;\n  context->state[1] = 0xEFCDAB89;\n  context->state[2] = 0x98BADCFE;\n  context->state[3] = 0x10325476;\n  context->state[4] = 0xC3D2E1F0;\n  context->count[0] = context->count[1] = 0;\n}\n\nvoid cs_sha1_update(cs_sha1_ctx *context, const unsigned char *data,\n                    uint32_t len)\n{\n  uint32_t i, j;\n\n  j = context->count[0];\n  if ((context->count[0] += len << 3) < j)\n    context->count[1]++;\n  context->count[1] += (len >> 29);\n  j = (j >> 3) & 63;\n  if ((j + len) > 63)\n  {\n    memcpy(&context->buffer[j], data, (i = 64 - j));\n    cs_sha1_transform(context->state, context->buffer);\n    for (; i + 63 < len; i += 64)\n    {\n      cs_sha1_transform(context->state, &data[i]);\n    }\n    j = 0;\n  }\n  else\n    i = 0;\n  memcpy(&context->buffer[j], &data[i], len - i);\n}\n\nvoid cs_sha1_final(unsigned char digest[20], cs_sha1_ctx *context)\n{\n  unsigned i;\n  unsigned char finalcount[8], c;\n\n  for (i = 0; i < 8; i++)\n  {\n    finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] >>\n                                     ((3 - (i & 3)) * 8)) &\n                                    255);\n  }\n  c = 0200;\n  cs_sha1_update(context, &c, 1);\n  while ((context->count[0] & 504) != 448)\n  {\n    c = 0000;\n    cs_sha1_update(context, &c, 1);\n  }\n  cs_sha1_update(context, finalcount, 8);\n  for (i = 0; i < 20; i++)\n  {\n    digest[i] =\n        (unsigned char)((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);\n  }\n  memset(context, '\\0', sizeof(*context));\n  memset(&finalcount, '\\0', sizeof(finalcount));\n}\n\nvoid cs_hmac_sha1(const unsigned char *key, size_t keylen,\n                  const unsigned char *data, size_t datalen,\n                  unsigned char out[20])\n{\n  cs_sha1_ctx ctx;\n  unsigned char buf1[64], buf2[64], tmp_key[20], i;\n\n  if (keylen > sizeof(buf1))\n  {\n    cs_sha1_init(&ctx);\n    cs_sha1_update(&ctx, key, keylen);\n    cs_sha1_final(tmp_key, &ctx);\n    key = tmp_key;\n    keylen = sizeof(tmp_key);\n  }\n\n  memset(buf1, 0, sizeof(buf1));\n  memset(buf2, 0, sizeof(buf2));\n  memcpy(buf1, key, keylen);\n  memcpy(buf2, key, keylen);\n\n  for (i = 0; i < sizeof(buf1); i++)\n  {\n    buf1[i] ^= 0x36;\n    buf2[i] ^= 0x5c;\n  }\n\n  cs_sha1_init(&ctx);\n  cs_sha1_update(&ctx, buf1, sizeof(buf1));\n  cs_sha1_update(&ctx, data, datalen);\n  cs_sha1_final(out, &ctx);\n\n  cs_sha1_init(&ctx);\n  cs_sha1_update(&ctx, buf2, sizeof(buf2));\n  cs_sha1_update(&ctx, out, 20);\n  cs_sha1_final(out, &ctx);\n}\n\n#endif /* EXCLUDE_COMMON */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/str_util.c\"\n#endif\n/*\n * Copyright (c) 2015 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef EXCLUDE_COMMON\n\n/* Amalgamated: #include \"common/platform.h\" */\n/* Amalgamated: #include \"common/str_util.h\" */\n\n#ifndef C_DISABLE_BUILTIN_SNPRINTF\n#define C_DISABLE_BUILTIN_SNPRINTF 0\n#endif\n\n#ifndef MG_MALLOC\n#define MG_MALLOC malloc\n#endif\n\n#ifndef MG_FREE\n#define MG_FREE free\n#endif\n\nsize_t c_strnlen(const char *s, size_t maxlen)\n{\n  size_t l = 0;\n  for (; l < maxlen && s[l] != '\\0'; l++)\n  {\n  }\n  return l;\n}\n\n#define C_SNPRINTF_APPEND_CHAR(ch) \\\n  do                               \\\n  {                                \\\n    if (i < (int)buf_size)         \\\n      buf[i] = ch;                 \\\n    i++;                           \\\n  } while (0)\n\n#define C_SNPRINTF_FLAG_ZERO 1\n\n#if C_DISABLE_BUILTIN_SNPRINTF\nint c_vsnprintf(char *buf, size_t buf_size, const char *fmt, va_list ap)\n{\n  return vsnprintf(buf, buf_size, fmt, ap);\n}\n#else\nstatic int c_itoa(char *buf, size_t buf_size, int64_t num, int base, int flags,\n                  int field_width)\n{\n  char tmp[40];\n  int i = 0, k = 0, neg = 0;\n\n  if (num < 0)\n  {\n    neg++;\n    num = -num;\n  }\n\n  /* Print into temporary buffer - in reverse order */\n  do\n  {\n    int rem = num % base;\n    if (rem < 10)\n    {\n      tmp[k++] = '0' + rem;\n    }\n    else\n    {\n      tmp[k++] = 'a' + (rem - 10);\n    }\n    num /= base;\n  } while (num > 0);\n\n  /* Zero padding */\n  if (flags && C_SNPRINTF_FLAG_ZERO)\n  {\n    while (k < field_width && k < (int)sizeof(tmp) - 1)\n    {\n      tmp[k++] = '0';\n    }\n  }\n\n  /* And sign */\n  if (neg)\n  {\n    tmp[k++] = '-';\n  }\n\n  /* Now output */\n  while (--k >= 0)\n  {\n    C_SNPRINTF_APPEND_CHAR(tmp[k]);\n  }\n\n  return i;\n}\n\nint c_vsnprintf(char *buf, size_t buf_size, const char *fmt, va_list ap)\n{\n  int ch, i = 0, len_mod, flags, precision, field_width;\n\n  while ((ch = *fmt++) != '\\0')\n  {\n    if (ch != '%')\n    {\n      C_SNPRINTF_APPEND_CHAR(ch);\n    }\n    else\n    {\n      /*\n       * Conversion specification:\n       *   zero or more flags (one of: # 0 - <space> + ')\n       *   an optional minimum  field  width (digits)\n       *   an  optional precision (. followed by digits, or *)\n       *   an optional length modifier (one of: hh h l ll L q j z t)\n       *   conversion specifier (one of: d i o u x X e E f F g G a A c s p n)\n       */\n      flags = field_width = precision = len_mod = 0;\n\n      /* Flags. only zero-pad flag is supported. */\n      if (*fmt == '0')\n      {\n        flags |= C_SNPRINTF_FLAG_ZERO;\n      }\n\n      /* Field width */\n      while (*fmt >= '0' && *fmt <= '9')\n      {\n        field_width *= 10;\n        field_width += *fmt++ - '0';\n      }\n      /* Dynamic field width */\n      if (*fmt == '*')\n      {\n        field_width = va_arg(ap, int);\n        fmt++;\n      }\n\n      /* Precision */\n      if (*fmt == '.')\n      {\n        fmt++;\n        if (*fmt == '*')\n        {\n          precision = va_arg(ap, int);\n          fmt++;\n        }\n        else\n        {\n          while (*fmt >= '0' && *fmt <= '9')\n          {\n            precision *= 10;\n            precision += *fmt++ - '0';\n          }\n        }\n      }\n\n      /* Length modifier */\n      switch (*fmt)\n      {\n      case 'h':\n      case 'l':\n      case 'L':\n      case 'I':\n      case 'q':\n      case 'j':\n      case 'z':\n      case 't':\n        len_mod = *fmt++;\n        if (*fmt == 'h')\n        {\n          len_mod = 'H';\n          fmt++;\n        }\n        if (*fmt == 'l')\n        {\n          len_mod = 'q';\n          fmt++;\n        }\n        break;\n      }\n\n      ch = *fmt++;\n      if (ch == 's')\n      {\n        const char *s = va_arg(ap, const char *); /* Always fetch parameter */\n        int j;\n        int pad = field_width - (precision >= 0 ? c_strnlen(s, precision) : 0);\n        for (j = 0; j < pad; j++)\n        {\n          C_SNPRINTF_APPEND_CHAR(' ');\n        }\n\n        /* `s` may be NULL in case of %.*s */\n        if (s != NULL)\n        {\n          /* Ignore negative and 0 precisions */\n          for (j = 0; (precision <= 0 || j < precision) && s[j] != '\\0'; j++)\n          {\n            C_SNPRINTF_APPEND_CHAR(s[j]);\n          }\n        }\n      }\n      else if (ch == 'c')\n      {\n        ch = va_arg(ap, int); /* Always fetch parameter */\n        C_SNPRINTF_APPEND_CHAR(ch);\n      }\n      else if (ch == 'd' && len_mod == 0)\n      {\n        i += c_itoa(buf + i, buf_size - i, va_arg(ap, int), 10, flags,\n                    field_width);\n      }\n      else if (ch == 'd' && len_mod == 'l')\n      {\n        i += c_itoa(buf + i, buf_size - i, va_arg(ap, long), 10, flags,\n                    field_width);\n#ifdef SSIZE_MAX\n      }\n      else if (ch == 'd' && len_mod == 'z')\n      {\n        i += c_itoa(buf + i, buf_size - i, va_arg(ap, ssize_t), 10, flags,\n                    field_width);\n#endif\n      }\n      else if (ch == 'd' && len_mod == 'q')\n      {\n        i += c_itoa(buf + i, buf_size - i, va_arg(ap, int64_t), 10, flags,\n                    field_width);\n      }\n      else if ((ch == 'x' || ch == 'u') && len_mod == 0)\n      {\n        i += c_itoa(buf + i, buf_size - i, va_arg(ap, unsigned),\n                    ch == 'x' ? 16 : 10, flags, field_width);\n      }\n      else if ((ch == 'x' || ch == 'u') && len_mod == 'l')\n      {\n        i += c_itoa(buf + i, buf_size - i, va_arg(ap, unsigned long),\n                    ch == 'x' ? 16 : 10, flags, field_width);\n      }\n      else if ((ch == 'x' || ch == 'u') && len_mod == 'z')\n      {\n        i += c_itoa(buf + i, buf_size - i, va_arg(ap, size_t),\n                    ch == 'x' ? 16 : 10, flags, field_width);\n      }\n      else if (ch == 'p')\n      {\n        unsigned long num = (unsigned long)(uintptr_t)va_arg(ap, void *);\n        C_SNPRINTF_APPEND_CHAR('0');\n        C_SNPRINTF_APPEND_CHAR('x');\n        i += c_itoa(buf + i, buf_size - i, num, 16, flags, 0);\n      }\n      else\n      {\n#ifndef NO_LIBC\n        /*\n         * TODO(lsm): abort is not nice in a library, remove it\n         * Also, ESP8266 SDK doesn't have it\n         */\n        abort();\n#endif\n      }\n    }\n  }\n\n  /* Zero-terminate the result */\n  if (buf_size > 0)\n  {\n    buf[i < (int)buf_size ? i : (int)buf_size - 1] = '\\0';\n  }\n\n  return i;\n}\n#endif\n\nint c_snprintf(char *buf, size_t buf_size, const char *fmt, ...)\n{\n  int result;\n  va_list ap;\n  va_start(ap, fmt);\n  result = c_vsnprintf(buf, buf_size, fmt, ap);\n  va_end(ap);\n  return result;\n}\n\n#ifdef _WIN32\nint to_wchar(const char *path, wchar_t *wbuf, size_t wbuf_len)\n{\n  int ret;\n  char buf[MAX_PATH * 2], buf2[MAX_PATH * 2], *p;\n\n  strncpy(buf, path, sizeof(buf));\n  buf[sizeof(buf) - 1] = '\\0';\n\n  /* Trim trailing slashes. Leave backslash for paths like \"X:\\\" */\n  p = buf + strlen(buf) - 1;\n  while (p > buf && p[-1] != ':' && (p[0] == '\\\\' || p[0] == '/'))\n    *p-- = '\\0';\n\n  memset(wbuf, 0, wbuf_len * sizeof(wchar_t));\n  ret = MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (int)wbuf_len);\n\n  /*\n   * Convert back to Unicode. If doubly-converted string does not match the\n   * original, something is fishy, reject.\n   */\n  WideCharToMultiByte(CP_UTF8, 0, wbuf, (int)wbuf_len, buf2, sizeof(buf2),\n                      NULL, NULL);\n  if (strcmp(buf, buf2) != 0)\n  {\n    wbuf[0] = L'\\0';\n    ret = 0;\n  }\n\n  return ret;\n}\n#endif /* _WIN32 */\n\n/* The simplest O(mn) algorithm. Better implementation are GPLed */\nconst char *c_strnstr(const char *s, const char *find, size_t slen)\n{\n  size_t find_length = strlen(find);\n  size_t i;\n\n  for (i = 0; i < slen; i++)\n  {\n    if (i + find_length > slen)\n    {\n      return NULL;\n    }\n\n    if (strncmp(&s[i], find, find_length) == 0)\n    {\n      return &s[i];\n    }\n  }\n\n  return NULL;\n}\n\n#if CS_ENABLE_STRDUP\nchar *strdup(const char *src)\n{\n  size_t len = strlen(src) + 1;\n  char *ret = malloc(len);\n  if (ret != NULL)\n  {\n    strcpy(ret, src);\n  }\n  return ret;\n}\n#endif\n\nvoid cs_to_hex(char *to, const unsigned char *p, size_t len)\n{\n  static const char *hex = \"0123456789abcdef\";\n\n  for (; len--; p++)\n  {\n    *to++ = hex[p[0] >> 4];\n    *to++ = hex[p[0] & 0x0f];\n  }\n  *to = '\\0';\n}\n\nstatic int fourbit(int ch)\n{\n  if (ch >= '0' && ch <= '9')\n  {\n    return ch - '0';\n  }\n  else if (ch >= 'a' && ch <= 'f')\n  {\n    return ch - 'a' + 10;\n  }\n  else if (ch >= 'A' && ch <= 'F')\n  {\n    return ch - 'A' + 10;\n  }\n  return 0;\n}\n\nvoid cs_from_hex(char *to, const char *p, size_t len)\n{\n  size_t i;\n\n  for (i = 0; i < len; i += 2)\n  {\n    *to++ = (fourbit(p[i]) << 4) + fourbit(p[i + 1]);\n  }\n  *to = '\\0';\n}\n\n#if CS_ENABLE_TO64\nint64_t cs_to64(const char *s)\n{\n  int64_t result = 0;\n  int64_t neg = 1;\n  while (*s && isspace((unsigned char)*s))\n    s++;\n  if (*s == '-')\n  {\n    neg = -1;\n    s++;\n  }\n  while (isdigit((unsigned char)*s))\n  {\n    result *= 10;\n    result += (*s - '0');\n    s++;\n  }\n  return result * neg;\n}\n#endif\n\nstatic int str_util_lowercase(const char *s)\n{\n  return tolower(*(const unsigned char *)s);\n}\n\nint mg_ncasecmp(const char *s1, const char *s2, size_t len)\n{\n  int diff = 0;\n\n  if (len > 0)\n    do\n    {\n      diff = str_util_lowercase(s1++) - str_util_lowercase(s2++);\n    } while (diff == 0 && s1[-1] != '\\0' && --len > 0);\n\n  return diff;\n}\n\nint mg_casecmp(const char *s1, const char *s2)\n{\n  return mg_ncasecmp(s1, s2, (size_t)~0);\n}\n\nint mg_asprintf(char **buf, size_t size, const char *fmt, ...)\n{\n  int ret;\n  va_list ap;\n  va_start(ap, fmt);\n  ret = mg_avprintf(buf, size, fmt, ap);\n  va_end(ap);\n  return ret;\n}\n\nint mg_avprintf(char **buf, size_t size, const char *fmt, va_list ap)\n{\n  va_list ap_copy;\n  int len;\n\n  va_copy(ap_copy, ap);\n  len = vsnprintf(*buf, size, fmt, ap_copy);\n  va_end(ap_copy);\n\n  if (len < 0)\n  {\n    /* eCos and Windows are not standard-compliant and return -1 when\n     * the buffer is too small. Keep allocating larger buffers until we\n     * succeed or out of memory. */\n    *buf = NULL; /* LCOV_EXCL_START */\n    while (len < 0)\n    {\n      MG_FREE(*buf);\n      size *= 2;\n      if ((*buf = (char *)MG_MALLOC(size)) == NULL)\n        break;\n      va_copy(ap_copy, ap);\n      len = vsnprintf(*buf, size, fmt, ap_copy);\n      va_end(ap_copy);\n    }\n    /* LCOV_EXCL_STOP */\n  }\n  else if (len >= (int)size)\n  {\n    /* Standard-compliant code path. Allocate a buffer that is large enough. */\n    if ((*buf = (char *)MG_MALLOC(len + 1)) == NULL)\n    {\n      len = -1; /* LCOV_EXCL_LINE */\n    }\n    else\n    { /* LCOV_EXCL_LINE */\n      va_copy(ap_copy, ap);\n      len = vsnprintf(*buf, len + 1, fmt, ap_copy);\n      va_end(ap_copy);\n    }\n  }\n\n  return len;\n}\n\n#endif /* EXCLUDE_COMMON */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/tun.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_MONGOOSE_SRC_TUN_H_\n#define CS_MONGOOSE_SRC_TUN_H_\n\n#if MG_ENABLE_TUN\n\n/* Amalgamated: #include \"mongoose/src/net.h\" */\n/* Amalgamated: #include \"common/mg_str.h\" */\n\n#ifndef MG_TUN_RECONNECT_INTERVAL\n#define MG_TUN_RECONNECT_INTERVAL 1\n#endif\n\n#define MG_TUN_PROTO_NAME \"mg_tun\"\n\n#define MG_TUN_DATA_FRAME 0x0\n#define MG_TUN_F_END_STREAM 0x1\n\n/*\n * MG TUN frame format is loosely based on HTTP/2.\n * However since the communication happens via WebSocket\n * there is no need to encode the frame length, since that's\n * solved by WebSocket framing.\n *\n * TODO(mkm): Detailed description of the protocol.\n */\nstruct mg_tun_frame\n{\n  uint8_t type;\n  uint8_t flags;\n  uint32_t stream_id; /* opaque stream identifier */\n  struct mg_str body;\n};\n\nstruct mg_tun_ssl_opts\n{\n#if MG_ENABLE_SSL\n  const char *ssl_cert;\n  const char *ssl_key;\n  const char *ssl_ca_cert;\n#else\n  int dummy; /* some compilers don't like empty structs */\n#endif\n};\n\nstruct mg_tun_client\n{\n  struct mg_mgr *mgr;\n  struct mg_iface *iface;\n  const char *disp_url;\n  struct mg_tun_ssl_opts ssl;\n\n  uint32_t last_stream_id; /* stream id of most recently accepted connection */\n\n  struct mg_connection *disp;\n  struct mg_connection *listener;\n};\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif /* __cplusplus */\n\n  struct mg_connection *mg_tun_bind_opt(struct mg_mgr *mgr,\n                                        const char *dispatcher,\n                                        mg_event_handler_t handler,\n                                        struct mg_bind_opts opts);\n\n  int mg_tun_parse_frame(void *data, size_t len, struct mg_tun_frame *frame);\n\n  void mg_tun_send_frame(struct mg_connection *ws, uint32_t stream_id,\n                         uint8_t type, uint8_t flags, struct mg_str msg);\n\n  void mg_tun_destroy_client(struct mg_tun_client *client);\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif /* MG_ENABLE_TUN */\n\n#endif /* CS_MONGOOSE_SRC_TUN_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/net.c\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n *\n * This software is dual-licensed: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation. For the terms of this\n * license, see <http://www.gnu.org/licenses/>.\n *\n * You are free to use this software under the terms of the GNU General\n * Public License, but WITHOUT ANY WARRANTY; without even the implied\n * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n * See the GNU General Public License for more details.\n *\n * Alternatively, you can license this software under a commercial\n * license, as set out in <https://www.cesanta.com/license>.\n */\n\n/* Amalgamated: #include \"common/cs_time.h\" */\n/* Amalgamated: #include \"mongoose/src/dns.h\" */\n/* Amalgamated: #include \"mongoose/src/internal.h\" */\n/* Amalgamated: #include \"mongoose/src/resolv.h\" */\n/* Amalgamated: #include \"mongoose/src/util.h\" */\n/* Amalgamated: #include \"mongoose/src/tun.h\" */\n\n#define MG_MAX_HOST_LEN 200\n\n#define MG_COPY_COMMON_CONNECTION_OPTIONS(dst, src) \\\n  memcpy(dst, src, sizeof(*dst));\n\n/* Which flags can be pre-set by the user at connection creation time. */\n#define _MG_ALLOWED_CONNECT_FLAGS_MASK                                   \\\n  (MG_F_USER_1 | MG_F_USER_2 | MG_F_USER_3 | MG_F_USER_4 | MG_F_USER_5 | \\\n   MG_F_USER_6 | MG_F_WEBSOCKET_NO_DEFRAG | MG_F_ENABLE_BROADCAST)\n/* Which flags should be modifiable by user's callbacks. */\n#define _MG_CALLBACK_MODIFIABLE_FLAGS_MASK                               \\\n  (MG_F_USER_1 | MG_F_USER_2 | MG_F_USER_3 | MG_F_USER_4 | MG_F_USER_5 | \\\n   MG_F_USER_6 | MG_F_WEBSOCKET_NO_DEFRAG | MG_F_SEND_AND_CLOSE |        \\\n   MG_F_CLOSE_IMMEDIATELY | MG_F_IS_WEBSOCKET | MG_F_DELETE_CHUNK)\n\n#ifndef intptr_t\n#define intptr_t long\n#endif\n\nvoid mg_add_conn(struct mg_mgr *mgr, struct mg_connection *c)\n{\n  DBG((\"%p %p\", mgr, c));\n  c->mgr = mgr;\n  c->next = mgr->active_connections;\n  mgr->active_connections = c;\n  c->prev = NULL;\n  if (c->next != NULL)\n    c->next->prev = c;\n  c->iface->vtable->add_conn(c);\n}\n\nvoid mg_remove_conn(struct mg_connection *conn)\n{\n  if (conn->prev == NULL)\n    conn->mgr->active_connections = conn->next;\n  if (conn->prev)\n    conn->prev->next = conn->next;\n  if (conn->next)\n    conn->next->prev = conn->prev;\n  conn->iface->vtable->remove_conn(conn);\n}\n\nMG_INTERNAL void mg_call(struct mg_connection *nc,\n                         mg_event_handler_t ev_handler, int ev, void *ev_data)\n{\n  if (ev_handler == NULL)\n  {\n    /*\n     * If protocol handler is specified, call it. Otherwise, call user-specified\n     * event handler.\n     */\n    ev_handler = nc->proto_handler ? nc->proto_handler : nc->handler;\n  }\n  if (ev != MG_EV_POLL)\n  {\n    DBG((\"%p %s ev=%d ev_data=%p flags=%lu rmbl=%d smbl=%d\", nc,\n         ev_handler == nc->handler ? \"user\" : \"proto\", ev, ev_data, nc->flags,\n         (int)nc->recv_mbuf.len, (int)nc->send_mbuf.len));\n  }\n\n#if !defined(NO_LIBC) && MG_ENABLE_HEXDUMP\n  /* LCOV_EXCL_START */\n  if (nc->mgr->hexdump_file != NULL && ev != MG_EV_POLL &&\n      ev != MG_EV_SEND /* handled separately */)\n  {\n    if (ev == MG_EV_RECV)\n    {\n      mg_hexdump_connection(nc, nc->mgr->hexdump_file, nc->recv_mbuf.buf,\n                            *(int *)ev_data, ev);\n    }\n    else\n    {\n      mg_hexdump_connection(nc, nc->mgr->hexdump_file, NULL, 0, ev);\n    }\n  }\n/* LCOV_EXCL_STOP */\n#endif\n  if (ev_handler != NULL)\n  {\n    unsigned long flags_before = nc->flags;\n    size_t recv_mbuf_before = nc->recv_mbuf.len, recved;\n    ev_handler(nc, ev, ev_data);\n    recved = (recv_mbuf_before - nc->recv_mbuf.len);\n    /* Prevent user handler from fiddling with system flags. */\n    if (ev_handler == nc->handler && nc->flags != flags_before)\n    {\n      nc->flags = (flags_before & ~_MG_CALLBACK_MODIFIABLE_FLAGS_MASK) |\n                  (nc->flags & _MG_CALLBACK_MODIFIABLE_FLAGS_MASK);\n    }\n    if (recved > 0 && !(nc->flags & MG_F_UDP))\n    {\n      nc->iface->vtable->recved(nc, recved);\n    }\n  }\n  if (ev != MG_EV_POLL)\n  {\n    DBG((\"%p after %s flags=%lu rmbl=%d smbl=%d\", nc,\n         ev_handler == nc->handler ? \"user\" : \"proto\", nc->flags,\n         (int)nc->recv_mbuf.len, (int)nc->send_mbuf.len));\n  }\n}\n\nvoid mg_if_timer(struct mg_connection *c, double now)\n{\n  if (c->ev_timer_time > 0 && now >= c->ev_timer_time)\n  {\n    double old_value = c->ev_timer_time;\n    mg_call(c, NULL, MG_EV_TIMER, &now);\n    /*\n     * To prevent timer firing all the time, reset the timer after delivery.\n     * However, in case user sets it to new value, do not reset.\n     */\n    if (c->ev_timer_time == old_value)\n    {\n      c->ev_timer_time = 0;\n    }\n  }\n}\n\nvoid mg_if_poll(struct mg_connection *nc, time_t now)\n{\n  if (!(nc->flags & MG_F_SSL) || (nc->flags & MG_F_SSL_HANDSHAKE_DONE))\n  {\n    mg_call(nc, NULL, MG_EV_POLL, &now);\n  }\n}\n\nstatic void mg_destroy_conn(struct mg_connection *conn, int destroy_if)\n{\n  if (destroy_if)\n    conn->iface->vtable->destroy_conn(conn);\n  if (conn->proto_data != NULL && conn->proto_data_destructor != NULL)\n  {\n    conn->proto_data_destructor(conn->proto_data);\n  }\n#if MG_ENABLE_SSL\n  mg_ssl_if_conn_free(conn);\n#endif\n  mbuf_free(&conn->recv_mbuf);\n  mbuf_free(&conn->send_mbuf);\n\n  memset(conn, 0, sizeof(*conn));\n  MG_FREE(conn);\n}\n\nvoid mg_close_conn(struct mg_connection *conn)\n{\n  DBG((\"%p %lu %d\", conn, conn->flags, conn->sock));\n  mg_remove_conn(conn);\n  conn->iface->vtable->destroy_conn(conn);\n  mg_call(conn, NULL, MG_EV_CLOSE, NULL);\n  mg_destroy_conn(conn, 0 /* destroy_if */);\n}\n\nvoid mg_mgr_init(struct mg_mgr *m, void *user_data)\n{\n  struct mg_mgr_init_opts opts;\n  memset(&opts, 0, sizeof(opts));\n  mg_mgr_init_opt(m, user_data, opts);\n}\n\nvoid mg_mgr_init_opt(struct mg_mgr *m, void *user_data,\n                     struct mg_mgr_init_opts opts)\n{\n  memset(m, 0, sizeof(*m));\n#if MG_ENABLE_BROADCAST\n  m->ctl[0] = m->ctl[1] = INVALID_SOCKET;\n#endif\n\n#if MG_ENABLE_MUTITHREADS\n  m->mthread_ctl[0] = INVALID_SOCKET;\n  m->mthread_ctl[1] = INVALID_SOCKET;\n#endif\n\n  m->user_data = user_data;\n\n#ifdef _WIN32\n  {\n    WSADATA data;\n    WSAStartup(MAKEWORD(2, 2), &data);\n  }\n#elif defined(__unix__)\n  /* Ignore SIGPIPE signal, so if client cancels the request, it\n   * won't kill the whole process. */\n  signal(SIGPIPE, SIG_IGN);\n#endif\n\n#if MG_ENABLE_SSL\n  {\n    static int init_done;\n    if (!init_done)\n    {\n      mg_ssl_if_init();\n      init_done++;\n    }\n  }\n#endif\n  {\n    int i;\n    if (opts.num_ifaces == 0)\n    {\n      opts.num_ifaces = mg_num_ifaces;\n      opts.ifaces = mg_ifaces;\n    }\n    if (opts.main_iface != NULL)\n    {\n      opts.ifaces[MG_MAIN_IFACE] = opts.main_iface;\n    }\n    m->num_ifaces = opts.num_ifaces;\n    m->ifaces =\n        (struct mg_iface **)MG_MALLOC(sizeof(*m->ifaces) * opts.num_ifaces);\n    for (i = 0; i < mg_num_ifaces; i++)\n    {\n      m->ifaces[i] = mg_if_create_iface(opts.ifaces[i], m);\n      m->ifaces[i]->vtable->init(m->ifaces[i]);\n    }\n  }\n  DBG((\"==================================\"));\n  DBG((\"init mgr=%p\", m));\n}\n\n#if MG_ENABLE_JAVASCRIPT\nstatic enum v7_err mg_send_js(struct v7 *v7, v7_val_t *res)\n{\n  v7_val_t arg0 = v7_arg(v7, 0);\n  v7_val_t arg1 = v7_arg(v7, 1);\n  struct mg_connection *c = (struct mg_connection *)v7_get_ptr(v7, arg0);\n  size_t len = 0;\n\n  if (v7_is_string(arg1))\n  {\n    const char *data = v7_get_string(v7, &arg1, &len);\n    mg_send(c, data, len);\n  }\n\n  *res = v7_mk_number(v7, len);\n\n  return V7_OK;\n}\n\nenum v7_err mg_enable_javascript(struct mg_mgr *m, struct v7 *v7,\n                                 const char *init_file_name)\n{\n  v7_val_t v;\n  m->v7 = v7;\n  v7_set_method(v7, v7_get_global(v7), \"mg_send\", mg_send_js);\n  return v7_exec_file(v7, init_file_name, &v);\n}\n#endif\n\nvoid mg_mgr_free(struct mg_mgr *m)\n{\n  struct mg_connection *conn, *tmp_conn;\n\n  DBG((\"%p\", m));\n  if (m == NULL)\n    return;\n  /* Do one last poll, see https://github.com/cesanta/mongoose/issues/286 */\n  mg_mgr_poll(m, 0);\n\n#if MG_ENABLE_BROADCAST\n  if (m->ctl[0] != INVALID_SOCKET)\n    closesocket(m->ctl[0]);\n  if (m->ctl[1] != INVALID_SOCKET)\n    closesocket(m->ctl[1]);\n  m->ctl[0] = m->ctl[1] = INVALID_SOCKET;\n#endif\n\n  for (conn = m->active_connections; conn != NULL; conn = tmp_conn)\n  {\n    tmp_conn = conn->next;\n    mg_close_conn(conn);\n  }\n\n  {\n    int i;\n    for (i = 0; i < m->num_ifaces; i++)\n    {\n      m->ifaces[i]->vtable->free(m->ifaces[i]);\n      MG_FREE(m->ifaces[i]);\n    }\n    MG_FREE(m->ifaces);\n  }\n}\n\ntime_t mg_mgr_poll(struct mg_mgr *m, int timeout_ms)\n{\n  int i;\n  time_t now = 0; /* oh GCC, seriously ? */\n\n  if (m->num_ifaces == 0)\n  {\n    LOG(LL_ERROR, (\"cannot poll: no interfaces\"));\n    return 0;\n  }\n\n  for (i = 0; i < m->num_ifaces; i++)\n  {\n    now = m->ifaces[i]->vtable->poll(m->ifaces[i], timeout_ms);\n  }\n  return now;\n}\n\nint mg_vprintf(struct mg_connection *nc, const char *fmt, va_list ap)\n{\n  char mem[MG_VPRINTF_BUFFER_SIZE], *buf = mem;\n  int len;\n\n  if ((len = mg_avprintf(&buf, sizeof(mem), fmt, ap)) > 0)\n  {\n    mg_send(nc, buf, len);\n  }\n  if (buf != mem && buf != NULL)\n  {\n    MG_FREE(buf); /* LCOV_EXCL_LINE */\n  }               /* LCOV_EXCL_LINE */\n\n  return len;\n}\n\nint mg_printf(struct mg_connection *conn, const char *fmt, ...)\n{\n  int len;\n  va_list ap;\n  va_start(ap, fmt);\n  len = mg_vprintf(conn, fmt, ap);\n  va_end(ap);\n  return len;\n}\n\n#if MG_ENABLE_SYNC_RESOLVER\n/* TODO(lsm): use non-blocking resolver */\nstatic int mg_resolve2(const char *host, struct in_addr *ina)\n{\n#if MG_ENABLE_GETADDRINFO\n  int rv = 0;\n  struct addrinfo hints, *servinfo, *p;\n  struct sockaddr_in *h = NULL;\n  memset(&hints, 0, sizeof hints);\n  hints.ai_family = AF_INET;\n  hints.ai_socktype = SOCK_STREAM;\n  if ((rv = getaddrinfo(host, NULL, NULL, &servinfo)) != 0)\n  {\n    DBG((\"getaddrinfo(%s) failed: %s\", host, strerror(mg_get_errno())));\n    return 0;\n  }\n  for (p = servinfo; p != NULL; p = p->ai_next)\n  {\n    memcpy(&h, &p->ai_addr, sizeof(struct sockaddr_in *));\n    memcpy(ina, &h->sin_addr, sizeof(ina));\n  }\n  freeaddrinfo(servinfo);\n  return 1;\n#else\n  struct hostent *he;\n  if ((he = gethostbyname(host)) == NULL)\n  {\n    DBG((\"gethostbyname(%s) failed: %s\", host, strerror(mg_get_errno())));\n  }\n  else\n  {\n    memcpy(ina, he->h_addr_list[0], sizeof(*ina));\n    return 1;\n  }\n  return 0;\n#endif /* MG_ENABLE_GETADDRINFO */\n}\n\nint mg_resolve(const char *host, char *buf, size_t n)\n{\n  struct in_addr ad;\n  return mg_resolve2(host, &ad) ? snprintf(buf, n, \"%s\", inet_ntoa(ad)) : 0;\n}\n#endif /* MG_ENABLE_SYNC_RESOLVER */\n\nMG_INTERNAL struct mg_connection *mg_create_connection_base(\n    struct mg_mgr *mgr, mg_event_handler_t callback,\n    struct mg_add_sock_opts opts)\n{\n  struct mg_connection *conn;\n\n  if ((conn = (struct mg_connection *)MG_CALLOC(1, sizeof(*conn))) != NULL)\n  {\n    conn->sock = INVALID_SOCKET;\n    conn->handler = callback;\n    conn->mgr = mgr;\n    conn->last_io_time = (time_t)mg_time();\n    conn->iface =\n        (opts.iface != NULL ? opts.iface : mgr->ifaces[MG_MAIN_IFACE]);\n    conn->flags = opts.flags & _MG_ALLOWED_CONNECT_FLAGS_MASK;\n    conn->user_data = opts.user_data;\n    /*\n     * SIZE_MAX is defined as a long long constant in\n     * system headers on some platforms and so it\n     * doesn't compile with pedantic ansi flags.\n     */\n    conn->recv_mbuf_limit = ~0;\n  }\n  else\n  {\n    MG_SET_PTRPTR(opts.error_string, \"failed to create connection\");\n  }\n\n  return conn;\n}\n\nMG_INTERNAL struct mg_connection *mg_create_connection(\n    struct mg_mgr *mgr, mg_event_handler_t callback,\n    struct mg_add_sock_opts opts)\n{\n  struct mg_connection *conn = mg_create_connection_base(mgr, callback, opts);\n\n  if (conn != NULL && !conn->iface->vtable->create_conn(conn))\n  {\n    MG_FREE(conn);\n    conn = NULL;\n  }\n  if (conn == NULL)\n  {\n    MG_SET_PTRPTR(opts.error_string, \"failed to init connection\");\n  }\n\n  return conn;\n}\n\n/*\n * Address format: [PROTO://][HOST]:PORT\n *\n * HOST could be IPv4/IPv6 address or a host name.\n * `host` is a destination buffer to hold parsed HOST part. Shoud be at least\n * MG_MAX_HOST_LEN bytes long.\n * `proto` is a returned socket type, either SOCK_STREAM or SOCK_DGRAM\n *\n * Return:\n *   -1   on parse error\n *    0   if HOST needs DNS lookup\n *   >0   length of the address string\n */\nMG_INTERNAL int mg_parse_address(const char *str, union socket_address *sa,\n                                 int *proto, char *host, size_t host_len)\n{\n  unsigned int a, b, c, d, port = 0;\n  int ch, len = 0;\n#if MG_ENABLE_IPV6\n  char buf[100];\n#endif\n\n  /*\n   * MacOS needs that. If we do not zero it, subsequent bind() will fail.\n   * Also, all-zeroes in the socket address means binding to all addresses\n   * for both IPv4 and IPv6 (INADDR_ANY and IN6ADDR_ANY_INIT).\n   */\n  memset(sa, 0, sizeof(*sa));\n  sa->sin.sin_family = AF_INET;\n\n  *proto = SOCK_STREAM;\n\n  if (strncmp(str, \"udp://\", 6) == 0)\n  {\n    str += 6;\n    *proto = SOCK_DGRAM;\n  }\n  else if (strncmp(str, \"tcp://\", 6) == 0)\n  {\n    str += 6;\n  }\n\n  if (sscanf(str, \"%u.%u.%u.%u:%u%n\", &a, &b, &c, &d, &port, &len) == 5)\n  {\n    /* Bind to a specific IPv4 address, e.g. 192.168.1.5:8080 */\n    sa->sin.sin_addr.s_addr =\n        htonl(((uint32_t)a << 24) | ((uint32_t)b << 16) | c << 8 | d);\n    sa->sin.sin_port = htons((uint16_t)port);\n#if MG_ENABLE_IPV6\n  }\n  else if (sscanf(str, \"[%99[^]]]:%u%n\", buf, &port, &len) == 2 &&\n           inet_pton(AF_INET6, buf, &sa->sin6.sin6_addr))\n  {\n    /* IPv6 address, e.g. [3ffe:2a00:100:7031::1]:8080 */\n    sa->sin6.sin6_family = AF_INET6;\n    sa->sin.sin_port = htons((uint16_t)port);\n#endif\n#if MG_ENABLE_ASYNC_RESOLVER\n  }\n  else if (strlen(str) < host_len &&\n           sscanf(str, \"%[^ :]:%u%n\", host, &port, &len) == 2)\n  {\n    sa->sin.sin_port = htons((uint16_t)port);\n    if (mg_resolve_from_hosts_file(host, sa) != 0)\n    {\n      /*\n       * if resolving from hosts file failed and the host\n       * we are trying to resolve is `localhost` - we should\n       * try to resolve it using `gethostbyname` and do not try\n       * to resolve it via DNS server if gethostbyname has failed too\n       */\n      if (mg_ncasecmp(host, \"localhost\", 9) != 0)\n      {\n        return 0;\n      }\n\n#if MG_ENABLE_SYNC_RESOLVER\n      if (!mg_resolve2(host, &sa->sin.sin_addr))\n      {\n        return -1;\n      }\n#else\n      return -1;\n#endif\n    }\n#endif\n  }\n  else if (sscanf(str, \":%u%n\", &port, &len) == 1 ||\n           sscanf(str, \"%u%n\", &port, &len) == 1)\n  {\n    /* If only port is specified, bind to IPv4, INADDR_ANY */\n    sa->sin.sin_port = htons((uint16_t)port);\n  }\n  else\n  {\n    return -1;\n  }\n\n  /* Required for MG_ENABLE_ASYNC_RESOLVER=0 */\n  (void)host;\n  (void)host_len;\n\n  ch = str[len]; /* Character that follows the address */\n  return port < 0xffffUL && (ch == '\\0' || ch == ',' || isspace(ch)) ? len : -1;\n}\n\nstruct mg_connection *mg_if_accept_new_conn(struct mg_connection *lc)\n{\n  struct mg_add_sock_opts opts;\n  struct mg_connection *nc;\n  memset(&opts, 0, sizeof(opts));\n  nc = mg_create_connection(lc->mgr, lc->handler, opts);\n  if (nc == NULL)\n    return NULL;\n  nc->listener = lc;\n  nc->proto_handler = lc->proto_handler;\n  nc->user_data = lc->user_data;\n  nc->recv_mbuf_limit = lc->recv_mbuf_limit;\n  nc->iface = lc->iface;\n  if (lc->flags & MG_F_SSL)\n    nc->flags |= MG_F_SSL;\n  mg_add_conn(nc->mgr, nc);\n  DBG((\"%p %p %d %d\", lc, nc, nc->sock, (int)nc->flags));\n  return nc;\n}\n\nvoid mg_if_accept_tcp_cb(struct mg_connection *nc, union socket_address *sa,\n                         size_t sa_len)\n{\n  (void)sa_len;\n  nc->sa = *sa;\n  mg_call(nc, NULL, MG_EV_ACCEPT, &nc->sa);\n}\n\nvoid mg_send(struct mg_connection *nc, const void *buf, int len)\n{\n  nc->last_io_time = (time_t)mg_time();\n  if (nc->flags & MG_F_UDP)\n  {\n    nc->iface->vtable->udp_send(nc, buf, len);\n  }\n  else\n  {\n    nc->iface->vtable->tcp_send(nc, buf, len);\n  }\n#if !defined(NO_LIBC) && MG_ENABLE_HEXDUMP\n  if (nc->mgr && nc->mgr->hexdump_file != NULL)\n  {\n    mg_hexdump_connection(nc, nc->mgr->hexdump_file, buf, len, MG_EV_SEND);\n  }\n#endif\n}\n\nvoid mg_if_sent_cb(struct mg_connection *nc, int num_sent)\n{\n  if (num_sent < 0)\n  {\n    nc->flags |= MG_F_CLOSE_IMMEDIATELY;\n  }\n  mg_call(nc, NULL, MG_EV_SEND, &num_sent);\n}\n\nMG_INTERNAL void mg_recv_common(struct mg_connection *nc, void *buf, int len,\n                                int own)\n{\n  DBG((\"%p %d %u\", nc, len, (unsigned int)nc->recv_mbuf.len));\n  if (nc->flags & MG_F_CLOSE_IMMEDIATELY)\n  {\n    DBG((\"%p discarded %d bytes\", nc, len));\n    /*\n     * This connection will not survive next poll. Do not deliver events,\n     * send data to /dev/null without acking.\n     */\n    if (own)\n    {\n      MG_FREE(buf);\n    }\n    return;\n  }\n  nc->last_io_time = (time_t)mg_time();\n  if (!own)\n  {\n    mbuf_append(&nc->recv_mbuf, buf, len);\n  }\n  else if (nc->recv_mbuf.len == 0)\n  {\n    /* Adopt buf as recv_mbuf's backing store. */\n    mbuf_free(&nc->recv_mbuf);\n    nc->recv_mbuf.buf = (char *)buf;\n    nc->recv_mbuf.size = nc->recv_mbuf.len = len;\n  }\n  else\n  {\n    mbuf_append(&nc->recv_mbuf, buf, len);\n    MG_FREE(buf);\n  }\n  mg_call(nc, NULL, MG_EV_RECV, &len);\n}\n\nvoid mg_if_recv_tcp_cb(struct mg_connection *nc, void *buf, int len, int own)\n{\n  mg_recv_common(nc, buf, len, own);\n}\n\nvoid mg_if_recv_udp_cb(struct mg_connection *nc, void *buf, int len,\n                       union socket_address *sa, size_t sa_len)\n{\n  assert(nc->flags & MG_F_UDP);\n  DBG((\"%p %u\", nc, (unsigned int)len));\n  if (nc->flags & MG_F_LISTENING)\n  {\n    struct mg_connection *lc = nc;\n    /*\n     * Do we have an existing connection for this source?\n     * This is very inefficient for long connection lists.\n     */\n    for (nc = mg_next(lc->mgr, NULL); nc != NULL; nc = mg_next(lc->mgr, nc))\n    {\n      if (memcmp(&nc->sa.sa, &sa->sa, sa_len) == 0 && nc->listener == lc)\n      {\n        break;\n      }\n    }\n    if (nc == NULL)\n    {\n      struct mg_add_sock_opts opts;\n      memset(&opts, 0, sizeof(opts));\n      /* Create fake connection w/out sock initialization */\n      nc = mg_create_connection_base(lc->mgr, lc->handler, opts);\n      if (nc != NULL)\n      {\n        nc->sock = lc->sock;\n        nc->listener = lc;\n        nc->sa = *sa;\n        nc->proto_handler = lc->proto_handler;\n        nc->user_data = lc->user_data;\n        nc->recv_mbuf_limit = lc->recv_mbuf_limit;\n        nc->flags = MG_F_UDP;\n        /*\n         * Long-lived UDP \"connections\" i.e. interactions that involve more\n         * than one request and response are rare, most are transactional:\n         * response is sent and the \"connection\" is closed. Or - should be.\n         * But users (including ourselves) tend to forget about that part,\n         * because UDP is connectionless and one does not think about\n         * processing a UDP request as handling a connection that needs to be\n         * closed. Thus, we begin with SEND_AND_CLOSE flag set, which should\n         * be a reasonable default for most use cases, but it is possible to\n         * turn it off the connection should be kept alive after processing.\n         */\n        nc->flags |= MG_F_SEND_AND_CLOSE;\n        mg_add_conn(lc->mgr, nc);\n        mg_call(nc, NULL, MG_EV_ACCEPT, &nc->sa);\n      }\n      else\n      {\n        DBG((\"OOM\"));\n        /* No return here, we still need to drop on the floor */\n      }\n    }\n  }\n  if (nc != NULL)\n  {\n    mg_recv_common(nc, buf, len, 1);\n  }\n  else\n  {\n    /* Drop on the floor. */\n    MG_FREE(buf);\n    nc->iface->vtable->recved(nc, len);\n  }\n}\n\n/*\n * Schedules an async connect for a resolved address and proto.\n * Called from two places: `mg_connect_opt()` and from async resolver.\n * When called from the async resolver, it must trigger `MG_EV_CONNECT` event\n * with a failure flag to indicate connection failure.\n */\nMG_INTERNAL struct mg_connection *mg_do_connect(struct mg_connection *nc,\n                                                int proto,\n                                                union socket_address *sa)\n{\n  DBG((\"%p %s://%s:%hu\", nc, proto == SOCK_DGRAM ? \"udp\" : \"tcp\",\n       inet_ntoa(sa->sin.sin_addr), ntohs(sa->sin.sin_port)));\n\n  nc->flags |= MG_F_CONNECTING;\n  if (proto == SOCK_DGRAM)\n  {\n    nc->iface->vtable->connect_udp(nc);\n  }\n  else\n  {\n    nc->iface->vtable->connect_tcp(nc, sa);\n  }\n  mg_add_conn(nc->mgr, nc);\n  return nc;\n}\n\nvoid mg_if_connect_cb(struct mg_connection *nc, int err)\n{\n  DBG((\"%p connect, err=%d\", nc, err));\n  nc->flags &= ~MG_F_CONNECTING;\n  if (err != 0)\n  {\n    nc->flags |= MG_F_CLOSE_IMMEDIATELY;\n  }\n  mg_call(nc, NULL, MG_EV_CONNECT, &err);\n}\n\n#if MG_ENABLE_ASYNC_RESOLVER\n/*\n * Callback for the async resolver on mg_connect_opt() call.\n * Main task of this function is to trigger MG_EV_CONNECT event with\n *    either failure (and dealloc the connection)\n *    or success (and proceed with connect()\n */\nstatic void resolve_cb(struct mg_dns_message *msg, void *data,\n                       enum mg_resolve_err e)\n{\n  struct mg_connection *nc = (struct mg_connection *)data;\n  int i;\n  int failure = -1;\n\n  nc->flags &= ~MG_F_RESOLVING;\n  if (msg != NULL)\n  {\n    /*\n     * Take the first DNS A answer and run...\n     */\n    for (i = 0; i < msg->num_answers; i++)\n    {\n      if (msg->answers[i].rtype == MG_DNS_A_RECORD)\n      {\n        /*\n         * Async resolver guarantees that there is at least one answer.\n         * TODO(lsm): handle IPv6 answers too\n         */\n        mg_dns_parse_record_data(msg, &msg->answers[i], &nc->sa.sin.sin_addr,\n                                 4);\n        mg_do_connect(nc, nc->flags & MG_F_UDP ? SOCK_DGRAM : SOCK_STREAM,\n                      &nc->sa);\n        return;\n      }\n    }\n  }\n\n  if (e == MG_RESOLVE_TIMEOUT)\n  {\n    double now = mg_time();\n    mg_call(nc, NULL, MG_EV_TIMER, &now);\n  }\n\n  /*\n   * If we get there was no MG_DNS_A_RECORD in the answer\n   */\n  mg_call(nc, NULL, MG_EV_CONNECT, &failure);\n  mg_call(nc, NULL, MG_EV_CLOSE, NULL);\n  mg_destroy_conn(nc, 1 /* destroy_if */);\n}\n#endif\n\nstruct mg_connection *mg_connect(struct mg_mgr *mgr, const char *address,\n                                 mg_event_handler_t callback)\n{\n  struct mg_connect_opts opts;\n  memset(&opts, 0, sizeof(opts));\n  return mg_connect_opt(mgr, address, callback, opts);\n}\n\nstruct mg_connection *mg_connect_opt(struct mg_mgr *mgr, const char *address,\n                                     mg_event_handler_t callback,\n                                     struct mg_connect_opts opts)\n{\n  struct mg_connection *nc = NULL;\n  int proto, rc;\n  struct mg_add_sock_opts add_sock_opts;\n  char host[MG_MAX_HOST_LEN];\n\n  MG_COPY_COMMON_CONNECTION_OPTIONS(&add_sock_opts, &opts);\n\n  if ((nc = mg_create_connection(mgr, callback, add_sock_opts)) == NULL)\n  {\n    return NULL;\n  }\n\n  if ((rc = mg_parse_address(address, &nc->sa, &proto, host, sizeof(host))) <\n      0)\n  {\n    /* Address is malformed */\n    MG_SET_PTRPTR(opts.error_string, \"cannot parse address\");\n    mg_destroy_conn(nc, 1 /* destroy_if */);\n    return NULL;\n  }\n\n  nc->flags |= opts.flags & _MG_ALLOWED_CONNECT_FLAGS_MASK;\n  nc->flags |= (proto == SOCK_DGRAM) ? MG_F_UDP : 0;\n  nc->user_data = opts.user_data;\n\n#if MG_ENABLE_SSL\n  DBG((\"%p %s %s,%s,%s\", nc, address, (opts.ssl_cert ? opts.ssl_cert : \"-\"),\n       (opts.ssl_key ? opts.ssl_key : \"-\"),\n       (opts.ssl_ca_cert ? opts.ssl_ca_cert : \"-\")));\n\n  if (opts.ssl_cert != NULL || opts.ssl_ca_cert != NULL)\n  {\n    const char *err_msg = NULL;\n    struct mg_ssl_if_conn_params params;\n    if (nc->flags & MG_F_UDP)\n    {\n      MG_SET_PTRPTR(opts.error_string, \"SSL for UDP is not supported\");\n      mg_destroy_conn(nc, 1 /* destroy_if */);\n      return NULL;\n    }\n    memset(&params, 0, sizeof(params));\n    params.cert = opts.ssl_cert;\n    params.key = opts.ssl_key;\n    params.ca_cert = opts.ssl_ca_cert;\n    if (opts.ssl_ca_cert != NULL)\n    {\n      if (opts.ssl_server_name != NULL)\n      {\n        if (strcmp(opts.ssl_server_name, \"*\") != 0)\n        {\n          params.server_name = opts.ssl_server_name;\n        }\n      }\n      else if (rc == 0)\n      { /* If it's a DNS name, use host. */\n        params.server_name = host;\n      }\n    }\n    if (mg_ssl_if_conn_init(nc, &params, &err_msg) != MG_SSL_OK)\n    {\n      MG_SET_PTRPTR(opts.error_string, err_msg);\n      mg_destroy_conn(nc, 1 /* destroy_if */);\n      return NULL;\n    }\n    nc->flags |= MG_F_SSL;\n  }\n#endif /* MG_ENABLE_SSL */\n\n  if (rc == 0)\n  {\n#if MG_ENABLE_ASYNC_RESOLVER\n    /*\n     * DNS resolution is required for host.\n     * mg_parse_address() fills port in nc->sa, which we pass to resolve_cb()\n     */\n    struct mg_connection *dns_conn = NULL;\n    struct mg_resolve_async_opts o;\n    memset(&o, 0, sizeof(o));\n    o.dns_conn = &dns_conn;\n    if (mg_resolve_async_opt(nc->mgr, host, MG_DNS_A_RECORD, resolve_cb, nc,\n                             o) != 0)\n    {\n      MG_SET_PTRPTR(opts.error_string, \"cannot schedule DNS lookup\");\n      mg_destroy_conn(nc, 1 /* destroy_if */);\n      return NULL;\n    }\n    nc->priv_2 = dns_conn;\n    nc->flags |= MG_F_RESOLVING;\n    return nc;\n#else\n    MG_SET_PTRPTR(opts.error_string, \"Resolver is disabled\");\n    mg_destroy_conn(nc, 1 /* destroy_if */);\n    return NULL;\n#endif\n  }\n  else\n  {\n    /* Address is parsed and resolved to IP. proceed with connect() */\n    return mg_do_connect(nc, proto, &nc->sa);\n  }\n}\n\nstruct mg_connection *mg_bind(struct mg_mgr *srv, const char *address,\n                              mg_event_handler_t event_handler)\n{\n  struct mg_bind_opts opts;\n  memset(&opts, 0, sizeof(opts));\n  return mg_bind_opt(srv, address, event_handler, opts);\n}\n\nstruct mg_connection *mg_bind_opt(struct mg_mgr *mgr, const char *address,\n                                  mg_event_handler_t callback,\n                                  struct mg_bind_opts opts)\n{\n  union socket_address sa;\n  struct mg_connection *nc = NULL;\n  int proto, rc;\n  struct mg_add_sock_opts add_sock_opts;\n  char host[MG_MAX_HOST_LEN];\n\n  MG_COPY_COMMON_CONNECTION_OPTIONS(&add_sock_opts, &opts);\n\n#if MG_ENABLE_TUN\n  if (mg_strncmp(mg_mk_str(address), mg_mk_str(\"ws://\"), 5) == 0 ||\n      mg_strncmp(mg_mk_str(address), mg_mk_str(\"wss://\"), 6) == 0)\n  {\n    return mg_tun_bind_opt(mgr, address, callback, opts);\n  }\n#endif\n\n  if (mg_parse_address(address, &sa, &proto, host, sizeof(host)) <= 0)\n  {\n    MG_SET_PTRPTR(opts.error_string, \"cannot parse address\");\n    return NULL;\n  }\n\n  nc = mg_create_connection(mgr, callback, add_sock_opts);\n  if (nc == NULL)\n  {\n    return NULL;\n  }\n\n  nc->sa = sa;\n  nc->flags |= MG_F_LISTENING;\n  if (proto == SOCK_DGRAM)\n    nc->flags |= MG_F_UDP;\n\n#if MG_ENABLE_SSL\n  DBG((\"%p %s %s,%s,%s\", nc, address, (opts.ssl_cert ? opts.ssl_cert : \"-\"),\n       (opts.ssl_key ? opts.ssl_key : \"-\"),\n       (opts.ssl_ca_cert ? opts.ssl_ca_cert : \"-\")));\n\n  if (opts.ssl_cert != NULL || opts.ssl_ca_cert != NULL)\n  {\n    const char *err_msg = NULL;\n    struct mg_ssl_if_conn_params params;\n    if (nc->flags & MG_F_UDP)\n    {\n      MG_SET_PTRPTR(opts.error_string, \"SSL for UDP is not supported\");\n      mg_destroy_conn(nc, 1 /* destroy_if */);\n      return NULL;\n    }\n    memset(&params, 0, sizeof(params));\n    params.cert = opts.ssl_cert;\n    params.key = opts.ssl_key;\n    params.ca_cert = opts.ssl_ca_cert;\n    if (mg_ssl_if_conn_init(nc, &params, &err_msg) != MG_SSL_OK)\n    {\n      MG_SET_PTRPTR(opts.error_string, err_msg);\n      mg_destroy_conn(nc, 1 /* destroy_if */);\n      return NULL;\n    }\n    nc->flags |= MG_F_SSL;\n  }\n#endif /* MG_ENABLE_SSL */\n\n  if (nc->flags & MG_F_UDP)\n  {\n    rc = nc->iface->vtable->listen_udp(nc, &nc->sa);\n  }\n  else\n  {\n    rc = nc->iface->vtable->listen_tcp(nc, &nc->sa);\n  }\n  if (rc != 0)\n  {\n    DBG((\"Failed to open listener: %d\", rc));\n    MG_SET_PTRPTR(opts.error_string, \"failed to open listener\");\n    mg_destroy_conn(nc, 1 /* destroy_if */);\n    return NULL;\n  }\n  mg_add_conn(nc->mgr, nc);\n\n  return nc;\n}\n\nstruct mg_connection *mg_next(struct mg_mgr *s, struct mg_connection *conn)\n{\n  return conn == NULL ? s->active_connections : conn->next;\n}\n\n#if MG_ENABLE_BROADCAST\nvoid mg_broadcast(struct mg_mgr *mgr, mg_event_handler_t cb, void *data,\n                  size_t len)\n{\n  struct ctl_msg ctl_msg;\n\n  /*\n   * Mongoose manager has a sockucnair, `struct mg_mgr::ctl`,\n   * where `mg_broadcast()` pushes the message.\n   * `mg_mgr_poll()` wakes up, reads a message from the socket pair, and calls\n   * specified callback for each connection. Thus the callback function executes\n   * in event manager thread.\n   */\n  if (mgr->ctl[0] != INVALID_SOCKET && data != NULL &&\n      len < sizeof(ctl_msg.message))\n  {\n    size_t dummy;\n\n    ctl_msg.callback = cb;\n    memcpy(ctl_msg.message, data, len);\n    dummy = MG_SEND_FUNC(mgr->ctl[0], (char *)&ctl_msg,\n                         offsetof(struct ctl_msg, message) + len, 0);\n    dummy = MG_RECV_FUNC(mgr->ctl[0], (char *)&len, 1, 0);\n    (void)dummy; /* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25509 */\n  }\n}\n#endif /* MG_ENABLE_BROADCAST */\n\nstatic int isbyte(int n)\n{\n  return n >= 0 && n <= 255;\n}\n\nstatic int parse_net(const char *spec, uint32_t *net, uint32_t *mask)\n{\n  int n, a, b, c, d, slash = 32, len = 0;\n\n  if ((sscanf(spec, \"%d.%d.%d.%d/%d%n\", &a, &b, &c, &d, &slash, &n) == 5 ||\n       sscanf(spec, \"%d.%d.%d.%d%n\", &a, &b, &c, &d, &n) == 4) &&\n      isbyte(a) && isbyte(b) && isbyte(c) && isbyte(d) && slash >= 0 &&\n      slash < 33)\n  {\n    len = n;\n    *net =\n        ((uint32_t)a << 24) | ((uint32_t)b << 16) | ((uint32_t)c << 8) | d;\n    *mask = slash ? 0xffffffffU << (32 - slash) : 0;\n  }\n\n  return len;\n}\n\nint mg_check_ip_acl(const char *acl, uint32_t remote_ip)\n{\n  int allowed, flag;\n  uint32_t net, mask;\n  struct mg_str vec;\n\n  /* If any ACL is set, deny by default */\n  allowed = (acl == NULL || *acl == '\\0') ? '+' : '-';\n\n  while ((acl = mg_next_comma_list_entry(acl, &vec, NULL)) != NULL)\n  {\n    flag = vec.p[0];\n    if ((flag != '+' && flag != '-') ||\n        parse_net(&vec.p[1], &net, &mask) == 0)\n    {\n      return -1;\n    }\n\n    if (net == (remote_ip & mask))\n    {\n      allowed = flag;\n    }\n  }\n\n  DBG((\"%08x %c\", remote_ip, allowed));\n  return allowed == '+';\n}\n\n/* Move data from one connection to another */\nvoid mg_forward(struct mg_connection *from, struct mg_connection *to)\n{\n  mg_send(to, from->recv_mbuf.buf, from->recv_mbuf.len);\n  mbuf_remove(&from->recv_mbuf, from->recv_mbuf.len);\n}\n\ndouble mg_set_timer(struct mg_connection *c, double timestamp)\n{\n  double result = c->ev_timer_time;\n  c->ev_timer_time = timestamp;\n  /*\n   * If this connection is resolving, it's not in the list of active\n   * connections, so not processed yet. It has a DNS resolver connection\n   * linked to it. Set up a timer for the DNS connection.\n   */\n  DBG((\"%p %p %d -> %lu\", c, c->priv_2, c->flags & MG_F_RESOLVING,\n       (unsigned long)timestamp));\n  if ((c->flags & MG_F_RESOLVING) && c->priv_2 != NULL)\n  {\n    ((struct mg_connection *)c->priv_2)->ev_timer_time = timestamp;\n  }\n  return result;\n}\n\nvoid mg_sock_set(struct mg_connection *nc, sock_t sock)\n{\n  nc->iface->vtable->sock_set(nc, sock);\n}\n\nvoid mg_if_get_conn_addr(struct mg_connection *nc, int remote,\n                         union socket_address *sa)\n{\n  nc->iface->vtable->get_conn_addr(nc, remote, sa);\n}\n\nstruct mg_connection *mg_add_sock_opt(struct mg_mgr *s, sock_t sock,\n                                      mg_event_handler_t callback,\n                                      struct mg_add_sock_opts opts)\n{\n  struct mg_connection *nc = mg_create_connection_base(s, callback, opts);\n  if (nc != NULL)\n  {\n    mg_sock_set(nc, sock);\n    mg_add_conn(nc->mgr, nc);\n  }\n  return nc;\n}\n\nstruct mg_connection *mg_add_sock(struct mg_mgr *s, sock_t sock,\n                                  mg_event_handler_t callback)\n{\n  struct mg_add_sock_opts opts;\n  memset(&opts, 0, sizeof(opts));\n  return mg_add_sock_opt(s, sock, callback, opts);\n}\n\ndouble mg_time(void)\n{\n  return cs_time();\n}\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/net_if_socket.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_MONGOOSE_SRC_NET_IF_SOCKET_H_\n#define CS_MONGOOSE_SRC_NET_IF_SOCKET_H_\n\n/* Amalgamated: #include \"mongoose/src/net_if.h\" */\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif /* __cplusplus */\n\n#ifndef MG_ENABLE_NET_IF_SOCKET\n#define MG_ENABLE_NET_IF_SOCKET MG_NET_IF == MG_NET_IF_SOCKET\n#endif\n\n  extern struct mg_iface_vtable mg_socket_iface_vtable;\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif /* CS_MONGOOSE_SRC_NET_IF_SOCKET_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/net_if_tun.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_MONGOOSE_SRC_NET_IF_TUN_H_\n#define CS_MONGOOSE_SRC_NET_IF_TUN_H_\n\n#if MG_ENABLE_TUN\n\n/* Amalgamated: #include \"mongoose/src/net_if.h\" */\n\nstruct mg_tun_client;\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif /* __cplusplus */\n\n  extern struct mg_iface_vtable mg_tun_iface_vtable;\n\n  struct mg_connection *mg_tun_if_find_conn(struct mg_tun_client *client,\n                                            uint32_t stream_id);\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif /* MG_ENABLE_TUN */\n\n#endif /* CS_MONGOOSE_SRC_NET_IF_TUN_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/net_if.c\"\n#endif\n/* Amalgamated: #include \"mongoose/src/net_if.h\" */\n/* Amalgamated: #include \"mongoose/src/internal.h\" */\n/* Amalgamated: #include \"mongoose/src/net_if_socket.h\" */\n/* Amalgamated: #include \"mongoose/src/net_if_tun.h\" */\n\nextern struct mg_iface_vtable mg_default_iface_vtable;\n\n#if MG_ENABLE_TUN\nstruct mg_iface_vtable *mg_ifaces[] = {&mg_default_iface_vtable,\n                                       &mg_tun_iface_vtable};\n#else\nstruct mg_iface_vtable *mg_ifaces[] = {&mg_default_iface_vtable};\n#endif\n\nint mg_num_ifaces = (int)(sizeof(mg_ifaces) / sizeof(mg_ifaces[0]));\n\nstruct mg_iface *mg_if_create_iface(struct mg_iface_vtable *vtable,\n                                    struct mg_mgr *mgr)\n{\n  struct mg_iface *iface = (struct mg_iface *)MG_CALLOC(1, sizeof(*iface));\n  iface->mgr = mgr;\n  iface->data = NULL;\n  iface->vtable = vtable;\n  return iface;\n}\n\nstruct mg_iface *mg_find_iface(struct mg_mgr *mgr,\n                               struct mg_iface_vtable *vtable,\n                               struct mg_iface *from)\n{\n  int i = 0;\n  if (from != NULL)\n  {\n    for (i = 0; i < mgr->num_ifaces; i++)\n    {\n      if (mgr->ifaces[i] == from)\n      {\n        i++;\n        break;\n      }\n    }\n  }\n\n  for (; i < mgr->num_ifaces; i++)\n  {\n    if (mgr->ifaces[i]->vtable == vtable)\n    {\n      return mgr->ifaces[i];\n    }\n  }\n  return NULL;\n}\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/net_if_socket.c\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#if MG_ENABLE_NET_IF_SOCKET\n\n/* Amalgamated: #include \"mongoose/src/net_if_socket.h\" */\n/* Amalgamated: #include \"mongoose/src/internal.h\" */\n/* Amalgamated: #include \"mongoose/src/util.h\" */\n\n#define MG_TCP_RECV_BUFFER_SIZE 1024\n#define MG_UDP_RECV_BUFFER_SIZE 1500\n\nstatic sock_t mg_open_listening_socket(union socket_address *sa, int type,\n                                       int proto);\n#if MG_ENABLE_SSL\nstatic void mg_ssl_begin(struct mg_connection *nc);\n#endif\n\nvoid mg_set_non_blocking_mode(sock_t sock)\n{\n#ifdef _WIN32\n  unsigned long on = 1;\n  ioctlsocket(sock, FIONBIO, &on);\n#else\n  int flags = fcntl(sock, F_GETFL, 0);\n  fcntl(sock, F_SETFL, flags | O_NONBLOCK);\n#endif\n}\n\nstatic int mg_is_error(int n)\n{\n  int err = mg_get_errno();\n  return (n < 0 && err != EINPROGRESS && err != EWOULDBLOCK\n#ifndef WINCE\n          && err != EAGAIN && err != EINTR\n#endif\n#ifdef _WIN32\n          && WSAGetLastError() != WSAEINTR &&\n          WSAGetLastError() != WSAEWOULDBLOCK\n#endif\n  );\n}\n\nvoid mg_socket_if_connect_tcp(struct mg_connection *nc,\n                              const union socket_address *sa)\n{\n  int rc, proto = 0;\n  nc->sock = socket(AF_INET, SOCK_STREAM, proto);\n  if (nc->sock == INVALID_SOCKET)\n  {\n    nc->err = mg_get_errno() ? mg_get_errno() : 1;\n    return;\n  }\n#if !defined(MG_ESP8266)\n  mg_set_non_blocking_mode(nc->sock);\n#endif\n  rc = connect(nc->sock, &sa->sa, sizeof(sa->sin));\n  nc->err = mg_is_error(rc) ? mg_get_errno() : 0;\n  LOG(LL_INFO, (\"%p sock %d err %d\", nc, nc->sock, nc->err));\n}\n\nvoid mg_socket_if_connect_udp(struct mg_connection *nc)\n{\n  nc->sock = socket(AF_INET, SOCK_DGRAM, 0);\n  if (nc->sock == INVALID_SOCKET)\n  {\n    nc->err = mg_get_errno() ? mg_get_errno() : 1;\n    return;\n  }\n  if (nc->flags & MG_F_ENABLE_BROADCAST)\n  {\n    int optval = 1;\n    setsockopt(nc->sock, SOL_SOCKET, SO_BROADCAST, (const char *)&optval,\n               sizeof(optval));\n  }\n  nc->err = 0;\n}\n\nint mg_socket_if_listen_tcp(struct mg_connection *nc,\n                            union socket_address *sa)\n{\n  int proto = 0;\n  sock_t sock = mg_open_listening_socket(sa, SOCK_STREAM, proto);\n  if (sock == INVALID_SOCKET)\n  {\n    return (mg_get_errno() ? mg_get_errno() : 1);\n  }\n  mg_sock_set(nc, sock);\n  return 0;\n}\n\nint mg_socket_if_listen_udp(struct mg_connection *nc,\n                            union socket_address *sa)\n{\n  sock_t sock = mg_open_listening_socket(sa, SOCK_DGRAM, 0);\n  if (sock == INVALID_SOCKET)\n    return (mg_get_errno() ? mg_get_errno() : 1);\n  mg_sock_set(nc, sock);\n  return 0;\n}\n\nvoid mg_socket_if_tcp_send(struct mg_connection *nc, const void *buf,\n                           size_t len)\n{\n  mbuf_append(&nc->send_mbuf, buf, len);\n}\n\nvoid mg_socket_if_udp_send(struct mg_connection *nc, const void *buf,\n                           size_t len)\n{\n  mbuf_append(&nc->send_mbuf, buf, len);\n}\n\nvoid mg_socket_if_recved(struct mg_connection *nc, size_t len)\n{\n  (void)nc;\n  (void)len;\n}\n\nint mg_socket_if_create_conn(struct mg_connection *nc)\n{\n  (void)nc;\n  return 1;\n}\n\nvoid mg_socket_if_destroy_conn(struct mg_connection *nc)\n{\n  if (nc->sock == INVALID_SOCKET)\n    return;\n  if (!(nc->flags & MG_F_UDP))\n  {\n    closesocket(nc->sock);\n  }\n  else\n  {\n    /* Only close outgoing UDP sockets or listeners. */\n    if (nc->listener == NULL)\n      closesocket(nc->sock);\n  }\n  nc->sock = INVALID_SOCKET;\n}\n\nstatic int mg_accept_conn(struct mg_connection *lc)\n{\n  struct mg_connection *nc;\n  union socket_address sa;\n  socklen_t sa_len = sizeof(sa);\n  /* NOTE(lsm): on Windows, sock is always > FD_SETSIZE */\n  sock_t sock = accept(lc->sock, &sa.sa, &sa_len);\n  if (sock == INVALID_SOCKET)\n  {\n    if (mg_is_error(-1))\n      DBG((\"%p: failed to accept: %d\", lc, mg_get_errno()));\n    return 0;\n  }\n  nc = mg_if_accept_new_conn(lc);\n  if (nc == NULL)\n  {\n    closesocket(sock);\n    return 0;\n  }\n  DBG((\"%p conn from %s:%d\", nc, inet_ntoa(sa.sin.sin_addr),\n       ntohs(sa.sin.sin_port)));\n  mg_sock_set(nc, sock);\n#if MG_ENABLE_SSL\n  if (lc->flags & MG_F_SSL)\n  {\n    if (mg_ssl_if_conn_accept(nc, lc) != MG_SSL_OK)\n      mg_close_conn(nc);\n  }\n  else\n#endif\n  {\n    mg_if_accept_tcp_cb(nc, &sa, sa_len);\n  }\n  return 1;\n}\n\n/* 'sa' must be an initialized address to bind to */\nstatic sock_t mg_open_listening_socket(union socket_address *sa, int type,\n                                       int proto)\n{\n  socklen_t sa_len =\n      (sa->sa.sa_family == AF_INET) ? sizeof(sa->sin) : sizeof(sa->sin6);\n  sock_t sock = INVALID_SOCKET;\n#if !MG_LWIP\n  int on = 1;\n#endif\n\n  if ((sock = socket(sa->sa.sa_family, type, proto)) != INVALID_SOCKET &&\n#if !MG_LWIP /* LWIP doesn't support either */\n#if defined(_WIN32) && defined(SO_EXCLUSIVEADDRUSE) && !defined(WINCE)\n      /* \"Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE\" http://goo.gl/RmrFTm */\n      !setsockopt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (void *)&on,\n                  sizeof(on)) &&\n#endif\n\n#if !defined(_WIN32) || !defined(SO_EXCLUSIVEADDRUSE)\n      /*\n       * SO_RESUSEADDR is not enabled on Windows because the semantics of\n       * SO_REUSEADDR on UNIX and Windows is different. On Windows,\n       * SO_REUSEADDR allows to bind a socket to a port without error even if\n       * the port is already open by another program. This is not the behavior\n       * SO_REUSEADDR was designed for, and leads to hard-to-track failure\n       * scenarios. Therefore, SO_REUSEADDR was disabled on Windows unless\n       * SO_EXCLUSIVEADDRUSE is supported and set on a socket.\n       */\n      !setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)) &&\n#endif\n#endif /* !MG_LWIP */\n\n      !bind(sock, &sa->sa, sa_len) &&\n      (type == SOCK_DGRAM || listen(sock, SOMAXCONN) == 0))\n  {\n#if !MG_LWIP\n    mg_set_non_blocking_mode(sock);\n    /* In case port was set to 0, get the real port number */\n    (void)getsockname(sock, &sa->sa, &sa_len);\n#endif\n  }\n  else if (sock != INVALID_SOCKET)\n  {\n    closesocket(sock);\n    sock = INVALID_SOCKET;\n  }\n\n  return sock;\n}\n\nstatic void mg_write_to_socket(struct mg_connection *nc)\n{\n  struct mbuf *io = &nc->send_mbuf;\n  int n = 0;\n\n#if MG_LWIP\n  /* With LWIP we don't know if the socket is ready */\n  if (io->len == 0)\n    return;\n#endif\n\n  assert(io->len > 0);\n\n  if (nc->flags & MG_F_UDP)\n  {\n    int n =\n        sendto(nc->sock, io->buf, io->len, 0, &nc->sa.sa, sizeof(nc->sa.sin));\n    DBG((\"%p %d %d %d %s:%hu\", nc, nc->sock, n, mg_get_errno(),\n         inet_ntoa(nc->sa.sin.sin_addr), ntohs(nc->sa.sin.sin_port)));\n    if (n > 0)\n    {\n      mbuf_remove(io, n);\n      mg_if_sent_cb(nc, n);\n    }\n    return;\n  }\n\n#if MG_ENABLE_SSL\n  if (nc->flags & MG_F_SSL)\n  {\n    if (nc->flags & MG_F_SSL_HANDSHAKE_DONE)\n    {\n      n = mg_ssl_if_write(nc, io->buf, io->len);\n      DBG((\"%p %d bytes -> %d (SSL)\", nc, n, nc->sock));\n      if (n < 0)\n      {\n        if (n != MG_SSL_WANT_READ && n != MG_SSL_WANT_WRITE)\n        {\n          nc->flags |= MG_F_CLOSE_IMMEDIATELY;\n        }\n        return;\n      }\n      else\n      {\n        /* Successful SSL operation, clear off SSL wait flags */\n        nc->flags &= ~(MG_F_WANT_READ | MG_F_WANT_WRITE);\n      }\n    }\n    else\n    {\n      mg_ssl_begin(nc);\n      return;\n    }\n  }\n  else\n#endif\n  {\n    n = (int)MG_SEND_FUNC(nc->sock, io->buf, io->len, 0);\n    DBG((\"%p %d bytes -> %d\", nc, n, nc->sock));\n    if (n < 0 && mg_is_error(n))\n    {\n      /* Something went wrong, drop the connection. */\n      nc->flags |= MG_F_CLOSE_IMMEDIATELY;\n      return;\n    }\n  }\n\n  if (n > 0)\n  {\n    mbuf_remove(io, n);\n    mg_if_sent_cb(nc, n);\n  }\n}\n\nMG_INTERNAL size_t recv_avail_size(struct mg_connection *conn, size_t max)\n{\n  size_t avail;\n  if (conn->recv_mbuf_limit < conn->recv_mbuf.len)\n    return 0;\n  avail = conn->recv_mbuf_limit - conn->recv_mbuf.len;\n  return avail > max ? max : avail;\n}\n\nstatic void mg_handle_tcp_read(struct mg_connection *conn)\n{\n  int n = 0;\n  char *buf = (char *)MG_MALLOC(MG_TCP_RECV_BUFFER_SIZE);\n\n  if (buf == NULL)\n  {\n    DBG((\"OOM\"));\n    return;\n  }\n\n#if MG_ENABLE_SSL\n  if (conn->flags & MG_F_SSL)\n  {\n    if (conn->flags & MG_F_SSL_HANDSHAKE_DONE)\n    {\n      /* SSL library may have more bytes ready to read than we ask to read.\n       * Therefore, read in a loop until we read everything. Without the loop,\n       * we skip to the next select() cycle which can just timeout. */\n      while ((n = mg_ssl_if_read(conn, buf, MG_TCP_RECV_BUFFER_SIZE)) > 0)\n      {\n        DBG((\"%p %d bytes <- %d (SSL)\", conn, n, conn->sock));\n        mg_if_recv_tcp_cb(conn, buf, n, 1 /* own */);\n        buf = NULL;\n        if (conn->flags & MG_F_CLOSE_IMMEDIATELY)\n          break;\n        /* buf has been freed, we need a new one. */\n        buf = (char *)MG_MALLOC(MG_TCP_RECV_BUFFER_SIZE);\n        if (buf == NULL)\n          break;\n      }\n      MG_FREE(buf);\n      if (n < 0 && n != MG_SSL_WANT_READ)\n        conn->flags |= MG_F_CLOSE_IMMEDIATELY;\n    }\n    else\n    {\n      MG_FREE(buf);\n      mg_ssl_begin(conn);\n      return;\n    }\n  }\n  else\n#endif\n  {\n    n = (int)MG_RECV_FUNC(conn->sock, buf,\n                          recv_avail_size(conn, MG_TCP_RECV_BUFFER_SIZE), 0);\n    DBG((\"%p %d bytes (PLAIN) <- %d\", conn, n, conn->sock));\n    if (n > 0)\n    {\n      mg_if_recv_tcp_cb(conn, buf, n, 1 /* own */);\n    }\n    else\n    {\n      MG_FREE(buf);\n    }\n    if (n == 0)\n    {\n      /* Orderly shutdown of the socket, try flushing output. */\n      conn->flags |= MG_F_SEND_AND_CLOSE;\n    }\n    else if (mg_is_error(n))\n    {\n      conn->flags |= MG_F_CLOSE_IMMEDIATELY;\n    }\n  }\n}\n\nstatic int mg_recvfrom(struct mg_connection *nc, union socket_address *sa,\n                       socklen_t *sa_len, char **buf)\n{\n  int n;\n  *buf = (char *)MG_MALLOC(MG_UDP_RECV_BUFFER_SIZE);\n  if (*buf == NULL)\n  {\n    DBG((\"Out of memory\"));\n    return -ENOMEM;\n  }\n  n = recvfrom(nc->sock, *buf, MG_UDP_RECV_BUFFER_SIZE, 0, &sa->sa, sa_len);\n  if (n <= 0)\n  {\n    DBG((\"%p recvfrom: %s\", nc, strerror(mg_get_errno())));\n    MG_FREE(*buf);\n  }\n  return n;\n}\n\nstatic void mg_handle_udp_read(struct mg_connection *nc)\n{\n  char *buf = NULL;\n  union socket_address sa;\n  socklen_t sa_len = sizeof(sa);\n  int n = mg_recvfrom(nc, &sa, &sa_len, &buf);\n  DBG((\"%p %d bytes from %s:%d\", nc, n, inet_ntoa(nc->sa.sin.sin_addr),\n       ntohs(nc->sa.sin.sin_port)));\n  mg_if_recv_udp_cb(nc, buf, n, &sa, sa_len);\n}\n\n#if MG_ENABLE_SSL\nstatic void mg_ssl_begin(struct mg_connection *nc)\n{\n  int server_side = (nc->listener != NULL);\n  enum mg_ssl_if_result res = mg_ssl_if_handshake(nc);\n  DBG((\"%p %d res %d\", nc, server_side, res));\n\n  if (res == MG_SSL_OK)\n  {\n    nc->flags |= MG_F_SSL_HANDSHAKE_DONE;\n    nc->flags &= ~(MG_F_WANT_READ | MG_F_WANT_WRITE);\n\n    if (server_side)\n    {\n      union socket_address sa;\n      socklen_t sa_len = sizeof(sa);\n      (void)getpeername(nc->sock, &sa.sa, &sa_len);\n      mg_if_accept_tcp_cb(nc, &sa, sa_len);\n    }\n    else\n    {\n      mg_if_connect_cb(nc, 0);\n    }\n  }\n  else if (res != MG_SSL_WANT_READ && res != MG_SSL_WANT_WRITE)\n  {\n    if (!server_side)\n    {\n      mg_if_connect_cb(nc, res);\n    }\n    nc->flags |= MG_F_CLOSE_IMMEDIATELY;\n  }\n}\n#endif /* MG_ENABLE_SSL */\n\n#define _MG_F_FD_CAN_READ 1\n#define _MG_F_FD_CAN_WRITE 1 << 1\n#define _MG_F_FD_ERROR 1 << 2\n\nvoid mg_mgr_handle_conn(struct mg_connection *nc, int fd_flags, double now)\n{\n  int worth_logging =\n      fd_flags != 0 || (nc->flags & (MG_F_WANT_READ | MG_F_SSL_HANDSHAKE_DONE |\n                                     MG_F_WANT_WRITE));\n  if (worth_logging)\n  {\n    DBG((\"%p fd=%d fd_flags=%d nc_flags=%lu rmbl=%d smbl=%d\", nc, nc->sock,\n         fd_flags, nc->flags, (int)nc->recv_mbuf.len,\n         (int)nc->send_mbuf.len));\n  }\n\n  if (nc->flags & MG_F_CONNECTING)\n  {\n    if (fd_flags != 0)\n    {\n      int err = 0;\n#if !defined(MG_ESP8266)\n      if (!(nc->flags & MG_F_UDP))\n      {\n        socklen_t len = sizeof(err);\n        int ret =\n            getsockopt(nc->sock, SOL_SOCKET, SO_ERROR, (char *)&err, &len);\n        if (ret != 0)\n          err = 1;\n      }\n#else\n      /*\n       * On ESP8266 we use blocking connect.\n       */\n      err = nc->err;\n#endif\n#if MG_ENABLE_SSL\n      if ((nc->flags & MG_F_SSL) && err == 0)\n      {\n        mg_ssl_begin(nc);\n      }\n      else\n      {\n        mg_if_connect_cb(nc, err);\n      }\n#else\n      mg_if_connect_cb(nc, err);\n#endif\n    }\n    else if (nc->err != 0)\n    {\n      mg_if_connect_cb(nc, nc->err);\n    }\n  }\n\n  if (fd_flags & _MG_F_FD_CAN_READ)\n  {\n    if (nc->flags & MG_F_UDP)\n    {\n      mg_handle_udp_read(nc);\n    }\n    else\n    {\n      if (nc->flags & MG_F_LISTENING)\n      {\n        /*\n         * We're not looping here, and accepting just one connection at\n         * a time. The reason is that eCos does not respect non-blocking\n         * flag on a listening socket and hangs in a loop.\n         */\n        mg_accept_conn(nc);\n      }\n      else\n      {\n        mg_handle_tcp_read(nc);\n      }\n    }\n  }\n\n  if (!(nc->flags & MG_F_CLOSE_IMMEDIATELY))\n  {\n    if ((fd_flags & _MG_F_FD_CAN_WRITE) && nc->send_mbuf.len > 0)\n    {\n      mg_write_to_socket(nc);\n    }\n\n    if (!(fd_flags & (_MG_F_FD_CAN_READ | _MG_F_FD_CAN_WRITE)))\n    {\n      mg_if_poll(nc, (time_t)now);\n    }\n    mg_if_timer(nc, now);\n  }\n\n  if (worth_logging)\n  {\n    DBG((\"%p after fd=%d nc_flags=%lu rmbl=%d smbl=%d\", nc, nc->sock, nc->flags,\n         (int)nc->recv_mbuf.len, (int)nc->send_mbuf.len));\n  }\n}\n\n#if MG_ENABLE_BROADCAST\nstatic void mg_mgr_handle_ctl_sock(struct mg_mgr *mgr)\n{\n  struct ctl_msg ctl_msg;\n  int len =\n      (int)MG_RECV_FUNC(mgr->ctl[1], (char *)&ctl_msg, sizeof(ctl_msg), 0);\n  size_t dummy = MG_SEND_FUNC(mgr->ctl[1], ctl_msg.message, 1, 0);\n  DBG((\"read %d from ctl socket\", len));\n  (void)dummy; /* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25509 */\n  if (len >= (int)sizeof(ctl_msg.callback) && ctl_msg.callback != NULL)\n  {\n    struct mg_connection *nc;\n    for (nc = mg_next(mgr, NULL); nc != NULL; nc = mg_next(mgr, nc))\n    {\n      ctl_msg.callback(nc, MG_EV_POLL, ctl_msg.message);\n    }\n  }\n}\n#endif\n\n#if MG_ENABLE_MUTITHREADS\nstatic void mg_mgr_handle_mthread_ctl_sock(struct mg_mgr *mgr)\n{\n  char d;\n  MG_RECV_FUNC(mgr->mthread_ctl[0], (char *)&d, 1, 0);\n}\n#endif\n\n/* Associate a socket to a connection. */\nvoid mg_socket_if_sock_set(struct mg_connection *nc, sock_t sock)\n{\n  mg_set_non_blocking_mode(sock);\n  mg_set_close_on_exec(sock);\n  nc->sock = sock;\n  DBG((\"%p %d\", nc, sock));\n}\n\nvoid mg_socket_if_init(struct mg_iface *iface)\n{\n  (void)iface;\n  DBG((\"%p using select()\", iface->mgr));\n#if MG_ENABLE_BROADCAST\n  do\n  {\n    mg_sockucnair(iface->mgr->ctl, SOCK_DGRAM);\n  } while (iface->mgr->ctl[0] == INVALID_SOCKET);\n#endif\n}\n\nvoid mg_socket_if_free(struct mg_iface *iface)\n{\n  (void)iface;\n}\n\nvoid mg_socket_if_add_conn(struct mg_connection *nc)\n{\n  (void)nc;\n}\n\nvoid mg_socket_if_remove_conn(struct mg_connection *nc)\n{\n  (void)nc;\n}\n\nvoid mg_add_to_set(sock_t sock, fd_set *set, sock_t *max_fd)\n{\n  if (sock != INVALID_SOCKET\n#ifdef __unix__\n      && sock < FD_SETSIZE\n#endif\n  )\n  {\n    FD_SET(sock, set);\n    if (*max_fd == INVALID_SOCKET || sock > *max_fd)\n    {\n      *max_fd = sock;\n    }\n  }\n}\n\ntime_t mg_socket_if_poll(struct mg_iface *iface, int timeout_ms)\n{\n  struct mg_mgr *mgr = iface->mgr;\n  double now = mg_time();\n  double min_timer;\n  struct mg_connection *nc, *tmp;\n  struct timeval tv;\n  fd_set read_set, write_set, err_set;\n  sock_t max_fd = INVALID_SOCKET;\n  int num_fds, num_ev, num_timers = 0;\n#ifdef __unix__\n  int try_dup = 1;\n#endif\n\n  FD_ZERO(&read_set);\n  FD_ZERO(&write_set);\n  FD_ZERO(&err_set);\n#if MG_ENABLE_BROADCAST\n  mg_add_to_set(mgr->ctl[1], &read_set, &max_fd);\n#endif\n\n#if MG_ENABLE_MUTITHREADS\n  if (mgr->mthread_ctl[0] != INVALID_SOCKET)\n  {\n    mg_add_to_set(mgr->mthread_ctl[0], &read_set, &max_fd);\n  }\n#endif\n\n  /*\n   * Note: it is ok to have connections with sock == INVALID_SOCKET in the list,\n   * e.g. timer-only \"connections\".\n   */\n  min_timer = 0;\n  for (nc = mgr->active_connections, num_fds = 0; nc != NULL; nc = tmp)\n  {\n    tmp = nc->next;\n\n    if (nc->sock != INVALID_SOCKET)\n    {\n      num_fds++;\n\n#ifdef __unix__\n      /* A hack to make sure all our file descriptos fit into FD_SETSIZE. */\n      if (nc->sock >= FD_SETSIZE && try_dup)\n      {\n        int new_sock = dup(nc->sock);\n        if (new_sock >= 0 && new_sock < FD_SETSIZE)\n        {\n          closesocket(nc->sock);\n          DBG((\"new sock %d -> %d\", nc->sock, new_sock));\n          nc->sock = new_sock;\n        }\n        else\n        {\n          try_dup = 0;\n        }\n      }\n#endif\n\n      if (!(nc->flags & MG_F_WANT_WRITE) &&\n          nc->recv_mbuf.len < nc->recv_mbuf_limit &&\n          (!(nc->flags & MG_F_UDP) || nc->listener == NULL))\n      {\n        mg_add_to_set(nc->sock, &read_set, &max_fd);\n      }\n\n      if (((nc->flags & MG_F_CONNECTING) && !(nc->flags & MG_F_WANT_READ)) ||\n          (nc->send_mbuf.len > 0 && !(nc->flags & MG_F_CONNECTING)))\n      {\n        mg_add_to_set(nc->sock, &write_set, &max_fd);\n        mg_add_to_set(nc->sock, &err_set, &max_fd);\n      }\n    }\n\n    if (nc->ev_timer_time > 0)\n    {\n      if (num_timers == 0 || nc->ev_timer_time < min_timer)\n      {\n        min_timer = nc->ev_timer_time;\n      }\n      num_timers++;\n    }\n  }\n\n  /*\n   * If there is a timer to be fired earlier than the requested timeout,\n   * adjust the timeout.\n   */\n  if (num_timers > 0)\n  {\n    double timer_timeout_ms = (min_timer - mg_time()) * 1000 + 1 /* rounding */;\n    if (timer_timeout_ms < timeout_ms)\n    {\n      timeout_ms = (int)timer_timeout_ms;\n    }\n  }\n  if (timeout_ms < 0)\n    timeout_ms = 0;\n\n  tv.tv_sec = timeout_ms / 1000;\n  tv.tv_usec = (timeout_ms % 1000) * 1000;\n\n  num_ev = select((int)max_fd + 1, &read_set, &write_set, &err_set, &tv);\n  now = mg_time();\n#if 0\n  DBG((\"select @ %ld num_ev=%d of %d, timeout=%d\", (long) now, num_ev, num_fds,\n       timeout_ms));\n#endif\n\n#if MG_ENABLE_BROADCAST\n  if (num_ev > 0 && mgr->ctl[1] != INVALID_SOCKET &&\n      FD_ISSET(mgr->ctl[1], &read_set))\n  {\n    mg_mgr_handle_ctl_sock(mgr);\n  }\n#endif\n\n#if MG_ENABLE_MUTITHREADS\n  if (num_ev > 0 && mgr->mthread_ctl[0] != INVALID_SOCKET &&\n      FD_ISSET(mgr->mthread_ctl[0], &read_set))\n  {\n    mg_mgr_handle_mthread_ctl_sock(mgr);\n  }\n#endif\n\n  for (nc = mgr->active_connections; nc != NULL; nc = tmp)\n  {\n    int fd_flags = 0;\n    if (nc->sock != INVALID_SOCKET)\n    {\n      if (num_ev > 0)\n      {\n        fd_flags = (FD_ISSET(nc->sock, &read_set) &&\n                            (!(nc->flags & MG_F_UDP) || nc->listener == NULL)\n                        ? _MG_F_FD_CAN_READ\n                        : 0) |\n                   (FD_ISSET(nc->sock, &write_set) ? _MG_F_FD_CAN_WRITE : 0) |\n                   (FD_ISSET(nc->sock, &err_set) ? _MG_F_FD_ERROR : 0);\n      }\n#if MG_LWIP\n      /* With LWIP socket emulation layer, we don't get write events */\n      fd_flags |= _MG_F_FD_CAN_WRITE;\n#endif\n    }\n    tmp = nc->next;\n    mg_mgr_handle_conn(nc, fd_flags, now);\n  }\n\n  for (nc = mgr->active_connections; nc != NULL; nc = tmp)\n  {\n    tmp = nc->next;\n    if ((nc->flags & MG_F_CLOSE_IMMEDIATELY) ||\n        (nc->send_mbuf.len == 0 && (nc->flags & MG_F_SEND_AND_CLOSE)))\n    {\n      mg_close_conn(nc);\n    }\n  }\n\n  return (time_t)now;\n}\n\n//#if MG_ENABLE_BROADCAST\nint mg_sockucnair(sock_t sp[2], int sock_type)\n{\n  union socket_address sa;\n  sock_t sock;\n  socklen_t len = sizeof(sa.sin);\n  int ret = 0;\n\n  sock = sp[0] = sp[1] = INVALID_SOCKET;\n\n  (void)memset(&sa, 0, sizeof(sa));\n  sa.sin.sin_family = AF_INET;\n  sa.sin.sin_port = htons(0);\n  sa.sin.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */\n\n  if ((sock = socket(AF_INET, sock_type, 0)) == INVALID_SOCKET)\n  {\n  }\n  else if (bind(sock, &sa.sa, len) != 0)\n  {\n  }\n  else if (sock_type == SOCK_STREAM && listen(sock, 1) != 0)\n  {\n  }\n  else if (getsockname(sock, &sa.sa, &len) != 0)\n  {\n  }\n  else if ((sp[0] = socket(AF_INET, sock_type, 0)) == INVALID_SOCKET)\n  {\n  }\n  else if (connect(sp[0], &sa.sa, len) != 0)\n  {\n  }\n  else if (sock_type == SOCK_DGRAM &&\n           (getsockname(sp[0], &sa.sa, &len) != 0 ||\n            connect(sock, &sa.sa, len) != 0))\n  {\n  }\n  else if ((sp[1] = (sock_type == SOCK_DGRAM ? sock\n                                             : accept(sock, &sa.sa, &len))) ==\n           INVALID_SOCKET)\n  {\n  }\n  else\n  {\n    mg_set_close_on_exec(sp[0]);\n    mg_set_close_on_exec(sp[1]);\n    if (sock_type == SOCK_STREAM)\n      closesocket(sock);\n    ret = 1;\n  }\n\n  if (!ret)\n  {\n    if (sp[0] != INVALID_SOCKET)\n      closesocket(sp[0]);\n    if (sp[1] != INVALID_SOCKET)\n      closesocket(sp[1]);\n    if (sock != INVALID_SOCKET)\n      closesocket(sock);\n    sock = sp[0] = sp[1] = INVALID_SOCKET;\n  }\n\n  return ret;\n}\n\n//#endif /* MG_ENABLE_BROADCAST */\n\nstatic void mg_sock_get_addr(sock_t sock, int remote,\n                             union socket_address *sa)\n{\n  socklen_t slen = sizeof(*sa);\n  memset(sa, 0, slen);\n  if (remote)\n  {\n    getpeername(sock, &sa->sa, &slen);\n  }\n  else\n  {\n    getsockname(sock, &sa->sa, &slen);\n  }\n}\n\nvoid mg_sock_to_str(sock_t sock, char *buf, size_t len, int flags)\n{\n  union socket_address sa;\n  mg_sock_get_addr(sock, flags & MG_SOCK_STRINGIFY_REMOTE, &sa);\n  mg_sock_addr_to_str(&sa, buf, len, flags);\n}\n\nvoid mg_socket_if_get_conn_addr(struct mg_connection *nc, int remote,\n                                union socket_address *sa)\n{\n  mg_sock_get_addr(nc->sock, remote, sa);\n}\n\n/* clang-format off */\n#define MG_SOCKET_IFACE_VTABLE                                          \\\n  {                                                                     \\\n    mg_socket_if_init,                                                  \\\n    mg_socket_if_free,                                                  \\\n    mg_socket_if_add_conn,                                              \\\n    mg_socket_if_remove_conn,                                           \\\n    mg_socket_if_poll,                                                  \\\n    mg_socket_if_listen_tcp,                                            \\\n    mg_socket_if_listen_udp,                                            \\\n    mg_socket_if_connect_tcp,                                           \\\n    mg_socket_if_connect_udp,                                           \\\n    mg_socket_if_tcp_send,                                              \\\n    mg_socket_if_udp_send,                                              \\\n    mg_socket_if_recved,                                                \\\n    mg_socket_if_create_conn,                                           \\\n    mg_socket_if_destroy_conn,                                          \\\n    mg_socket_if_sock_set,                                              \\\n    mg_socket_if_get_conn_addr,                                         \\\n  }\n/* clang-format on */\n\nstruct mg_iface_vtable mg_socket_iface_vtable = MG_SOCKET_IFACE_VTABLE;\n#if MG_NET_IF == MG_NET_IF_SOCKET\nstruct mg_iface_vtable mg_default_iface_vtable = MG_SOCKET_IFACE_VTABLE;\n#endif\n\n#endif /* MG_ENABLE_NET_IF_SOCKET */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/net_if_tun.c\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#if MG_ENABLE_TUN\n\n/* Amalgamated: #include \"common/cs_dbg.h\" */\n/* Amalgamated: #include \"common/cs_time.h\" */\n/* Amalgamated: #include \"mongoose/src/internal.h\" */\n/* Amalgamated: #include \"mongoose/src/net_if_tun.h\" */\n/* Amalgamated: #include \"mongoose/src/tun.h\" */\n/* Amalgamated: #include \"mongoose/src/util.h\" */\n\n#define MG_TCP_RECV_BUFFER_SIZE 1024\n#define MG_UDP_RECV_BUFFER_SIZE 1500\n\nvoid mg_tun_if_connect_tcp(struct mg_connection *nc,\n                           const union socket_address *sa)\n{\n  (void)nc;\n  (void)sa;\n}\n\nvoid mg_tun_if_connect_udp(struct mg_connection *nc)\n{\n  (void)nc;\n}\n\nint mg_tun_if_listen_tcp(struct mg_connection *nc, union socket_address *sa)\n{\n  (void)nc;\n  (void)sa;\n  return 0;\n}\n\nint mg_tun_if_listen_udp(struct mg_connection *nc, union socket_address *sa)\n{\n  (void)nc;\n  (void)sa;\n  return -1;\n}\n\nvoid mg_tun_if_tcp_send(struct mg_connection *nc, const void *buf, size_t len)\n{\n  struct mg_tun_client *client = (struct mg_tun_client *)nc->iface->data;\n  uint32_t stream_id = (uint32_t)(uintptr_t)nc->mgr_data;\n  struct mg_str msg = {(char *)buf, len};\n#if MG_ENABLE_HEXDUMP\n  char hex[512];\n  mg_hexdump(buf, len, hex, sizeof(hex));\n  LOG(LL_DEBUG, (\"sending to stream %zu:\\n%s\", stream_id, hex));\n#endif\n\n  mg_tun_send_frame(client->disp, stream_id, MG_TUN_DATA_FRAME, 0, msg);\n}\n\nvoid mg_tun_if_udp_send(struct mg_connection *nc, const void *buf, size_t len)\n{\n  (void)nc;\n  (void)buf;\n  (void)len;\n}\n\nvoid mg_tun_if_recved(struct mg_connection *nc, size_t len)\n{\n  (void)nc;\n  (void)len;\n}\n\nint mg_tun_if_create_conn(struct mg_connection *nc)\n{\n  (void)nc;\n  return 1;\n}\n\nvoid mg_tun_if_destroy_conn(struct mg_connection *nc)\n{\n  struct mg_tun_client *client = (struct mg_tun_client *)nc->iface->data;\n\n  if (nc->flags & MG_F_LISTENING)\n  {\n    mg_tun_destroy_client(client);\n  }\n  else if (client->disp)\n  {\n    uint32_t stream_id = (uint32_t)(uintptr_t)nc->mgr_data;\n    struct mg_str msg = {NULL, 0};\n\n    LOG(LL_DEBUG, (\"closing %zu:\", stream_id));\n    mg_tun_send_frame(client->disp, stream_id, MG_TUN_DATA_FRAME,\n                      MG_TUN_F_END_STREAM, msg);\n  }\n}\n\n/* Associate a socket to a connection. */\nvoid mg_tun_if_sock_set(struct mg_connection *nc, sock_t sock)\n{\n  (void)nc;\n  (void)sock;\n}\n\nvoid mg_tun_if_init(struct mg_iface *iface)\n{\n  (void)iface;\n}\n\nvoid mg_tun_if_free(struct mg_iface *iface)\n{\n  (void)iface;\n}\n\nvoid mg_tun_if_add_conn(struct mg_connection *nc)\n{\n  nc->sock = INVALID_SOCKET;\n}\n\nvoid mg_tun_if_remove_conn(struct mg_connection *nc)\n{\n  (void)nc;\n}\n\ntime_t mg_tun_if_poll(struct mg_iface *iface, int timeout_ms)\n{\n  (void)iface;\n  (void)timeout_ms;\n  return (time_t)cs_time();\n}\n\nvoid mg_tun_if_get_conn_addr(struct mg_connection *nc, int remote,\n                             union socket_address *sa)\n{\n  (void)nc;\n  (void)remote;\n  (void)sa;\n}\n\nstruct mg_connection *mg_tun_if_find_conn(struct mg_tun_client *client,\n                                          uint32_t stream_id)\n{\n  struct mg_connection *nc = NULL;\n\n  for (nc = client->mgr->active_connections; nc != NULL; nc = nc->next)\n  {\n    if (nc->iface != client->iface || (nc->flags & MG_F_LISTENING))\n    {\n      continue;\n    }\n    if (stream_id == (uint32_t)(uintptr_t)nc->mgr_data)\n    {\n      return nc;\n    }\n  }\n\n  if (stream_id > client->last_stream_id)\n  {\n    /* create a new connection */\n    LOG(LL_DEBUG, (\"new stream 0x%lx, accepting\", stream_id));\n    nc = mg_if_accept_new_conn(client->listener);\n    nc->mgr_data = (void *)(uintptr_t)stream_id;\n    client->last_stream_id = stream_id;\n  }\n  else\n  {\n    LOG(LL_DEBUG, (\"Ignoring stream 0x%lx (last_stream_id 0x%lx)\", stream_id,\n                   client->last_stream_id));\n  }\n\n  return nc;\n}\n\n/* clang-format off */\n#define MG_TUN_IFACE_VTABLE                                             \\\n  {                                                                     \\\n    mg_tun_if_init,                                                     \\\n    mg_tun_if_free,                                                     \\\n    mg_tun_if_add_conn,                                                 \\\n    mg_tun_if_remove_conn,                                              \\\n    mg_tun_if_poll,                                                     \\\n    mg_tun_if_listen_tcp,                                               \\\n    mg_tun_if_listen_udp,                                               \\\n    mg_tun_if_connect_tcp,                                              \\\n    mg_tun_if_connect_udp,                                              \\\n    mg_tun_if_tcp_send,                                                 \\\n    mg_tun_if_udp_send,                                                 \\\n    mg_tun_if_recved,                                                   \\\n    mg_tun_if_create_conn,                                              \\\n    mg_tun_if_destroy_conn,                                             \\\n    mg_tun_if_sock_set,                                                 \\\n    mg_tun_if_get_conn_addr,                                            \\\n  }\n/* clang-format on */\n\nstruct mg_iface_vtable mg_tun_iface_vtable = MG_TUN_IFACE_VTABLE;\n\n#endif /* MG_ENABLE_TUN */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/ssl_if_openssl.c\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#if MG_ENABLE_SSL && MG_SSL_IF == MG_SSL_IF_OPENSSL\n\n#ifdef __APPLE__\n#pragma GCC diagnostic ignored \"-Wdeprecated-declarations\"\n#endif\n\n#include <openssl/ssl.h>\n\nstruct mg_ssl_if_ctx\n{\n  SSL *ssl;\n  SSL_CTX *ssl_ctx;\n};\n\nvoid mg_ssl_if_init()\n{\n  SSL_library_init();\n}\n\nenum mg_ssl_if_result mg_ssl_if_conn_accept(struct mg_connection *nc,\n                                            struct mg_connection *lc)\n{\n  struct mg_ssl_if_ctx *ctx =\n      (struct mg_ssl_if_ctx *)MG_CALLOC(1, sizeof(*ctx));\n  struct mg_ssl_if_ctx *lc_ctx = (struct mg_ssl_if_ctx *)lc->ssl_if_data;\n  nc->ssl_if_data = ctx;\n  if (ctx == NULL || lc_ctx == NULL)\n    return MG_SSL_ERROR;\n  ctx->ssl_ctx = lc_ctx->ssl_ctx;\n  if ((ctx->ssl = SSL_new(ctx->ssl_ctx)) == NULL)\n  {\n    return MG_SSL_ERROR;\n  }\n  return MG_SSL_OK;\n}\n\nstatic enum mg_ssl_if_result mg_use_cert(SSL_CTX *ctx, const char *cert,\n                                         const char *key, const char **err_msg);\nstatic enum mg_ssl_if_result mg_use_ca_cert(SSL_CTX *ctx, const char *cert);\nstatic enum mg_ssl_if_result mg_set_cipher_list(SSL_CTX *ctx);\n\nenum mg_ssl_if_result mg_ssl_if_conn_init(\n    struct mg_connection *nc, const struct mg_ssl_if_conn_params *params,\n    const char **err_msg)\n{\n  struct mg_ssl_if_ctx *ctx =\n      (struct mg_ssl_if_ctx *)MG_CALLOC(1, sizeof(*ctx));\n  DBG((\"%p %s,%s,%s\", nc, (params->cert ? params->cert : \"\"),\n       (params->key ? params->key : \"\"),\n       (params->ca_cert ? params->ca_cert : \"\")));\n  if (ctx == NULL)\n  {\n    MG_SET_PTRPTR(err_msg, \"Out of memory\");\n    return MG_SSL_ERROR;\n  }\n  nc->ssl_if_data = ctx;\n  if (nc->flags & MG_F_LISTENING)\n  {\n    ctx->ssl_ctx = SSL_CTX_new(SSLv23_server_method());\n  }\n  else\n  {\n    ctx->ssl_ctx = SSL_CTX_new(SSLv23_client_method());\n  }\n  if (ctx->ssl_ctx == NULL)\n  {\n    MG_SET_PTRPTR(err_msg, \"Failed to create SSL context\");\n    return MG_SSL_ERROR;\n  }\n\n  if (params->cert != NULL &&\n      mg_use_cert(ctx->ssl_ctx, params->cert, params->key, err_msg) !=\n          MG_SSL_OK)\n  {\n    return MG_SSL_ERROR;\n  }\n\n  if (params->ca_cert != NULL &&\n      mg_use_ca_cert(ctx->ssl_ctx, params->ca_cert) != MG_SSL_OK)\n  {\n    MG_SET_PTRPTR(err_msg, \"Invalid SSL CA cert\");\n    return MG_SSL_ERROR;\n  }\n\n  if (params->server_name != NULL)\n  {\n#ifdef KR_VERSION\n    SSL_CTX_kr_set_verify_name(ctx->ssl_ctx, params->server_name);\n#else\n/* TODO(rojer): Implement server name verification on OpenSSL. */\n#endif\n  }\n\n  mg_set_cipher_list(ctx->ssl_ctx);\n\n  if (!(nc->flags & MG_F_LISTENING) &&\n      (ctx->ssl = SSL_new(ctx->ssl_ctx)) == NULL)\n  {\n    MG_SET_PTRPTR(err_msg, \"Failed to create SSL session\");\n    return MG_SSL_ERROR;\n  }\n\n  nc->flags |= MG_F_SSL;\n\n  return MG_SSL_OK;\n}\n\nstatic enum mg_ssl_if_result mg_ssl_if_ssl_err(struct mg_connection *nc,\n                                               int res)\n{\n  struct mg_ssl_if_ctx *ctx = (struct mg_ssl_if_ctx *)nc->ssl_if_data;\n  int err = SSL_get_error(ctx->ssl, res);\n  if (err == SSL_ERROR_WANT_READ)\n    return MG_SSL_WANT_READ;\n  if (err == SSL_ERROR_WANT_WRITE)\n    return MG_SSL_WANT_WRITE;\n  DBG((\"%p %p SSL error: %d %d\", nc, ctx->ssl_ctx, res, err));\n  nc->err = err;\n  return MG_SSL_ERROR;\n}\n\nenum mg_ssl_if_result mg_ssl_if_handshake(struct mg_connection *nc)\n{\n  struct mg_ssl_if_ctx *ctx = (struct mg_ssl_if_ctx *)nc->ssl_if_data;\n  int server_side = (nc->listener != NULL);\n  int res;\n  /* If descriptor is not yet set, do it now. */\n  if (SSL_get_fd(ctx->ssl) < 0)\n  {\n    if (SSL_set_fd(ctx->ssl, nc->sock) != 1)\n      return MG_SSL_ERROR;\n  }\n  res = server_side ? SSL_accept(ctx->ssl) : SSL_connect(ctx->ssl);\n  if (res != 1)\n    return mg_ssl_if_ssl_err(nc, res);\n  return MG_SSL_OK;\n}\n\nint mg_ssl_if_read(struct mg_connection *nc, void *buf, size_t buf_size)\n{\n  struct mg_ssl_if_ctx *ctx = (struct mg_ssl_if_ctx *)nc->ssl_if_data;\n  int n = SSL_read(ctx->ssl, buf, buf_size);\n  DBG((\"%p %d -> %d\", nc, (int)buf_size, n));\n  if (n < 0)\n    return mg_ssl_if_ssl_err(nc, n);\n  if (n == 0)\n    nc->flags |= MG_F_CLOSE_IMMEDIATELY;\n  return n;\n}\n\nint mg_ssl_if_write(struct mg_connection *nc, const void *data, size_t len)\n{\n  struct mg_ssl_if_ctx *ctx = (struct mg_ssl_if_ctx *)nc->ssl_if_data;\n  int n = SSL_write(ctx->ssl, data, len);\n  DBG((\"%p %d -> %d\", nc, (int)len, n));\n  if (n <= 0)\n    return mg_ssl_if_ssl_err(nc, n);\n  return n;\n}\n\nvoid mg_ssl_if_conn_free(struct mg_connection *nc)\n{\n  struct mg_ssl_if_ctx *ctx = (struct mg_ssl_if_ctx *)nc->ssl_if_data;\n  if (ctx == NULL)\n    return;\n  nc->ssl_if_data = NULL;\n  if (ctx->ssl != NULL)\n    SSL_free(ctx->ssl);\n  if (ctx->ssl_ctx != NULL && nc->listener == NULL)\n    SSL_CTX_free(ctx->ssl_ctx);\n  memset(ctx, 0, sizeof(*ctx));\n  MG_FREE(ctx);\n}\n\n/*\n * Cipher suite options used for TLS negotiation.\n * https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_configurations\n */\nstatic const char mg_s_cipher_list[] =\n#if defined(MG_SSL_CRYPTO_MODERN)\n    \"ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:\"\n    \"ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:\"\n    \"DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:\"\n    \"ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:\"\n    \"ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:\"\n    \"ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:\"\n    \"DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:\"\n    \"DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:\"\n    \"!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK\"\n#elif defined(MG_SSL_CRYPTO_OLD)\n    \"ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:\"\n    \"ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:\"\n    \"DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:\"\n    \"ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:\"\n    \"ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:\"\n    \"ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:\"\n    \"DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:\"\n    \"DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:\"\n    \"ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:\"\n    \"AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:\"\n    \"HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:\"\n    \"!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA\"\n#else /* Default - intermediate. */\n    \"ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:\"\n    \"ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:\"\n    \"DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:\"\n    \"ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:\"\n    \"ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:\"\n    \"ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:\"\n    \"DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:\"\n    \"DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:\"\n    \"AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:\"\n    \"DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:\"\n    \"!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA\"\n#endif\n    ;\n\n/*\n * Default DH params for PFS cipher negotiation. This is a 2048-bit group.\n * Will be used if none are provided by the user in the certificate file.\n */\n#if !MG_DISABLE_PFS && !defined(KR_VERSION)\nstatic const char mg_s_default_dh_params[] =\n    \"\\\n-----BEGIN DH PARAMETERS-----\\n\\\nMIIBCAKCAQEAlvbgD/qh9znWIlGFcV0zdltD7rq8FeShIqIhkQ0C7hYFThrBvF2E\\n\\\nZ9bmgaP+sfQwGpVlv9mtaWjvERbu6mEG7JTkgmVUJrUt/wiRzwTaCXBqZkdUO8Tq\\n\\\n+E6VOEQAilstG90ikN1Tfo+K6+X68XkRUIlgawBTKuvKVwBhuvlqTGerOtnXWnrt\\n\\\nym//hd3cd5PBYGBix0i7oR4xdghvfR2WLVu0LgdThTBb6XP7gLd19cQ1JuBtAajZ\\n\\\nwMuPn7qlUkEFDIkAZy59/Hue/H2Q2vU/JsvVhHWCQBL4F1ofEAt50il6ZxR1QfFK\\n\\\n9VGKDC4oOgm9DlxwwBoC2FjqmvQlqVV3kwIBAg==\\n\\\n-----END DH PARAMETERS-----\\n\";\n#endif\n\nstatic enum mg_ssl_if_result mg_use_ca_cert(SSL_CTX *ctx, const char *cert)\n{\n  if (cert == NULL || strcmp(cert, \"*\") == 0)\n  {\n    return MG_SSL_OK;\n  }\n  SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);\n  return SSL_CTX_load_verify_locations(ctx, cert, NULL) == 1 ? MG_SSL_OK\n                                                             : MG_SSL_ERROR;\n}\n\nstatic enum mg_ssl_if_result mg_use_cert(SSL_CTX *ctx, const char *cert,\n                                         const char *key,\n                                         const char **err_msg)\n{\n  if (key == NULL)\n    key = cert;\n  if (cert == NULL || cert[0] == '\\0' || key == NULL || key[0] == '\\0')\n  {\n    return MG_SSL_OK;\n  }\n  else if (SSL_CTX_use_certificate_file(ctx, cert, 1) == 0)\n  {\n    MG_SET_PTRPTR(err_msg, \"Invalid SSL cert\");\n    return MG_SSL_ERROR;\n  }\n  else if (SSL_CTX_use_PrivateKey_file(ctx, key, 1) == 0)\n  {\n    MG_SET_PTRPTR(err_msg, \"Invalid SSL key\");\n    return MG_SSL_ERROR;\n  }\n  else if (SSL_CTX_use_certificate_chain_file(ctx, cert) == 0)\n  {\n    MG_SET_PTRPTR(err_msg, \"Invalid CA bundle\");\n    return MG_SSL_ERROR;\n  }\n  else\n  {\n    SSL_CTX_set_mode(ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);\n#if !MG_DISABLE_PFS && !defined(KR_VERSION)\n    BIO *bio = NULL;\n    DH *dh = NULL;\n\n    /* Try to read DH parameters from the cert/key file. */\n    bio = BIO_new_file(cert, \"r\");\n    if (bio != NULL)\n    {\n      dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);\n      BIO_free(bio);\n    }\n    /*\n     * If there are no DH params in the file, fall back to hard-coded ones.\n     * Not ideal, but better than nothing.\n     */\n    if (dh == NULL)\n    {\n      bio = BIO_new_mem_buf((void *)mg_s_default_dh_params, -1);\n      dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);\n      BIO_free(bio);\n    }\n    if (dh != NULL)\n    {\n      SSL_CTX_set_tmp_dh(ctx, dh);\n      SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);\n      DH_free(dh);\n    }\n#if OPENSSL_VERSION_NUMBER > 0x10002000L\n    SSL_CTX_set_ecdh_auto(ctx, 1);\n#endif\n#endif\n  }\n  return MG_SSL_OK;\n}\n\nstatic enum mg_ssl_if_result mg_set_cipher_list(SSL_CTX *ctx)\n{\n  return (SSL_CTX_set_cipher_list(ctx, mg_s_cipher_list) == 1 ? MG_SSL_OK\n                                                              : MG_SSL_ERROR);\n}\n\nconst char *mg_set_ssl(struct mg_connection *nc, const char *cert,\n                       const char *ca_cert)\n{\n  const char *err_msg = NULL;\n  struct mg_ssl_if_conn_params params;\n  memset(&params, 0, sizeof(params));\n  params.cert = cert;\n  params.ca_cert = ca_cert;\n  if (mg_ssl_if_conn_init(nc, &params, &err_msg) != MG_SSL_OK)\n  {\n    return err_msg;\n  }\n  return NULL;\n}\n\n#endif /* MG_ENABLE_SSL && MG_SSL_IF == MG_SSL_IF_OPENSSL */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/ssl_if_mbedtls.c\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#if MG_ENABLE_SSL && MG_SSL_IF == MG_SSL_IF_MBEDTLS\n\n#include <mbedtls/debug.h>\n#include <mbedtls/ecp.h>\n#include <mbedtls/ssl.h>\n#include <mbedtls/x509_crt.h>\n\nstatic void mg_ssl_mbed_log(void *ctx, int level, const char *file, int line,\n                            const char *str)\n{\n  enum cs_log_level cs_level;\n  switch (level)\n  {\n  case 1:\n    cs_level = LL_ERROR;\n    break;\n  case 2:\n  case 3:\n    cs_level = LL_DEBUG;\n    break;\n  default:\n    cs_level = LL_VERBOSE_DEBUG;\n  }\n  /* mbedTLS passes strings with \\n at the end, strip it. */\n  LOG(cs_level, (\"%p %.*s\", ctx, (int)(strlen(str) - 1), str));\n  (void)file;\n  (void)line;\n}\n\nstruct mg_ssl_if_ctx\n{\n  mbedtls_ssl_config *conf;\n  mbedtls_ssl_context *ssl;\n  mbedtls_x509_crt *cert;\n  mbedtls_pk_context *key;\n  mbedtls_x509_crt *ca_cert;\n};\n\n/* Must be provided by the platform. ctx is struct mg_connection. */\nextern int mg_ssl_if_mbed_random(void *ctx, unsigned char *buf, size_t len);\n\nvoid mg_ssl_if_init()\n{\n}\n\nenum mg_ssl_if_result mg_ssl_if_conn_accept(struct mg_connection *nc,\n                                            struct mg_connection *lc)\n{\n  struct mg_ssl_if_ctx *ctx =\n      (struct mg_ssl_if_ctx *)MG_CALLOC(1, sizeof(*ctx));\n  struct mg_ssl_if_ctx *lc_ctx = (struct mg_ssl_if_ctx *)lc->ssl_if_data;\n  nc->ssl_if_data = ctx;\n  if (ctx == NULL || lc_ctx == NULL)\n    return MG_SSL_ERROR;\n  ctx->ssl = MG_CALLOC(1, sizeof(*ctx->ssl));\n  if (mbedtls_ssl_setup(ctx->ssl, lc_ctx->conf) != 0)\n  {\n    return MG_SSL_ERROR;\n  }\n  return MG_SSL_OK;\n}\n\nstatic enum mg_ssl_if_result mg_use_cert(struct mg_ssl_if_ctx *ctx,\n                                         const char *cert, const char *key,\n                                         const char **err_msg);\nstatic enum mg_ssl_if_result mg_use_ca_cert(struct mg_ssl_if_ctx *ctx,\n                                            const char *cert);\nstatic enum mg_ssl_if_result mg_set_cipher_list(struct mg_ssl_if_ctx *ctx,\n                                                const char *ciphers);\n\nenum mg_ssl_if_result mg_ssl_if_conn_init(\n    struct mg_connection *nc, const struct mg_ssl_if_conn_params *params,\n    const char **err_msg)\n{\n  struct mg_ssl_if_ctx *ctx =\n      (struct mg_ssl_if_ctx *)MG_CALLOC(1, sizeof(*ctx));\n  DBG((\"%p %s,%s,%s\", nc, (params->cert ? params->cert : \"\"),\n       (params->key ? params->key : \"\"),\n       (params->ca_cert ? params->ca_cert : \"\")));\n\n  if (ctx == NULL)\n  {\n    MG_SET_PTRPTR(err_msg, \"Out of memory\");\n    return MG_SSL_ERROR;\n  }\n  nc->ssl_if_data = ctx;\n  ctx->conf = MG_CALLOC(1, sizeof(*ctx->conf));\n  mbedtls_ssl_config_init(ctx->conf);\n  mbedtls_ssl_conf_dbg(ctx->conf, mg_ssl_mbed_log, nc);\n  if (mbedtls_ssl_config_defaults(\n          ctx->conf, (nc->flags & MG_F_LISTENING ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT),\n          MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT) != 0)\n  {\n    MG_SET_PTRPTR(err_msg, \"Failed to init SSL config\");\n    return MG_SSL_ERROR;\n  }\n  /* TLS 1.2 and up */\n  mbedtls_ssl_conf_min_version(ctx->conf, MBEDTLS_SSL_MAJOR_VERSION_3,\n                               MBEDTLS_SSL_MINOR_VERSION_3);\n  mbedtls_ssl_conf_rng(ctx->conf, mg_ssl_if_mbed_random, nc);\n\n  if (params->cert != NULL &&\n      mg_use_cert(ctx, params->cert, params->key, err_msg) != MG_SSL_OK)\n  {\n    return MG_SSL_ERROR;\n  }\n\n  if (params->ca_cert != NULL &&\n      mg_use_ca_cert(ctx, params->ca_cert) != MG_SSL_OK)\n  {\n    MG_SET_PTRPTR(err_msg, \"Invalid SSL CA cert\");\n    return MG_SSL_ERROR;\n  }\n\n  if (params->server_name != NULL)\n  {\n    /* TODO(rojer): Implement server name verification on mbedTLS. */\n  }\n\n  mg_set_cipher_list(ctx, NULL);\n\n  if (!(nc->flags & MG_F_LISTENING))\n  {\n    ctx->ssl = MG_CALLOC(1, sizeof(*ctx->ssl));\n    mbedtls_ssl_init(ctx->ssl);\n    if (mbedtls_ssl_setup(ctx->ssl, ctx->conf) != 0)\n    {\n      MG_SET_PTRPTR(err_msg, \"Failed to create SSL session\");\n      return MG_SSL_ERROR;\n    }\n  }\n\n  nc->flags |= MG_F_SSL;\n\n  return MG_SSL_OK;\n}\n\n#if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL\nint ssl_socket_send(void *ctx, const unsigned char *buf, size_t len);\nint ssl_socket_recv(void *ctx, unsigned char *buf, size_t len);\n#else\nstatic int ssl_socket_send(void *ctx, const unsigned char *buf, size_t len)\n{\n  struct mg_connection *nc = (struct mg_connection *)ctx;\n  int n = (int)MG_SEND_FUNC(nc->sock, buf, len, 0);\n  DBG((\"%p %d -> %d\", nc, (int)len, n));\n  if (n >= 0)\n    return n;\n  n = mg_get_errno();\n  return ((n == EAGAIN || n == EINPROGRESS) ? MBEDTLS_ERR_SSL_WANT_WRITE : -1);\n}\n\nstatic int ssl_socket_recv(void *ctx, unsigned char *buf, size_t len)\n{\n  struct mg_connection *nc = (struct mg_connection *)ctx;\n  int n = (int)MG_RECV_FUNC(nc->sock, buf, len, 0);\n  DBG((\"%p %d <- %d\", nc, (int)len, n));\n  if (n >= 0)\n    return n;\n  n = mg_get_errno();\n  return ((n == EAGAIN || n == EINPROGRESS) ? MBEDTLS_ERR_SSL_WANT_READ : -1);\n}\n#endif\n\nstatic enum mg_ssl_if_result mg_ssl_if_mbed_err(struct mg_connection *nc,\n                                                int ret)\n{\n  if (ret == MBEDTLS_ERR_SSL_WANT_READ)\n    return MG_SSL_WANT_READ;\n  if (ret == MBEDTLS_ERR_SSL_WANT_WRITE)\n    return MG_SSL_WANT_WRITE;\n  if (ret !=\n      MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)\n  { /* CLOSE_NOTIFY = Normal shutdown */\n    LOG(LL_ERROR, (\"%p SSL error: %d\", nc, ret));\n  }\n  nc->err = ret;\n  nc->flags |= MG_F_CLOSE_IMMEDIATELY;\n  return MG_SSL_ERROR;\n}\n\nenum mg_ssl_if_result mg_ssl_if_handshake(struct mg_connection *nc)\n{\n  struct mg_ssl_if_ctx *ctx = (struct mg_ssl_if_ctx *)nc->ssl_if_data;\n  int err;\n  /* If bio is not yet set, do it now. */\n  if (ctx->ssl->p_bio == NULL)\n  {\n    mbedtls_ssl_set_bio(ctx->ssl, nc, ssl_socket_send, ssl_socket_recv, NULL);\n  }\n  err = mbedtls_ssl_handshake(ctx->ssl);\n  if (err != 0)\n    return mg_ssl_if_mbed_err(nc, err);\n  return MG_SSL_OK;\n}\n\nint mg_ssl_if_read(struct mg_connection *nc, void *buf, size_t buf_size)\n{\n  struct mg_ssl_if_ctx *ctx = (struct mg_ssl_if_ctx *)nc->ssl_if_data;\n  int n = mbedtls_ssl_read(ctx->ssl, buf, buf_size);\n  DBG((\"%p %d -> %d\", nc, (int)buf_size, n));\n  if (n < 0)\n    return mg_ssl_if_mbed_err(nc, n);\n  if (n == 0)\n    nc->flags |= MG_F_CLOSE_IMMEDIATELY;\n  return n;\n}\n\nint mg_ssl_if_write(struct mg_connection *nc, const void *data, size_t len)\n{\n  struct mg_ssl_if_ctx *ctx = (struct mg_ssl_if_ctx *)nc->ssl_if_data;\n  int n = mbedtls_ssl_write(ctx->ssl, data, len);\n  DBG((\"%p %d -> %d\", nc, (int)len, n));\n  if (n < 0)\n    return mg_ssl_if_mbed_err(nc, n);\n  return n;\n}\n\nvoid mg_ssl_if_conn_free(struct mg_connection *nc)\n{\n  struct mg_ssl_if_ctx *ctx = (struct mg_ssl_if_ctx *)nc->ssl_if_data;\n  if (ctx == NULL)\n    return;\n  nc->ssl_if_data = NULL;\n  if (ctx->ssl != NULL)\n  {\n    mbedtls_ssl_free(ctx->ssl);\n    MG_FREE(ctx->ssl);\n  }\n  if (ctx->conf != NULL)\n  {\n    mbedtls_ssl_config_free(ctx->conf);\n    MG_FREE(ctx->conf);\n  }\n  if (ctx->ca_cert != NULL)\n  {\n    mbedtls_x509_crt_free(ctx->ca_cert);\n    MG_FREE(ctx->ca_cert);\n  }\n  if (ctx->cert != NULL)\n  {\n    mbedtls_x509_crt_free(ctx->cert);\n    MG_FREE(ctx->cert);\n  }\n  if (ctx->key != NULL)\n  {\n    mbedtls_pk_free(ctx->key);\n    MG_FREE(ctx->key);\n  }\n  memset(ctx, 0, sizeof(*ctx));\n  MG_FREE(ctx);\n}\n\nstatic enum mg_ssl_if_result mg_use_ca_cert(struct mg_ssl_if_ctx *ctx,\n                                            const char *ca_cert)\n{\n  if (ca_cert == NULL || strcmp(ca_cert, \"*\") == 0)\n  {\n    return MG_SSL_OK;\n  }\n  ctx->ca_cert = MG_CALLOC(1, sizeof(*ctx->ca_cert));\n  mbedtls_x509_crt_init(ctx->ca_cert);\n  if (mbedtls_x509_crt_parse_file(ctx->ca_cert, ca_cert) != 0)\n  {\n    return MG_SSL_ERROR;\n  }\n  mbedtls_ssl_conf_ca_chain(ctx->conf, ctx->ca_cert, NULL);\n  mbedtls_ssl_conf_authmode(ctx->conf, MBEDTLS_SSL_VERIFY_REQUIRED);\n  return MG_SSL_OK;\n}\n\nstatic enum mg_ssl_if_result mg_use_cert(struct mg_ssl_if_ctx *ctx,\n                                         const char *cert, const char *key,\n                                         const char **err_msg)\n{\n  if (key == NULL)\n    key = cert;\n  if (cert == NULL || cert[0] == '\\0' || key == NULL || key[0] == '\\0')\n  {\n    return MG_SSL_OK;\n  }\n  ctx->cert = MG_CALLOC(1, sizeof(*ctx->cert));\n  mbedtls_x509_crt_init(ctx->cert);\n  ctx->key = MG_CALLOC(1, sizeof(*ctx->key));\n  mbedtls_pk_init(ctx->key);\n  if (mbedtls_x509_crt_parse_file(ctx->cert, cert) != 0)\n  {\n    MG_SET_PTRPTR(err_msg, \"Invalid SSL cert\");\n    return MG_SSL_ERROR;\n  }\n  if (mbedtls_pk_parse_keyfile(ctx->key, key, NULL) != 0)\n  {\n    MG_SET_PTRPTR(err_msg, \"Invalid SSL key\");\n    return MG_SSL_ERROR;\n  }\n  if (mbedtls_ssl_conf_own_cert(ctx->conf, ctx->cert, ctx->key) != 0)\n  {\n    MG_SET_PTRPTR(err_msg, \"Invalid SSL key or cert\");\n    return MG_SSL_ERROR;\n  }\n  return MG_SSL_OK;\n}\n\nstatic const int mg_s_cipher_list[] = {\n    MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,\n    MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,\n    MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,\n    MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,\n    MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,\n    MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,\n    MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,\n    MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,\n    MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,\n    MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,\n    MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256,\n    MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256,\n    MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, 0};\n\n/*\n * Ciphers can be specified as a colon-separated list of cipher suite names.\n * These can be found in\n * https://github.com/ARMmbed/mbedtls/blob/development/library/ssl_ciphersuites.c#L267\n * E.g.: TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-256-CCM\n */\nstatic enum mg_ssl_if_result mg_set_cipher_list(struct mg_ssl_if_ctx *ctx,\n                                                const char *ciphers)\n{\n  if (ciphers != NULL)\n  {\n    int ids[50], n = 0, l, id;\n    const char *s = ciphers;\n    char *e, tmp[50];\n    while (s != NULL && n < (int)(sizeof(ids) / sizeof(ids[0])) - 1)\n    {\n      e = strchr(s, ':');\n      l = (e != NULL ? (e - s) : (int)strlen(s));\n      strncpy(tmp, s, l);\n      id = mbedtls_ssl_get_ciphersuite_id(tmp);\n      DBG((\"%s -> %d\", tmp, id));\n      if (id != 0)\n        ids[n++] = id;\n      s = (e != NULL ? e + 1 : NULL);\n    }\n    if (n == 0)\n      return MG_SSL_ERROR;\n    ids[n] = 0;\n    mbedtls_ssl_conf_ciphersuites(ctx->conf, ids);\n  }\n  else\n  {\n    mbedtls_ssl_conf_ciphersuites(ctx->conf, mg_s_cipher_list);\n  }\n  return MG_SSL_OK;\n}\n\nconst char *mg_set_ssl(struct mg_connection *nc, const char *cert,\n                       const char *ca_cert)\n{\n  const char *err_msg = NULL;\n  struct mg_ssl_if_conn_params params;\n  memset(&params, 0, sizeof(params));\n  params.cert = cert;\n  params.ca_cert = ca_cert;\n  if (mg_ssl_if_conn_init(nc, &params, &err_msg) != MG_SSL_OK)\n  {\n    return err_msg;\n  }\n  return NULL;\n}\n\n/* Lazy RNG. Warning: it would be a bad idea to do this in production! */\n#ifdef MG_SSL_MBED_DUMMY_RANDOM\nint mg_ssl_if_mbed_random(void *ctx, unsigned char *buf, size_t len)\n{\n  (void)ctx;\n  while (len--)\n    *buf++ = rand();\n  return 0;\n}\n#endif\n\n#endif /* MG_ENABLE_SSL && MG_SSL_IF == MG_SSL_IF_MBEDTLS */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/multithreading.c\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n */\n\n/* Amalgamated: #include \"mongoose/src/internal.h\" */\n/* Amalgamated: #include \"mongoose/src/util.h\" */\n\n#if MG_ENABLE_THREADS\n\nstatic void multithreaded_ev_handler(struct mg_connection *c, int ev, void *p);\n\n/*\n * This thread function executes user event handler.\n * It runs an event manager that has only one connection, until that\n * connection is alive.\n */\nstatic void *per_connection_thread_function(void *param)\n{\n  struct mg_connection *c = (struct mg_connection *)param;\n  struct mg_mgr m;\n  /* mgr_data can be used subsequently, store its value */\n  int poll_timeout = (intptr_t)c->mgr_data;\n\n  mg_mgr_init(&m, NULL);\n  mg_add_conn(&m, c);\n  mg_call(c, NULL, MG_EV_ACCEPT, &c->sa);\n\n  while (m.active_connections != NULL)\n  {\n    mg_mgr_poll(&m, poll_timeout ? poll_timeout : 1000);\n  }\n  mg_mgr_free(&m);\n\n  return param;\n}\n\nstatic void link_conns(struct mg_connection *c1, struct mg_connection *c2)\n{\n  c1->priv_2 = c2;\n  c2->priv_2 = c1;\n}\n\nstatic void unlink_conns(struct mg_connection *c)\n{\n  struct mg_connection *peer = (struct mg_connection *)c->priv_2;\n  if (peer != NULL)\n  {\n    peer->flags |= MG_F_SEND_AND_CLOSE;\n    peer->priv_2 = NULL;\n  }\n  c->priv_2 = NULL;\n}\n\nstatic void forwarder_ev_handler(struct mg_connection *c, int ev, void *p)\n{\n  (void)p;\n  if (ev == MG_EV_RECV && c->priv_2)\n  {\n    mg_forward(c, (struct mg_connection *)c->priv_2);\n  }\n  else if (ev == MG_EV_CLOSE)\n  {\n    unlink_conns(c);\n  }\n}\n\nstatic void spawn_handling_thread(struct mg_connection *nc)\n{\n  struct mg_mgr dummy;\n  sock_t sp[2];\n  struct mg_connection *c[2];\n  int poll_timeout;\n  /*\n   * Create a socket pair, and wrap each socket into the connection with\n   * dummy event manager.\n   * c[0] stays in this thread, c[1] goes to another thread.\n   */\n  mg_mgr_init(&dummy, NULL);\n  mg_sockucnair(sp, SOCK_STREAM);\n\n  c[0] = mg_add_sock(&dummy, sp[0], forwarder_ev_handler);\n  c[1] = mg_add_sock(&dummy, sp[1], nc->listener->priv_1.f);\n\n  /* link_conns replaces priv_2, storing its value */\n  poll_timeout = (intptr_t)nc->priv_2;\n\n  /* Interlink client connection with c[0] */\n  link_conns(c[0], nc);\n\n  /*\n   * Switch c[0] manager from the dummy one to the real one. c[1] manager\n   * will be set in another thread, allocated on stack of that thread.\n   */\n  mg_add_conn(nc->mgr, c[0]);\n\n  /*\n   * Dress c[1] as nc.\n   * TODO(lsm): code in accept_conn() looks similar. Refactor.\n   */\n  c[1]->listener = nc->listener;\n  c[1]->proto_handler = nc->proto_handler;\n  c[1]->user_data = nc->user_data;\n  c[1]->sa = nc->sa;\n  c[1]->flags = nc->flags;\n\n  /* priv_2 is used, so, put timeout to mgr_data */\n  c[1]->mgr_data = (void *)(intptr_t)poll_timeout;\n\n  mg_start_thread(per_connection_thread_function, c[1]);\n}\n\nstatic void multithreaded_ev_handler(struct mg_connection *c, int ev, void *p)\n{\n  (void)p;\n  if (ev == MG_EV_ACCEPT)\n  {\n    spawn_handling_thread(c);\n    c->handler = forwarder_ev_handler;\n  }\n}\n\nvoid mg_enable_multithreading_opt(struct mg_connection *nc,\n                                  struct mg_multithreading_opts opts)\n{\n  /* Wrap user event handler into our multithreaded_ev_handler */\n  nc->priv_1.f = nc->handler;\n  /*\n   * We put timeout to `priv_2` member of the main\n   * (listening) connection, mt is not enabled yet,\n   * and this member is not used\n   */\n  nc->priv_2 = (void *)(intptr_t)opts.poll_timeout;\n  nc->handler = multithreaded_ev_handler;\n}\n\nvoid mg_enable_multithreading(struct mg_connection *nc)\n{\n  struct mg_multithreading_opts opts;\n  memset(&opts, 0, sizeof(opts));\n  mg_enable_multithreading_opt(nc, opts);\n}\n\n#endif\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/uri.c\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n */\n\n/* Amalgamated: #include \"mongoose/src/internal.h\" */\n/* Amalgamated: #include \"mongoose/src/uri.h\" */\n\n/*\n * scan string until `sep`, keeping track of component boundaries in `res`.\n *\n * `p` will point to the char after the separator or it will be `end`.\n */\nstatic void parse_uri_component(const char **p, const char *end, char sep,\n                                struct mg_str *res)\n{\n  res->p = *p;\n  for (; *p < end; (*p)++)\n  {\n    if (**p == sep)\n    {\n      break;\n    }\n  }\n  res->len = (*p) - res->p;\n  if (*p < end)\n    (*p)++;\n}\n\nint mg_parse_uri(struct mg_str uri, struct mg_str *scheme,\n                 struct mg_str *user_info, struct mg_str *host,\n                 unsigned int *port, struct mg_str *path, struct mg_str *query,\n                 struct mg_str *fragment)\n{\n  struct mg_str rscheme = {0, 0}, ruser_info = {0, 0}, rhost = {0, 0},\n                rpath = {0, 0}, rquery = {0, 0}, rfragment = {0, 0};\n  unsigned int rport = 0;\n  enum\n  {\n    P_START,\n    P_SCHEME_OR_PORT,\n    P_USER_INFO,\n    P_HOST,\n    P_PORT,\n    P_REST\n  } state = P_START;\n\n  const char *p = uri.p, *end = p + uri.len;\n  while (p < end)\n  {\n    switch (state)\n    {\n    case P_START:\n      /*\n         * expecting on of:\n         * - `scheme://xxxx`\n         * - `xxxx:port`\n         * - `xxxx/path`\n         */\n      for (; p < end; p++)\n      {\n        if (*p == ':')\n        {\n          state = P_SCHEME_OR_PORT;\n          break;\n        }\n        else if (*p == '/')\n        {\n          state = P_REST;\n          break;\n        }\n      }\n      if (state == P_START || state == P_REST)\n      {\n        rhost.p = uri.p;\n        rhost.len = p - uri.p;\n      }\n      break;\n    case P_SCHEME_OR_PORT:\n      if (end - p >= 3 && memcmp(p, \"://\", 3) == 0)\n      {\n        rscheme.p = uri.p;\n        rscheme.len = p - uri.p;\n        state = P_USER_INFO;\n        p += 2; /* point to last separator char */\n      }\n      else\n      {\n        rhost.p = uri.p;\n        rhost.len = p - uri.p;\n        state = P_PORT;\n      }\n      break;\n    case P_USER_INFO:\n      p++;\n      ruser_info.p = p;\n      for (; p < end; p++)\n      {\n        if (*p == '@')\n        {\n          state = P_HOST;\n          break;\n        }\n        else if (*p == '/')\n        {\n          break;\n        }\n      }\n      if (p == end || *p == '/')\n      {\n        /* backtrack and parse as host */\n        state = P_HOST;\n        p = ruser_info.p;\n      }\n      ruser_info.len = p - ruser_info.p;\n      break;\n    case P_HOST:\n      if (*p == '@')\n        p++;\n      rhost.p = p;\n      for (; p < end; p++)\n      {\n        if (*p == ':')\n        {\n          state = P_PORT;\n          break;\n        }\n        else if (*p == '/')\n        {\n          state = P_REST;\n          break;\n        }\n      }\n      rhost.len = p - rhost.p;\n      break;\n    case P_PORT:\n      p++;\n      for (; p < end; p++)\n      {\n        if (*p == '/')\n        {\n          state = P_REST;\n          break;\n        }\n        rport *= 10;\n        rport += *p - '0';\n      }\n      break;\n    case P_REST:\n      /* `p` points to separator. `path` includes the separator */\n      parse_uri_component(&p, end, '?', &rpath);\n      parse_uri_component(&p, end, '#', &rquery);\n      parse_uri_component(&p, end, '\\0', &rfragment);\n      break;\n    }\n  }\n\n  if (scheme != 0)\n    *scheme = rscheme;\n  if (user_info != 0)\n    *user_info = ruser_info;\n  if (host != 0)\n    *host = rhost;\n  if (port != 0)\n    *port = rport;\n  if (path != 0)\n    *path = rpath;\n  if (query != 0)\n    *query = rquery;\n  if (fragment != 0)\n    *fragment = rfragment;\n\n  return 0;\n}\n\n/* Normalize the URI path. Remove/resolve \".\" and \"..\". */\nint mg_normalize_uri_path(const struct mg_str *in, struct mg_str *out)\n{\n  const char *s = in->p, *se = s + in->len;\n  char *cp = (char *)out->p, *d;\n\n  if (in->len == 0 || *s != '/')\n  {\n    out->len = 0;\n    return 0;\n  }\n\n  d = cp;\n\n  while (s < se)\n  {\n    const char *next = s;\n    struct mg_str component;\n    parse_uri_component(&next, se, '/', &component);\n    if (mg_vcmp(&component, \".\") == 0)\n    {\n      /* Yum. */\n    }\n    else if (mg_vcmp(&component, \"..\") == 0)\n    {\n      /* Backtrack to previous slash. */\n      if (d > cp + 1 && *(d - 1) == '/')\n        d--;\n      while (d > cp && *(d - 1) != '/')\n        d--;\n    }\n    else\n    {\n      memmove(d, s, next - s);\n      d += next - s;\n    }\n    s = next;\n  }\n  if (d == cp)\n    *d++ = '/';\n\n  out->p = cp;\n  out->len = d - cp;\n  return 1;\n}\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/http.c\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n */\n\n#if MG_ENABLE_HTTP\n\n/* Amalgamated: #include \"mongoose/src/internal.h\" */\n/* Amalgamated: #include \"mongoose/src/util.h\" */\n/* Amalgamated: #include \"common/sha1.h\" */\n/* Amalgamated: #include \"common/md5.h\" */\n\nstatic const char *mg_version_header = \"Mongoose/\" MG_VERSION;\n\nenum mg_http_proto_data_type\n{\n  DATA_NONE,\n  DATA_FILE,\n  DATA_PUT\n};\n\nstruct mg_http_proto_data_file\n{\n  FILE *fp;      /* Opened file. */\n  int64_t cl;    /* Content-Length. How many bytes to send. */\n  int64_t sent;  /* How many bytes have been already sent. */\n  int keepalive; /* Keep connection open after sending. */\n  enum mg_http_proto_data_type type;\n};\n\n#if MG_ENABLE_HTTP_CGI\nstruct mg_http_proto_data_cgi\n{\n  struct mg_connection *cgi_nc;\n};\n#endif\n\nstruct mg_http_proto_data_chuncked\n{\n  int64_t body_len; /* How many bytes of chunked body was reassembled. */\n};\n\nstruct mg_http_endpoint\n{\n  struct mg_http_endpoint *next;\n  const char *name;\n  size_t name_len;\n  mg_event_handler_t handler;\n};\n\nenum mg_http_multipart_stream_state\n{\n  MPS_BEGIN,\n  MPS_WAITING_FOR_BOUNDARY,\n  MPS_WAITING_FOR_CHUNK,\n  MPS_GOT_CHUNK,\n  MPS_GOT_BOUNDARY,\n  MPS_FINALIZE,\n  MPS_FINISHED\n};\n\nstruct mg_http_multipart_stream\n{\n  const char *boundary;\n  int boundary_len;\n  const char *var_name;\n  const char *file_name;\n  void *user_data;\n  int prev_io_len;\n  enum mg_http_multipart_stream_state state;\n  int processing_part;\n};\n\nstruct mg_http_proto_data\n{\n#if MG_ENABLE_FILESYSTEM\n  struct mg_http_proto_data_file file;\n#endif\n#if MG_ENABLE_HTTP_CGI\n  struct mg_http_proto_data_cgi cgi;\n#endif\n#if MG_ENABLE_HTTP_STREAMING_MULTIPART\n  struct mg_http_multipart_stream mp_stream;\n#endif\n  struct mg_http_proto_data_chuncked chunk;\n  struct mg_http_endpoint *endpoints;\n  mg_event_handler_t endpoint_handler;\n};\n\nstatic void mg_http_conn_destructor(void *proto_data);\nstruct mg_connection *mg_connect_http_base(\n    struct mg_mgr *mgr, mg_event_handler_t ev_handler,\n    struct mg_connect_opts opts, const char *schema, const char *schema_ssl,\n    const char *url, const char **path, char **user, char **pass, char **addr);\n\nstatic struct mg_http_proto_data *mg_http_get_proto_data(\n    struct mg_connection *c)\n{\n  if (c->proto_data == NULL)\n  {\n    c->proto_data = MG_CALLOC(1, sizeof(struct mg_http_proto_data));\n    c->proto_data_destructor = mg_http_conn_destructor;\n  }\n\n  return (struct mg_http_proto_data *)c->proto_data;\n}\n\n#if MG_ENABLE_HTTP_STREAMING_MULTIPART\nstatic void mg_http_free_proto_data_mp_stream(\n    struct mg_http_multipart_stream *mp)\n{\n  free((void *)mp->boundary);\n  free((void *)mp->var_name);\n  free((void *)mp->file_name);\n  memset(mp, 0, sizeof(*mp));\n}\n#endif\n\n#if MG_ENABLE_FILESYSTEM\nstatic void mg_http_free_proto_data_file(struct mg_http_proto_data_file *d)\n{\n  if (d != NULL)\n  {\n    if (d->fp != NULL)\n    {\n      fclose(d->fp);\n    }\n    memset(d, 0, sizeof(struct mg_http_proto_data_file));\n  }\n}\n#endif\n\nstatic void mg_http_free_proto_data_endpoints(struct mg_http_endpoint **ep)\n{\n  struct mg_http_endpoint *current = *ep;\n\n  while (current != NULL)\n  {\n    struct mg_http_endpoint *tmp = current->next;\n    free((void *)current->name);\n    free(current);\n    current = tmp;\n  }\n\n  ep = NULL;\n}\n\nstatic void mg_http_conn_destructor(void *proto_data)\n{\n  struct mg_http_proto_data *pd = (struct mg_http_proto_data *)proto_data;\n#if MG_ENABLE_FILESYSTEM\n  mg_http_free_proto_data_file(&pd->file);\n#endif\n#if MG_ENABLE_HTTP_CGI\n  mg_http_free_proto_data_cgi(&pd->cgi);\n#endif\n#if MG_ENABLE_HTTP_STREAMING_MULTIPART\n  mg_http_free_proto_data_mp_stream(&pd->mp_stream);\n#endif\n  mg_http_free_proto_data_endpoints(&pd->endpoints);\n  free(proto_data);\n}\n\n#if MG_ENABLE_FILESYSTEM\n\n#define MIME_ENTRY(_ext, _type)   \\\n  {                               \\\n    _ext, sizeof(_ext) - 1, _type \\\n  }\nstatic const struct\n{\n  const char *extension;\n  size_t ext_len;\n  const char *mime_type;\n} mg_static_builtin_mime_types[] = {\n    MIME_ENTRY(\"html\", \"text/html\"),\n    MIME_ENTRY(\"html\", \"text/html\"),\n    MIME_ENTRY(\"htm\", \"text/html\"),\n    MIME_ENTRY(\"shtm\", \"text/html\"),\n    MIME_ENTRY(\"shtml\", \"text/html\"),\n    MIME_ENTRY(\"css\", \"text/css\"),\n    MIME_ENTRY(\"js\", \"application/x-javascript\"),\n    MIME_ENTRY(\"ico\", \"image/x-icon\"),\n    MIME_ENTRY(\"gif\", \"image/gif\"),\n    MIME_ENTRY(\"jpg\", \"image/jpeg\"),\n    MIME_ENTRY(\"jpeg\", \"image/jpeg\"),\n    MIME_ENTRY(\"png\", \"image/png\"),\n    MIME_ENTRY(\"svg\", \"image/svg+xml\"),\n    MIME_ENTRY(\"txt\", \"text/plain\"),\n    MIME_ENTRY(\"torrent\", \"application/x-bittorrent\"),\n    MIME_ENTRY(\"wav\", \"audio/x-wav\"),\n    MIME_ENTRY(\"mp3\", \"audio/x-mp3\"),\n    MIME_ENTRY(\"mid\", \"audio/mid\"),\n    MIME_ENTRY(\"m3u\", \"audio/x-mpegurl\"),\n    MIME_ENTRY(\"ogg\", \"application/ogg\"),\n    MIME_ENTRY(\"ram\", \"audio/x-pn-realaudio\"),\n    MIME_ENTRY(\"xml\", \"text/xml\"),\n    MIME_ENTRY(\"ttf\", \"application/x-font-ttf\"),\n    MIME_ENTRY(\"json\", \"application/json\"),\n    MIME_ENTRY(\"xslt\", \"application/xml\"),\n    MIME_ENTRY(\"xsl\", \"application/xml\"),\n    MIME_ENTRY(\"ra\", \"audio/x-pn-realaudio\"),\n    MIME_ENTRY(\"doc\", \"application/msword\"),\n    MIME_ENTRY(\"exe\", \"application/octet-stream\"),\n    MIME_ENTRY(\"zip\", \"application/x-zip-compressed\"),\n    MIME_ENTRY(\"xls\", \"application/excel\"),\n    MIME_ENTRY(\"tgz\", \"application/x-tar-gz\"),\n    MIME_ENTRY(\"tar\", \"application/x-tar\"),\n    MIME_ENTRY(\"gz\", \"application/x-gunzip\"),\n    MIME_ENTRY(\"arj\", \"application/x-arj-compressed\"),\n    MIME_ENTRY(\"rar\", \"application/x-rar-compressed\"),\n    MIME_ENTRY(\"rtf\", \"application/rtf\"),\n    MIME_ENTRY(\"pdf\", \"application/pdf\"),\n    MIME_ENTRY(\"swf\", \"application/x-shockwave-flash\"),\n    MIME_ENTRY(\"mpg\", \"video/mpeg\"),\n    MIME_ENTRY(\"webm\", \"video/webm\"),\n    MIME_ENTRY(\"mpeg\", \"video/mpeg\"),\n    MIME_ENTRY(\"mov\", \"video/quicktime\"),\n    MIME_ENTRY(\"mp4\", \"video/mp4\"),\n    MIME_ENTRY(\"m4v\", \"video/x-m4v\"),\n    MIME_ENTRY(\"asf\", \"video/x-ms-asf\"),\n    MIME_ENTRY(\"avi\", \"video/x-msvideo\"),\n    MIME_ENTRY(\"bmp\", \"image/bmp\"),\n    {NULL, 0, NULL}};\n\nstatic struct mg_str mg_get_mime_type(const char *path, const char *dflt,\n                                      const struct mg_serve_http_opts *opts)\n{\n  const char *ext, *overrides;\n  size_t i, path_len;\n  struct mg_str r, k, v;\n\n  path_len = strlen(path);\n\n  overrides = opts->custom_mime_types;\n  while ((overrides = mg_next_comma_list_entry(overrides, &k, &v)) != NULL)\n  {\n    ext = path + (path_len - k.len);\n    if (path_len > k.len && mg_vcasecmp(&k, ext) == 0)\n    {\n      return v;\n    }\n  }\n\n  for (i = 0; mg_static_builtin_mime_types[i].extension != NULL; i++)\n  {\n    ext = path + (path_len - mg_static_builtin_mime_types[i].ext_len);\n    if (path_len > mg_static_builtin_mime_types[i].ext_len && ext[-1] == '.' &&\n        mg_casecmp(ext, mg_static_builtin_mime_types[i].extension) == 0)\n    {\n      r.p = mg_static_builtin_mime_types[i].mime_type;\n      r.len = strlen(r.p);\n      return r;\n    }\n  }\n\n  r.p = dflt;\n  r.len = strlen(r.p);\n  return r;\n}\n#endif\n\n/*\n * Check whether full request is buffered. Return:\n *   -1  if request is malformed\n *    0  if request is not yet fully buffered\n *   >0  actual request length, including last \\r\\n\\r\\n\n */\nstatic int mg_http_get_request_len(const char *s, int buf_len)\n{\n  const unsigned char *buf = (unsigned char *)s;\n  int i;\n\n  for (i = 0; i < buf_len; i++)\n  {\n    if (!isprint(buf[i]) && buf[i] != '\\r' && buf[i] != '\\n' && buf[i] < 128)\n    {\n      return -1;\n    }\n    else if (buf[i] == '\\n' && i + 1 < buf_len && buf[i + 1] == '\\n')\n    {\n      return i + 2;\n    }\n    else if (buf[i] == '\\n' && i + 2 < buf_len && buf[i + 1] == '\\r' &&\n             buf[i + 2] == '\\n')\n    {\n      return i + 3;\n    }\n  }\n\n  return 0;\n}\n\nstatic const char *mg_http_parse_headers(const char *s, const char *end,\n                                         int len, struct http_message *req)\n{\n  int i = 0;\n  while (i < (int)ARRAY_SIZE(req->header_names) - 1)\n  {\n    struct mg_str *k = &req->header_names[i], *v = &req->header_values[i];\n\n    s = mg_skip(s, end, \": \", k);\n    s = mg_skip(s, end, \"\\r\\n\", v);\n\n    while (v->len > 0 && v->p[v->len - 1] == ' ')\n    {\n      v->len--; /* Trim trailing spaces in header value */\n    }\n\n    /*\n     * If header value is empty - skip it and go to next (if any).\n     * NOTE: Do not add it to headers_values because such addition changes API\n     * behaviour\n     */\n    if (k->len != 0 && v->len == 0)\n    {\n      continue;\n    }\n\n    if (k->len == 0 || v->len == 0)\n    {\n      k->p = v->p = NULL;\n      k->len = v->len = 0;\n      break;\n    }\n\n    if (!mg_ncasecmp(k->p, \"Content-Length\", 14))\n    {\n      req->body.len = (size_t)to64(v->p);\n      req->message.len = len + req->body.len;\n    }\n\n    i++;\n  }\n\n  return s;\n}\n\nint mg_parse_http(const char *s, int n, struct http_message *hm, int is_req)\n{\n  const char *end, *qs;\n  int len = mg_http_get_request_len(s, n);\n\n  if (len <= 0)\n    return len;\n\n  memset(hm, 0, sizeof(*hm));\n  hm->message.p = s;\n  hm->body.p = s + len;\n  hm->message.len = hm->body.len = (size_t)~0;\n  end = s + len;\n\n  /* Request is fully buffered. Skip leading whitespaces. */\n  while (s < end && isspace(*(unsigned char *)s))\n    s++;\n\n  if (is_req)\n  {\n    /* Parse request line: method, URI, proto */\n    s = mg_skip(s, end, \" \", &hm->method);\n    s = mg_skip(s, end, \" \", &hm->uri);\n    s = mg_skip(s, end, \"\\r\\n\", &hm->proto);\n    if (hm->uri.p <= hm->method.p || hm->proto.p <= hm->uri.p)\n      return -1;\n\n    /* If URI contains '?' character, initialize query_string */\n    if ((qs = (char *)memchr(hm->uri.p, '?', hm->uri.len)) != NULL)\n    {\n      hm->query_string.p = qs + 1;\n      hm->query_string.len = &hm->uri.p[hm->uri.len] - (qs + 1);\n      hm->uri.len = qs - hm->uri.p;\n    }\n  }\n  else\n  {\n    s = mg_skip(s, end, \" \", &hm->proto);\n    if (end - s < 4 || s[3] != ' ')\n      return -1;\n    hm->resp_code = atoi(s);\n    if (hm->resp_code < 100 || hm->resp_code >= 600)\n      return -1;\n    s += 4;\n    s = mg_skip(s, end, \"\\r\\n\", &hm->resp_status_msg);\n  }\n\n  s = mg_http_parse_headers(s, end, len, hm);\n\n  /*\n   * mg_parse_http() is used to parse both HTTP requests and HTTP\n   * responses. If HTTP response does not have Content-Length set, then\n   * body is read until socket is closed, i.e. body.len is infinite (~0).\n   *\n   * For HTTP requests though, according to\n   * http://tools.ietf.org/html/rfc7231#section-8.1.3,\n   * only POST and PUT methods have defined body semantics.\n   * Therefore, if Content-Length is not specified and methods are\n   * not one of PUT or POST, set body length to 0.\n   *\n   * So,\n   * if it is HTTP request, and Content-Length is not set,\n   * and method is not (PUT or POST) then reset body length to zero.\n   */\n  if (hm->body.len == (size_t)~0 && is_req &&\n      mg_vcasecmp(&hm->method, \"PUT\") != 0 &&\n      mg_vcasecmp(&hm->method, \"POST\") != 0)\n  {\n    hm->body.len = 0;\n    hm->message.len = len;\n  }\n\n  return len;\n}\n\nstruct mg_str *mg_get_http_header(struct http_message *hm, const char *name)\n{\n  size_t i, len = strlen(name);\n\n  for (i = 0; hm->header_names[i].len > 0; i++)\n  {\n    struct mg_str *h = &hm->header_names[i], *v = &hm->header_values[i];\n    if (h->p != NULL && h->len == len && !mg_ncasecmp(h->p, name, len))\n      return v;\n  }\n\n  return NULL;\n}\n\n#if MG_ENABLE_FILESYSTEM\nstatic void mg_http_transfer_file_data(struct mg_connection *nc)\n{\n  struct mg_http_proto_data *pd = mg_http_get_proto_data(nc);\n  char buf[MG_MAX_HTTP_SEND_MBUF];\n  size_t n = 0, to_read = 0, left = (size_t)(pd->file.cl - pd->file.sent);\n\n  if (pd->file.type == DATA_FILE)\n  {\n    struct mbuf *io = &nc->send_mbuf;\n    if (io->len < sizeof(buf))\n    {\n      to_read = sizeof(buf) - io->len;\n    }\n\n    if (left > 0 && to_read > left)\n    {\n      to_read = left;\n    }\n\n    if (to_read == 0)\n    {\n      /* Rate limiting. send_mbuf is too full, wait until it's drained. */\n    }\n    else if (pd->file.sent < pd->file.cl &&\n             (n = fread(buf, 1, to_read, pd->file.fp)) > 0)\n    {\n      mg_send(nc, buf, n);\n      pd->file.sent += n;\n    }\n    else\n    {\n      if (!pd->file.keepalive)\n        nc->flags |= MG_F_SEND_AND_CLOSE;\n      mg_http_free_proto_data_file(&pd->file);\n    }\n  }\n  else if (pd->file.type == DATA_PUT)\n  {\n    struct mbuf *io = &nc->recv_mbuf;\n    size_t to_write = left <= 0 ? 0 : left < io->len ? (size_t)left : io->len;\n    size_t n = fwrite(io->buf, 1, to_write, pd->file.fp);\n    if (n > 0)\n    {\n      mbuf_remove(io, n);\n      pd->file.sent += n;\n    }\n    if (n == 0 || pd->file.sent >= pd->file.cl)\n    {\n      if (!pd->file.keepalive)\n        nc->flags |= MG_F_SEND_AND_CLOSE;\n      mg_http_free_proto_data_file(&pd->file);\n    }\n  }\n#if MG_ENABLE_HTTP_CGI\n  else if (pd->cgi.cgi_nc != NULL)\n  {\n    /* This is POST data that needs to be forwarded to the CGI process */\n    if (pd->cgi.cgi_nc != NULL)\n    {\n      mg_forward(nc, pd->cgi.cgi_nc);\n    }\n    else\n    {\n      nc->flags |= MG_F_SEND_AND_CLOSE;\n    }\n  }\n#endif\n}\n#endif /* MG_ENABLE_FILESYSTEM */\n\n/*\n * Parse chunked-encoded buffer. Return 0 if the buffer is not encoded, or\n * if it's incomplete. If the chunk is fully buffered, return total number of\n * bytes in a chunk, and store data in `data`, `data_len`.\n */\nstatic size_t mg_http_parse_chunk(char *buf, size_t len, char **chunk_data,\n                                  size_t *chunk_len)\n{\n  unsigned char *s = (unsigned char *)buf;\n  size_t n = 0; /* scanned chunk length */\n  size_t i = 0; /* index in s */\n\n  /* Scan chunk length. That should be a hexadecimal number. */\n  while (i < len && isxdigit(s[i]))\n  {\n    n *= 16;\n    n += (s[i] >= '0' && s[i] <= '9') ? s[i] - '0' : tolower(s[i]) - 'a' + 10;\n    i++;\n  }\n\n  /* Skip new line */\n  if (i == 0 || i + 2 > len || s[i] != '\\r' || s[i + 1] != '\\n')\n  {\n    return 0;\n  }\n  i += 2;\n\n  /* Record where the data is */\n  *chunk_data = (char *)s + i;\n  *chunk_len = n;\n\n  /* Skip data */\n  i += n;\n\n  /* Skip new line */\n  if (i == 0 || i + 2 > len || s[i] != '\\r' || s[i + 1] != '\\n')\n  {\n    return 0;\n  }\n  return i + 2;\n}\n\nMG_INTERNAL size_t mg_handle_chunked(struct mg_connection *nc,\n                                     struct http_message *hm, char *buf,\n                                     size_t blen)\n{\n  struct mg_http_proto_data *pd = mg_http_get_proto_data(nc);\n  char *data;\n  size_t i, n, data_len, body_len, zero_chunk_received = 0;\n  /* Find out piece of received data that is not yet reassembled */\n  body_len = (size_t)pd->chunk.body_len;\n  assert(blen >= body_len);\n\n  /* Traverse all fully buffered chunks */\n  for (i = body_len;\n       (n = mg_http_parse_chunk(buf + i, blen - i, &data, &data_len)) > 0;\n       i += n)\n  {\n    /* Collapse chunk data to the rest of HTTP body */\n    memmove(buf + body_len, data, data_len);\n    body_len += data_len;\n    hm->body.len = body_len;\n\n    if (data_len == 0)\n    {\n      zero_chunk_received = 1;\n      i += n;\n      break;\n    }\n  }\n\n  if (i > body_len)\n  {\n    /* Shift unparsed content to the parsed body */\n    assert(i <= blen);\n    memmove(buf + body_len, buf + i, blen - i);\n    memset(buf + body_len + blen - i, 0, i - body_len);\n    nc->recv_mbuf.len -= i - body_len;\n    pd->chunk.body_len = body_len;\n\n    /* Send MG_EV_HTTP_CHUNK event */\n    nc->flags &= ~MG_F_DELETE_CHUNK;\n    mg_call(nc, nc->handler, MG_EV_HTTP_CHUNK, hm);\n\n    /* Delete processed data if user set MG_F_DELETE_CHUNK flag */\n    if (nc->flags & MG_F_DELETE_CHUNK)\n    {\n      memset(buf, 0, body_len);\n      memmove(buf, buf + body_len, blen - i);\n      nc->recv_mbuf.len -= body_len;\n      hm->body.len = 0;\n      pd->chunk.body_len = 0;\n    }\n\n    if (zero_chunk_received)\n    {\n      hm->message.len = (size_t)pd->chunk.body_len + blen - i;\n    }\n  }\n\n  return body_len;\n}\n\nstatic mg_event_handler_t mg_http_get_endpoint_handler(\n    struct mg_connection *nc, struct mg_str *uri_path)\n{\n  struct mg_http_proto_data *pd;\n  mg_event_handler_t ret = NULL;\n  int matched, matched_max = 0;\n  struct mg_http_endpoint *ep;\n\n  if (nc == NULL)\n  {\n    return NULL;\n  }\n\n  pd = mg_http_get_proto_data(nc);\n\n  ep = pd->endpoints;\n  while (ep != NULL)\n  {\n    const struct mg_str name_s = {ep->name, ep->name_len};\n    if ((matched = mg_match_prefix_n(name_s, *uri_path)) != -1)\n    {\n      if (matched > matched_max)\n      {\n        /* Looking for the longest suitable handler */\n        ret = ep->handler;\n        matched_max = matched;\n      }\n    }\n\n    ep = ep->next;\n  }\n\n  return ret;\n}\n\nstatic void mg_http_call_endpoint_handler(struct mg_connection *nc, int ev,\n                                          struct http_message *hm)\n{\n  struct mg_http_proto_data *pd = mg_http_get_proto_data(nc);\n\n  if (pd->endpoint_handler == NULL || ev == MG_EV_HTTP_REQUEST)\n  {\n    pd->endpoint_handler =\n        ev == MG_EV_HTTP_REQUEST\n            ? mg_http_get_endpoint_handler(nc->listener, &hm->uri)\n            : NULL;\n  }\n  mg_call(nc, pd->endpoint_handler ? pd->endpoint_handler : nc->handler, ev,\n          hm);\n}\n\n#if MG_ENABLE_HTTP_STREAMING_MULTIPART\nstatic void mg_http_multipart_continue(struct mg_connection *nc);\n\nstatic void mg_http_multipart_begin(struct mg_connection *nc,\n                                    struct http_message *hm, int req_len);\n\n#endif\n\n/*\n * lx106 compiler has a bug (TODO(mkm) report and insert tracking bug here)\n * If a big structure is declared in a big function, lx106 gcc will make it\n * even bigger (round up to 4k, from 700 bytes of actual size).\n */\n#ifdef __xtensa__\nstatic void mg_http_handler2(struct mg_connection *nc, int ev, void *ev_data,\n                             struct http_message *hm) __attribute__((noinline));\n\nvoid mg_http_handler(struct mg_connection *nc, int ev, void *ev_data)\n{\n  struct http_message hm;\n  mg_http_handler2(nc, ev, ev_data, &hm);\n}\n\nstatic void mg_http_handler2(struct mg_connection *nc, int ev, void *ev_data,\n                             struct http_message *hm)\n{\n#else  /* !__XTENSA__ */\nvoid mg_http_handler(struct mg_connection *nc, int ev, void *ev_data)\n{\n  struct http_message shm;\n  struct http_message *hm = &shm;\n#endif /* __XTENSA__ */\n  struct mg_http_proto_data *pd = mg_http_get_proto_data(nc);\n  struct mbuf *io = &nc->recv_mbuf;\n  int req_len;\n  const int is_req = (nc->listener != NULL);\n#if MG_ENABLE_HTTP_WEBSOCKET\n  struct mg_str *vec;\n#endif\n  if (ev == MG_EV_CLOSE)\n  {\n#if MG_ENABLE_HTTP_STREAMING_MULTIPART\n    if (pd->mp_stream.boundary != NULL)\n    {\n      /*\n       * Multipart message is in progress, but connection is closed.\n       * Finish part and request with an error flag.\n       */\n      struct mg_http_multipart_part mp;\n      memset(&mp, 0, sizeof(mp));\n      mp.status = -1;\n      mp.var_name = pd->mp_stream.var_name;\n      mp.file_name = pd->mp_stream.file_name;\n      mg_call(nc, (pd->endpoint_handler ? pd->endpoint_handler : nc->handler),\n              MG_EV_HTTP_PART_END, &mp);\n      mp.var_name = NULL;\n      mp.file_name = NULL;\n      mg_call(nc, (pd->endpoint_handler ? pd->endpoint_handler : nc->handler),\n              MG_EV_HTTP_MULTIPART_REQUEST_END, &mp);\n    }\n    else\n#endif\n        if (io->len > 0 && mg_parse_http(io->buf, io->len, hm, is_req) > 0)\n    {\n      /*\n      * For HTTP messages without Content-Length, always send HTTP message\n      * before MG_EV_CLOSE message.\n      */\n      int ev2 = is_req ? MG_EV_HTTP_REQUEST : MG_EV_HTTP_REPLY;\n      hm->message.len = io->len;\n      hm->body.len = io->buf + io->len - hm->body.p;\n      mg_http_call_endpoint_handler(nc, ev2, hm);\n    }\n  }\n\n#if MG_ENABLE_FILESYSTEM\n  if (pd->file.fp != NULL)\n  {\n    mg_http_transfer_file_data(nc);\n  }\n#endif\n\n  mg_call(nc, nc->handler, ev, ev_data);\n\n  if (ev == MG_EV_RECV)\n  {\n    struct mg_str *s;\n\n#if MG_ENABLE_HTTP_STREAMING_MULTIPART\n    if (pd->mp_stream.boundary != NULL)\n    {\n      mg_http_multipart_continue(nc);\n      return;\n    }\n#endif /* MG_ENABLE_HTTP_STREAMING_MULTIPART */\n\n    req_len = mg_parse_http(io->buf, io->len, hm, is_req);\n\n    if (req_len > 0 &&\n        (s = mg_get_http_header(hm, \"Transfer-Encoding\")) != NULL &&\n        mg_vcasecmp(s, \"chunked\") == 0)\n    {\n      mg_handle_chunked(nc, hm, io->buf + req_len, io->len - req_len);\n    }\n\n#if MG_ENABLE_HTTP_STREAMING_MULTIPART\n    if (req_len > 0 && (s = mg_get_http_header(hm, \"Content-Type\")) != NULL &&\n        s->len >= 9 && strncmp(s->p, \"multipart\", 9) == 0)\n    {\n      mg_http_multipart_begin(nc, hm, req_len);\n      mg_http_multipart_continue(nc);\n      return;\n    }\n#endif /* MG_ENABLE_HTTP_STREAMING_MULTIPART */\n\n    /* TODO(alashkin): refactor this ifelseifelseifelseifelse */\n    if ((req_len < 0 ||\n         (req_len == 0 && io->len >= MG_MAX_HTTP_REQUEST_SIZE)))\n    {\n      DBG((\"invalid request\"));\n      nc->flags |= MG_F_CLOSE_IMMEDIATELY;\n    }\n    else if (req_len == 0)\n    {\n      /* Do nothing, request is not yet fully buffered */\n    }\n#if MG_ENABLE_HTTP_WEBSOCKET\n    else if (nc->listener == NULL &&\n             mg_get_http_header(hm, \"Sec-WebSocket-Accept\"))\n    {\n      /* We're websocket client, got handshake response from server. */\n      /* TODO(lsm): check the validity of accept Sec-WebSocket-Accept */\n      mbuf_remove(io, req_len);\n      nc->proto_handler = mg_ws_handler;\n      nc->flags |= MG_F_IS_WEBSOCKET;\n      mg_call(nc, nc->handler, MG_EV_WEBSOCKET_HANDSHAKE_DONE, NULL);\n      mg_ws_handler(nc, MG_EV_RECV, ev_data);\n    }\n    else if (nc->listener != NULL &&\n             (vec = mg_get_http_header(hm, \"Sec-WebSocket-Key\")) != NULL)\n    {\n      mg_event_handler_t handler;\n\n      /* This is a websocket request. Switch protocol handlers. */\n      mbuf_remove(io, req_len);\n      nc->proto_handler = mg_ws_handler;\n      nc->flags |= MG_F_IS_WEBSOCKET;\n\n      /*\n       * If we have a handler set up with mg_register_http_endpoint(),\n       * deliver subsequent websocket events to this handler after the\n       * protocol switch.\n       */\n      handler = mg_http_get_endpoint_handler(nc->listener, &hm->uri);\n      if (handler != NULL)\n      {\n        nc->handler = handler;\n      }\n\n      /* Send handshake */\n      mg_call(nc, nc->handler, MG_EV_WEBSOCKET_HANDSHAKE_REQUEST, hm);\n      if (!(nc->flags & MG_F_CLOSE_IMMEDIATELY))\n      {\n        if (nc->send_mbuf.len == 0)\n        {\n          mg_ws_handshake(nc, vec);\n        }\n        mg_call(nc, nc->handler, MG_EV_WEBSOCKET_HANDSHAKE_DONE, NULL);\n        mg_ws_handler(nc, MG_EV_RECV, ev_data);\n      }\n    }\n#endif /* MG_ENABLE_HTTP_WEBSOCKET */\n    else if (hm->message.len <= io->len)\n    {\n      int trigger_ev = nc->listener ? MG_EV_HTTP_REQUEST : MG_EV_HTTP_REPLY;\n\n      /* Whole HTTP message is fully buffered, call event handler */\n\n#if MG_ENABLE_JAVASCRIPT\n      v7_val_t v1, v2, headers, req, args, res;\n      struct v7 *v7 = nc->mgr->v7;\n      const char *ev_name = trigger_ev == MG_EV_HTTP_REPLY ? \"onsnd\" : \"onrcv\";\n      int i, js_callback_handled_request = 0;\n\n      if (v7 != NULL)\n      {\n        /* Lookup JS callback */\n        v1 = v7_get(v7, v7_get_global(v7), \"Http\", ~0);\n        v2 = v7_get(v7, v1, ev_name, ~0);\n\n        /* Create callback params. TODO(lsm): own/disown those */\n        args = v7_mk_array(v7);\n        req = v7_mk_object(v7);\n        headers = v7_mk_object(v7);\n\n        /* Populate request object */\n        v7_set(v7, req, \"method\", ~0,\n               v7_mk_string(v7, hm->method.p, hm->method.len, 1));\n        v7_set(v7, req, \"uri\", ~0, v7_mk_string(v7, hm->uri.p, hm->uri.len, 1));\n        v7_set(v7, req, \"body\", ~0,\n               v7_mk_string(v7, hm->body.p, hm->body.len, 1));\n        v7_set(v7, req, \"headers\", ~0, headers);\n        for (i = 0; hm->header_names[i].len > 0; i++)\n        {\n          const struct mg_str *name = &hm->header_names[i];\n          const struct mg_str *value = &hm->header_values[i];\n          v7_set(v7, headers, name->p, name->len,\n                 v7_mk_string(v7, value->p, value->len, 1));\n        }\n\n        /* Invoke callback. TODO(lsm): report errors */\n        v7_array_push(v7, args, v7_mk_foreign(v7, nc));\n        v7_array_push(v7, args, req);\n        if (v7_apply(v7, v2, V7_UNDEFINED, args, &res) == V7_OK &&\n            v7_is_truthy(v7, res))\n        {\n          js_callback_handled_request++;\n        }\n      }\n\n      /* If JS callback returns true, stop request processing */\n      if (js_callback_handled_request)\n      {\n        nc->flags |= MG_F_SEND_AND_CLOSE;\n      }\n      else\n      {\n        mg_http_call_endpoint_handler(nc, trigger_ev, hm);\n      }\n#else\n      mg_http_call_endpoint_handler(nc, trigger_ev, hm);\n#endif\n      mbuf_remove(io, hm->message.len);\n    }\n  }\n  (void)pd;\n}\n\nstatic size_t mg_get_line_len(const char *buf, size_t buf_len)\n{\n  size_t len = 0;\n  while (len < buf_len && buf[len] != '\\n')\n    len++;\n  return len == buf_len ? 0 : len + 1;\n}\n\n#if MG_ENABLE_HTTP_STREAMING_MULTIPART\nstatic void mg_http_multipart_begin(struct mg_connection *nc,\n                                    struct http_message *hm, int req_len)\n{\n  struct mg_http_proto_data *pd = mg_http_get_proto_data(nc);\n  struct mg_str *ct;\n  struct mbuf *io = &nc->recv_mbuf;\n\n  char boundary[100];\n  int boundary_len;\n\n  if (nc->listener == NULL)\n  {\n    /* No streaming for replies now */\n    goto exit_mp;\n  }\n\n  ct = mg_get_http_header(hm, \"Content-Type\");\n  if (ct == NULL)\n  {\n    /* We need more data - or it isn't multipart mesage */\n    goto exit_mp;\n  }\n\n  /* Content-type should start with \"multipart\" */\n  if (ct->len < 9 || strncmp(ct->p, \"multipart\", 9) != 0)\n  {\n    goto exit_mp;\n  }\n\n  boundary_len =\n      mg_http_parse_header(ct, \"boundary\", boundary, sizeof(boundary));\n  if (boundary_len == 0)\n  {\n    /*\n     * Content type is multipart, but there is no boundary,\n     * probably malformed request\n     */\n    nc->flags = MG_F_CLOSE_IMMEDIATELY;\n    DBG((\"invalid request\"));\n    goto exit_mp;\n  }\n\n  /* If we reach this place - that is multipart request */\n\n  if (pd->mp_stream.boundary != NULL)\n  {\n    /*\n     * Another streaming request was in progress,\n     * looks like protocol error\n     */\n    nc->flags |= MG_F_CLOSE_IMMEDIATELY;\n  }\n  else\n  {\n    pd->mp_stream.state = MPS_BEGIN;\n    pd->mp_stream.boundary = strdup(boundary);\n    pd->mp_stream.boundary_len = strlen(boundary);\n    pd->mp_stream.var_name = pd->mp_stream.file_name = NULL;\n\n    pd->endpoint_handler = mg_http_get_endpoint_handler(nc->listener, &hm->uri);\n    if (pd->endpoint_handler == NULL)\n    {\n      pd->endpoint_handler = nc->handler;\n    }\n\n    mg_call(nc, pd->endpoint_handler, MG_EV_HTTP_MULTIPART_REQUEST, hm);\n\n    mbuf_remove(io, req_len);\n  }\nexit_mp:;\n}\n\n#define CONTENT_DISPOSITION \"Content-Disposition: \"\n\nstatic void mg_http_multipart_call_handler(struct mg_connection *c, int ev,\n                                           const char *data, size_t data_len)\n{\n  struct mg_http_multipart_part mp;\n  struct mg_http_proto_data *pd = mg_http_get_proto_data(c);\n  memset(&mp, 0, sizeof(mp));\n\n  mp.var_name = pd->mp_stream.var_name;\n  mp.file_name = pd->mp_stream.file_name;\n  mp.user_data = pd->mp_stream.user_data;\n  mp.data.p = data;\n  mp.data.len = data_len;\n  mg_call(c, pd->endpoint_handler, ev, &mp);\n  pd->mp_stream.user_data = mp.user_data;\n}\n\nstatic int mg_http_multipart_got_chunk(struct mg_connection *c)\n{\n  struct mg_http_proto_data *pd = mg_http_get_proto_data(c);\n  struct mbuf *io = &c->recv_mbuf;\n\n  mg_http_multipart_call_handler(c, MG_EV_HTTP_PART_DATA, io->buf,\n                                 pd->mp_stream.prev_io_len);\n  mbuf_remove(io, pd->mp_stream.prev_io_len);\n  pd->mp_stream.prev_io_len = 0;\n  pd->mp_stream.state = MPS_WAITING_FOR_CHUNK;\n\n  return 0;\n}\n\nstatic int mg_http_multipart_finalize(struct mg_connection *c)\n{\n  struct mg_http_proto_data *pd = mg_http_get_proto_data(c);\n\n  mg_http_multipart_call_handler(c, MG_EV_HTTP_PART_END, NULL, 0);\n  free((void *)pd->mp_stream.file_name);\n  pd->mp_stream.file_name = NULL;\n  free((void *)pd->mp_stream.var_name);\n  pd->mp_stream.var_name = NULL;\n  mg_http_multipart_call_handler(c, MG_EV_HTTP_MULTIPART_REQUEST_END, NULL, 0);\n  mg_http_free_proto_data_mp_stream(&pd->mp_stream);\n  pd->mp_stream.state = MPS_FINISHED;\n\n  return 1;\n}\n\nstatic int mg_http_multipart_wait_for_boundary(struct mg_connection *c)\n{\n  const char *boundary;\n  struct mbuf *io = &c->recv_mbuf;\n  struct mg_http_proto_data *pd = mg_http_get_proto_data(c);\n\n  if ((int)io->len < pd->mp_stream.boundary_len + 2)\n  {\n    return 0;\n  }\n\n  boundary = c_strnstr(io->buf, pd->mp_stream.boundary, io->len);\n  if (boundary != NULL)\n  {\n    const char *boundary_end = (boundary + pd->mp_stream.boundary_len);\n    if (io->len - (boundary_end - io->buf) < 4)\n    {\n      return 0;\n    }\n    if (memcmp(boundary_end, \"--\\r\\n\", 4) == 0)\n    {\n      pd->mp_stream.state = MPS_FINALIZE;\n      mbuf_remove(io, (boundary_end - io->buf) + 4);\n    }\n    else\n    {\n      pd->mp_stream.state = MPS_GOT_BOUNDARY;\n    }\n  }\n  else\n  {\n    return 0;\n  }\n\n  return 1;\n}\n\nstatic int mg_http_multipart_process_boundary(struct mg_connection *c)\n{\n  int data_size;\n  const char *boundary, *block_begin;\n  struct mbuf *io = &c->recv_mbuf;\n  struct mg_http_proto_data *pd = mg_http_get_proto_data(c);\n  char file_name[100], var_name[100];\n  int line_len;\n  boundary = c_strnstr(io->buf, pd->mp_stream.boundary, io->len);\n  block_begin = boundary + pd->mp_stream.boundary_len + 2;\n  data_size = io->len - (block_begin - io->buf);\n\n  while (data_size > 0 &&\n         (line_len = mg_get_line_len(block_begin, data_size)) != 0)\n  {\n    if (line_len > (int)sizeof(CONTENT_DISPOSITION) &&\n        mg_ncasecmp(block_begin, CONTENT_DISPOSITION,\n                    sizeof(CONTENT_DISPOSITION) - 1) == 0)\n    {\n      struct mg_str header;\n\n      header.p = block_begin + sizeof(CONTENT_DISPOSITION) - 1;\n      header.len = line_len - sizeof(CONTENT_DISPOSITION) - 1;\n      mg_http_parse_header(&header, \"name\", var_name, sizeof(var_name) - 2);\n      mg_http_parse_header(&header, \"filename\", file_name,\n                           sizeof(file_name) - 2);\n      block_begin += line_len;\n      data_size -= line_len;\n      continue;\n    }\n\n    if (line_len == 2 && mg_ncasecmp(block_begin, \"\\r\\n\", 2) == 0)\n    {\n      mbuf_remove(io, block_begin - io->buf + 2);\n\n      if (pd->mp_stream.processing_part != 0)\n      {\n        mg_http_multipart_call_handler(c, MG_EV_HTTP_PART_END, NULL, 0);\n      }\n\n      free((void *)pd->mp_stream.file_name);\n      pd->mp_stream.file_name = strdup(file_name);\n      free((void *)pd->mp_stream.var_name);\n      pd->mp_stream.var_name = strdup(var_name);\n\n      mg_http_multipart_call_handler(c, MG_EV_HTTP_PART_BEGIN, NULL, 0);\n      pd->mp_stream.state = MPS_WAITING_FOR_CHUNK;\n      pd->mp_stream.processing_part++;\n      return 1;\n    }\n\n    block_begin += line_len;\n  }\n\n  pd->mp_stream.state = MPS_WAITING_FOR_BOUNDARY;\n\n  return 0;\n}\n\nstatic int mg_http_multipart_continue_wait_for_chunk(struct mg_connection *c)\n{\n  struct mg_http_proto_data *pd = mg_http_get_proto_data(c);\n  struct mbuf *io = &c->recv_mbuf;\n\n  const char *boundary;\n  if ((int)io->len < pd->mp_stream.boundary_len + 6 /* \\r\\n, --, -- */)\n  {\n    return 0;\n  }\n\n  boundary = c_strnstr(io->buf, pd->mp_stream.boundary, io->len);\n  if (boundary == NULL && pd->mp_stream.prev_io_len == 0)\n  {\n    pd->mp_stream.prev_io_len = io->len;\n    return 0;\n  }\n  else if (boundary == NULL &&\n           (int)io->len >\n               pd->mp_stream.prev_io_len + pd->mp_stream.boundary_len + 4)\n  {\n    pd->mp_stream.state = MPS_GOT_CHUNK;\n    return 1;\n  }\n  else if (boundary != NULL)\n  {\n    int data_size = (boundary - io->buf - 4);\n    mg_http_multipart_call_handler(c, MG_EV_HTTP_PART_DATA, io->buf, data_size);\n    mbuf_remove(io, (boundary - io->buf));\n    pd->mp_stream.prev_io_len = 0;\n    pd->mp_stream.state = MPS_WAITING_FOR_BOUNDARY;\n    return 1;\n  }\n  else\n  {\n    return 0;\n  }\n}\n\nstatic void mg_http_multipart_continue(struct mg_connection *c)\n{\n  struct mg_http_proto_data *pd = mg_http_get_proto_data(c);\n  while (1)\n  {\n    switch (pd->mp_stream.state)\n    {\n    case MPS_BEGIN:\n    {\n      pd->mp_stream.state = MPS_WAITING_FOR_BOUNDARY;\n      break;\n    }\n    case MPS_WAITING_FOR_BOUNDARY:\n    {\n      if (mg_http_multipart_wait_for_boundary(c) == 0)\n      {\n        return;\n      }\n      break;\n    }\n    case MPS_GOT_BOUNDARY:\n    {\n      if (mg_http_multipart_process_boundary(c) == 0)\n      {\n        return;\n      }\n      break;\n    }\n    case MPS_WAITING_FOR_CHUNK:\n    {\n      if (mg_http_multipart_continue_wait_for_chunk(c) == 0)\n      {\n        return;\n      }\n      break;\n    }\n    case MPS_GOT_CHUNK:\n    {\n      if (mg_http_multipart_got_chunk(c) == 0)\n      {\n        return;\n      }\n      break;\n    }\n    case MPS_FINALIZE:\n    {\n      if (mg_http_multipart_finalize(c) == 0)\n      {\n        return;\n      }\n      break;\n    }\n    case MPS_FINISHED:\n    {\n      mbuf_remove(&c->recv_mbuf, c->recv_mbuf.len);\n      return;\n    }\n    }\n  }\n}\n\nstruct file_upload_state\n{\n  char *lfn;\n  size_t num_recd;\n  FILE *fp;\n};\n\nvoid mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data,\n                            mg_fu_fname_fn local_name_fn)\n{\n  switch (ev)\n  {\n  case MG_EV_HTTP_PART_BEGIN:\n  {\n    struct mg_http_multipart_part *mp =\n        (struct mg_http_multipart_part *)ev_data;\n    struct file_upload_state *fus =\n        (struct file_upload_state *)calloc(1, sizeof(*fus));\n    mp->user_data = NULL;\n\n    struct mg_str lfn = local_name_fn(nc, mg_mk_str(mp->file_name));\n    if (lfn.p == NULL || lfn.len == 0)\n    {\n      LOG(LL_ERROR, (\"%p Not allowed to upload %s\", nc, mp->file_name));\n      mg_printf(nc,\n                \"HTTP/1.1 403 Not Allowed\\r\\n\"\n                \"Content-Type: text/plain\\r\\n\"\n                \"Connection: close\\r\\n\\r\\n\"\n                \"Not allowed to upload %s\\r\\n\",\n                mp->file_name);\n      nc->flags |= MG_F_SEND_AND_CLOSE;\n      return;\n    }\n    fus->lfn = (char *)malloc(lfn.len + 1);\n    memcpy(fus->lfn, lfn.p, lfn.len);\n    fus->lfn[lfn.len] = '\\0';\n    if (lfn.p != mp->file_name)\n      free((char *)lfn.p);\n    LOG(LL_DEBUG,\n        (\"%p Receiving file %s -> %s\", nc, mp->file_name, fus->lfn));\n    fus->fp = fopen(fus->lfn, \"w\");\n    if (fus->fp == NULL)\n    {\n      mg_printf(nc,\n                \"HTTP/1.1 500 Internal Server Error\\r\\n\"\n                \"Content-Type: text/plain\\r\\n\"\n                \"Connection: close\\r\\n\\r\\n\");\n      LOG(LL_ERROR, (\"Failed to open %s: %d\\n\", fus->lfn, mg_get_errno()));\n      mg_printf(nc, \"Failed to open %s: %d\\n\", fus->lfn, mg_get_errno());\n      /* Do not close the connection just yet, discard remainder of the data.\n         * This is because at the time of writing some browsers (Chrome) fail to\n         * render response before all the data is sent. */\n    }\n    mp->user_data = (void *)fus;\n    break;\n  }\n  case MG_EV_HTTP_PART_DATA:\n  {\n    struct mg_http_multipart_part *mp =\n        (struct mg_http_multipart_part *)ev_data;\n    struct file_upload_state *fus =\n        (struct file_upload_state *)mp->user_data;\n    if (fus == NULL || fus->fp == NULL)\n      break;\n    if (fwrite(mp->data.p, 1, mp->data.len, fus->fp) != mp->data.len)\n    {\n      LOG(LL_ERROR, (\"Failed to write to %s: %d, wrote %d\", fus->lfn,\n                     mg_get_errno(), (int)fus->num_recd));\n      if (mg_get_errno() == ENOSPC\n#ifdef SPIFFS_ERR_FULL\n          || mg_get_errno() == SPIFFS_ERR_FULL\n#endif\n      )\n      {\n        mg_printf(nc,\n                  \"HTTP/1.1 413 Payload Too Large\\r\\n\"\n                  \"Content-Type: text/plain\\r\\n\"\n                  \"Connection: close\\r\\n\\r\\n\");\n        mg_printf(nc, \"Failed to write to %s: no space left; wrote %d\\r\\n\",\n                  fus->lfn, (int)fus->num_recd);\n      }\n      else\n      {\n        mg_printf(nc,\n                  \"HTTP/1.1 500 Internal Server Error\\r\\n\"\n                  \"Content-Type: text/plain\\r\\n\"\n                  \"Connection: close\\r\\n\\r\\n\");\n        mg_printf(nc, \"Failed to write to %s: %d, wrote %d\", mp->file_name,\n                  mg_get_errno(), (int)fus->num_recd);\n      }\n      fclose(fus->fp);\n      remove(fus->lfn);\n      fus->fp = NULL;\n      /* Do not close the connection just yet, discard remainder of the data.\n         * This is because at the time of writing some browsers (Chrome) fail to\n         * render response before all the data is sent. */\n      return;\n    }\n    fus->num_recd += mp->data.len;\n    LOG(LL_DEBUG, (\"%p rec'd %d bytes, %d total\", nc, (int)mp->data.len,\n                   (int)fus->num_recd));\n    break;\n  }\n  case MG_EV_HTTP_PART_END:\n  {\n    struct mg_http_multipart_part *mp =\n        (struct mg_http_multipart_part *)ev_data;\n    struct file_upload_state *fus =\n        (struct file_upload_state *)mp->user_data;\n    if (fus == NULL)\n      break;\n    if (mp->status >= 0 && fus->fp != NULL)\n    {\n      LOG(LL_DEBUG, (\"%p Uploaded %s (%s), %d bytes\", nc, mp->file_name,\n                     fus->lfn, (int)fus->num_recd));\n      mg_printf(nc,\n                \"HTTP/1.1 200 OK\\r\\n\"\n                \"Content-Type: text/plain\\r\\n\"\n                \"Connection: close\\r\\n\\r\\n\"\n                \"Ok, %s - %d bytes.\\r\\n\",\n                mp->file_name, (int)fus->num_recd);\n    }\n    else\n    {\n      LOG(LL_ERROR, (\"Failed to store %s (%s)\", mp->file_name, fus->lfn));\n      /*\n         * mp->status < 0 means connection was terminated, so no reason to send\n         * HTTP reply\n         */\n    }\n    if (fus->fp != NULL)\n      fclose(fus->fp);\n    free(fus->lfn);\n    free(fus);\n    mp->user_data = NULL;\n    nc->flags |= MG_F_SEND_AND_CLOSE;\n    break;\n  }\n  }\n}\n\n#endif /* MG_ENABLE_HTTP_STREAMING_MULTIPART */\n\nvoid mg_set_protocol_http_websocket(struct mg_connection *nc)\n{\n  nc->proto_handler = mg_http_handler;\n}\n\nconst char *mg_status_message(int status_code)\n{\n  switch (status_code)\n  {\n  case 206:\n    return \"Partial Content\";\n  case 301:\n    return \"Moved\";\n  case 302:\n    return \"Found\";\n  case 400:\n    return \"Bad Request\";\n  case 401:\n    return \"Unauthorized\";\n  case 403:\n    return \"Forbidden\";\n  case 404:\n    return \"Not Found\";\n  case 416:\n    return \"Requested range not satisfiable\";\n  case 418:\n    return \"I'm a teapot\";\n  case 500:\n    return \"Internal Server Error\";\n  case 502:\n    return \"Bad Gateway\";\n  case 503:\n    return \"Service Unavailable\";\n  default:\n    return \"OK\";\n  }\n}\n\nvoid mg_send_response_line_s(struct mg_connection *nc, int status_code,\n                             const struct mg_str extra_headers)\n{\n  mg_printf(nc, \"HTTP/1.1 %d %s\\r\\nServer: %s\\r\\n\", status_code,\n            mg_status_message(status_code), mg_version_header);\n  if (extra_headers.len > 0)\n  {\n    mg_printf(nc, \"%.*s\\r\\n\", (int)extra_headers.len, extra_headers.p);\n  }\n}\n\nvoid mg_send_response_line(struct mg_connection *nc, int status_code,\n                           const char *extra_headers)\n{\n  mg_send_response_line_s(nc, status_code, mg_mk_str(extra_headers));\n}\n\nvoid mg_http_send_redirect(struct mg_connection *nc, int status_code,\n                           const struct mg_str location,\n                           const struct mg_str extra_headers)\n{\n  char bbody[100], *pbody = bbody;\n  int bl = mg_asprintf(&pbody, sizeof(bbody),\n                       \"<p>Moved <a href='%.*s'>here</a>.\\r\\n\",\n                       (int)location.len, location.p);\n  char bhead[150], *phead = bhead;\n  mg_asprintf(&phead, sizeof(bhead),\n              \"Location: %.*s\\r\\n\"\n              \"Content-Type: text/html\\r\\n\"\n              \"Content-Length: %d\\r\\n\"\n              \"Cache-Control: no-cache\\r\\n\"\n              \"%.*s%s\",\n              (int)location.len, location.p, bl, (int)extra_headers.len,\n              extra_headers.p, (extra_headers.len > 0 ? \"\\r\\n\" : \"\"));\n  mg_send_response_line(nc, status_code, phead);\n  if (phead != bhead)\n    MG_FREE(phead);\n  mg_send(nc, pbody, bl);\n  if (pbody != bbody)\n    MG_FREE(pbody);\n}\n\nvoid mg_send_head(struct mg_connection *c, int status_code,\n                  int64_t content_length, const char *extra_headers)\n{\n  mg_send_response_line(c, status_code, extra_headers);\n  if (content_length < 0)\n  {\n    mg_printf(c, \"%s\", \"Transfer-Encoding: chunked\\r\\n\");\n  }\n  else\n  {\n    mg_printf(c, \"Content-Length: %\" INT64_FMT \"\\r\\n\", content_length);\n  }\n  mg_send(c, \"\\r\\n\", 2);\n}\n\nvoid mg_http_send_error(struct mg_connection *nc, int code,\n                        const char *reason)\n{\n  if (!reason)\n    reason = mg_status_message(code);\n  DBG((\"%p %d %s\", nc, code, reason));\n  mg_send_head(nc, code, strlen(reason),\n               \"Content-Type: text/plain\\r\\nConnection: close\");\n  mg_send(nc, reason, strlen(reason));\n  nc->flags |= MG_F_SEND_AND_CLOSE;\n}\n\n#if MG_ENABLE_FILESYSTEM\nstatic void mg_http_construct_etag(char *buf, size_t buf_len,\n                                   const cs_stat_t *st)\n{\n  snprintf(buf, buf_len, \"\\\"%lx.%\" INT64_FMT \"\\\"\", (unsigned long)st->st_mtime,\n           (int64_t)st->st_size);\n}\n\n#ifndef WINCE\nstatic void mg_gmt_time_string(char *buf, size_t buf_len, time_t *t)\n{\n  strftime(buf, buf_len, \"%a, %d %b %Y %H:%M:%S GMT\", gmtime(t));\n}\n#else\n/* Look wince_lib.c for WindowsCE implementation */\nstatic void mg_gmt_time_string(char *buf, size_t buf_len, time_t *t);\n#endif\n\nstatic int mg_http_parse_range_header(const struct mg_str *header, int64_t *a,\n                                      int64_t *b)\n{\n  /*\n   * There is no snscanf. Headers are not guaranteed to be NUL-terminated,\n   * so we have this. Ugh.\n   */\n  int result;\n  char *p = (char *)MG_MALLOC(header->len + 1);\n  if (p == NULL)\n    return 0;\n  memcpy(p, header->p, header->len);\n  p[header->len] = '\\0';\n  result = sscanf(p, \"bytes=%\" INT64_FMT \"-%\" INT64_FMT, a, b);\n  MG_FREE(p);\n  return result;\n}\n\nvoid mg_http_serve_file(struct mg_connection *nc, struct http_message *hm,\n                        const char *path, const struct mg_str mime_type,\n                        const struct mg_str extra_headers)\n{\n  struct mg_http_proto_data *pd = mg_http_get_proto_data(nc);\n  cs_stat_t st;\n  DBG((\"%p [%s] %.*s\", nc, path, (int)mime_type.len, mime_type.p));\n  if (mg_stat(path, &st) != 0 || (pd->file.fp = fopen(path, \"rb\")) == NULL)\n  {\n    int code, err = mg_get_errno();\n    switch (err)\n    {\n    case EACCES:\n      code = 403;\n      break;\n    case ENOENT:\n      code = 404;\n      break;\n    default:\n      code = 500;\n    };\n    mg_http_send_error(nc, code, \"Open failed\");\n  }\n  else\n  {\n    char etag[50], current_time[50], last_modified[50], range[70];\n    time_t t = (time_t)mg_time();\n    int64_t r1 = 0, r2 = 0, cl = st.st_size;\n    struct mg_str *range_hdr = mg_get_http_header(hm, \"Range\");\n    int n, status_code = 200;\n\n    /* Handle Range header */\n    range[0] = '\\0';\n    if (range_hdr != NULL &&\n        (n = mg_http_parse_range_header(range_hdr, &r1, &r2)) > 0 && r1 >= 0 &&\n        r2 >= 0)\n    {\n      /* If range is specified like \"400-\", set second limit to content len */\n      if (n == 1)\n      {\n        r2 = cl - 1;\n      }\n      if (r1 > r2 || r2 >= cl)\n      {\n        status_code = 416;\n        cl = 0;\n        snprintf(range, sizeof(range),\n                 \"Content-Range: bytes */%\" INT64_FMT \"\\r\\n\",\n                 (int64_t)st.st_size);\n      }\n      else\n      {\n        status_code = 206;\n        cl = r2 - r1 + 1;\n        snprintf(range, sizeof(range), \"Content-Range: bytes %\" INT64_FMT \"-%\" INT64_FMT \"/%\" INT64_FMT \"\\r\\n\",\n                 r1, r1 + cl - 1, (int64_t)st.st_size);\n#if _FILE_OFFSET_BITS == 64 || _POSIX_C_SOURCE >= 200112L || \\\n    _XOPEN_SOURCE >= 600\n        fseeko(pd->file.fp, r1, SEEK_SET);\n#else\n        fseek(pd->file.fp, (long)r1, SEEK_SET);\n#endif\n      }\n    }\n\n#if !MG_DISABLE_HTTP_KEEP_ALIVE\n    {\n      struct mg_str *conn_hdr = mg_get_http_header(hm, \"Connection\");\n      if (conn_hdr != NULL)\n      {\n        pd->file.keepalive = (mg_vcasecmp(conn_hdr, \"keep-alive\") == 0);\n      }\n      else\n      {\n        pd->file.keepalive = (mg_vcmp(&hm->proto, \"HTTP/1.1\") == 0);\n      }\n    }\n#endif\n\n    mg_http_construct_etag(etag, sizeof(etag), &st);\n    mg_gmt_time_string(current_time, sizeof(current_time), &t);\n    mg_gmt_time_string(last_modified, sizeof(last_modified), &st.st_mtime);\n    /*\n     * Content length casted to size_t because:\n     * 1) that's the maximum buffer size anyway\n     * 2) ESP8266 RTOS SDK newlib vprintf cannot contain a 64bit arg at non-last\n     *    position\n     * TODO(mkm): fix ESP8266 RTOS SDK\n     */\n    mg_send_response_line_s(nc, status_code, extra_headers);\n    mg_printf(nc,\n              \"Date: %s\\r\\n\"\n              \"Last-Modified: %s\\r\\n\"\n              \"Accept-Ranges: bytes\\r\\n\"\n              \"Content-Type: %.*s\\r\\n\"\n              \"Connection: %s\\r\\n\"\n              \"Content-Length: %\" SIZE_T_FMT\n              \"\\r\\n\"\n              \"%sEtag: %s\\r\\n\\r\\n\",\n              current_time, last_modified, (int)mime_type.len, mime_type.p,\n              (pd->file.keepalive ? \"keep-alive\" : \"close\"), (size_t)cl, range,\n              etag);\n\n    pd->file.cl = cl;\n    pd->file.type = DATA_FILE;\n    mg_http_transfer_file_data(nc);\n  }\n}\n\nstatic void mg_http_serve_file2(struct mg_connection *nc, const char *path,\n                                struct http_message *hm,\n                                struct mg_serve_http_opts *opts)\n{\n#if MG_ENABLE_HTTP_SSI\n  if (mg_match_prefix(opts->ssi_pattern, strlen(opts->ssi_pattern), path) > 0)\n  {\n    mg_handle_ssi_request(nc, hm, path, opts);\n    return;\n  }\n#endif\n  mg_http_serve_file(nc, hm, path, mg_get_mime_type(path, \"text/plain\", opts),\n                     mg_mk_str(opts->extra_headers));\n}\n\n#endif\n\nint mg_url_decode(const char *src, int src_len, char *dst, int dst_len,\n                  int is_form_url_encoded)\n{\n  int i, j, a, b;\n#define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'W')\n\n  for (i = j = 0; i < src_len && j < dst_len - 1; i++, j++)\n  {\n    if (src[i] == '%')\n    {\n      if (i < src_len - 2 && isxdigit(*(const unsigned char *)(src + i + 1)) &&\n          isxdigit(*(const unsigned char *)(src + i + 2)))\n      {\n        a = tolower(*(const unsigned char *)(src + i + 1));\n        b = tolower(*(const unsigned char *)(src + i + 2));\n        dst[j] = (char)((HEXTOI(a) << 4) | HEXTOI(b));\n        i += 2;\n      }\n      else\n      {\n        return -1;\n      }\n    }\n    else if (is_form_url_encoded && src[i] == '+')\n    {\n      dst[j] = ' ';\n    }\n    else\n    {\n      dst[j] = src[i];\n    }\n  }\n\n  dst[j] = '\\0'; /* Null-terminate the destination */\n\n  return i >= src_len ? j : -1;\n}\n\nint mg_get_http_var(const struct mg_str *buf, const char *name, char *dst,\n                    size_t dst_len)\n{\n  const char *p, *e, *s;\n  size_t name_len;\n  int len;\n\n  if (dst == NULL || dst_len == 0)\n  {\n    len = -2;\n  }\n  else if (buf->p == NULL || name == NULL || buf->len == 0)\n  {\n    len = -1;\n    dst[0] = '\\0';\n  }\n  else\n  {\n    name_len = strlen(name);\n    e = buf->p + buf->len;\n    len = -1;\n    dst[0] = '\\0';\n\n    for (p = buf->p; p + name_len < e; p++)\n    {\n      if ((p == buf->p || p[-1] == '&') && p[name_len] == '=' &&\n          !mg_ncasecmp(name, p, name_len))\n      {\n        p += name_len + 1;\n        s = (const char *)memchr(p, '&', (size_t)(e - p));\n        if (s == NULL)\n        {\n          s = e;\n        }\n        len = mg_url_decode(p, (size_t)(s - p), dst, dst_len, 1);\n        if (len == -1)\n        {\n          len = -2;\n        }\n        break;\n      }\n    }\n  }\n\n  return len;\n}\n\nvoid mg_send_http_chunk(struct mg_connection *nc, const char *buf, size_t len)\n{\n  char chunk_size[50];\n  int n;\n\n  n = snprintf(chunk_size, sizeof(chunk_size), \"%lX\\r\\n\", (unsigned long)len);\n  mg_send(nc, chunk_size, n);\n  mg_send(nc, buf, len);\n  mg_send(nc, \"\\r\\n\", 2);\n}\n\nvoid mg_printf_http_chunk(struct mg_connection *nc, const char *fmt, ...)\n{\n  char mem[MG_VPRINTF_BUFFER_SIZE], *buf = mem;\n  int len;\n  va_list ap;\n\n  va_start(ap, fmt);\n  len = mg_avprintf(&buf, sizeof(mem), fmt, ap);\n  va_end(ap);\n\n  if (len >= 0)\n  {\n    mg_send_http_chunk(nc, buf, len);\n  }\n\n  /* LCOV_EXCL_START */\n  if (buf != mem && buf != NULL)\n  {\n    MG_FREE(buf);\n  }\n  /* LCOV_EXCL_STOP */\n}\n\nvoid mg_printf_html_escape(struct mg_connection *nc, const char *fmt, ...)\n{\n  char mem[MG_VPRINTF_BUFFER_SIZE], *buf = mem;\n  int i, j, len;\n  va_list ap;\n\n  va_start(ap, fmt);\n  len = mg_avprintf(&buf, sizeof(mem), fmt, ap);\n  va_end(ap);\n\n  if (len >= 0)\n  {\n    for (i = j = 0; i < len; i++)\n    {\n      if (buf[i] == '<' || buf[i] == '>')\n      {\n        mg_send(nc, buf + j, i - j);\n        mg_send(nc, buf[i] == '<' ? \"&lt;\" : \"&gt;\", 4);\n        j = i + 1;\n      }\n    }\n    mg_send(nc, buf + j, i - j);\n  }\n\n  /* LCOV_EXCL_START */\n  if (buf != mem && buf != NULL)\n  {\n    MG_FREE(buf);\n  }\n  /* LCOV_EXCL_STOP */\n}\n\nint mg_http_parse_header(struct mg_str *hdr, const char *var_name, char *buf,\n                         size_t buf_size)\n{\n  int ch = ' ', ch1 = ',', len = 0, n = strlen(var_name);\n  const char *p, *end = hdr ? hdr->p + hdr->len : NULL, *s = NULL;\n\n  if (buf != NULL && buf_size > 0)\n    buf[0] = '\\0';\n  if (hdr == NULL)\n    return 0;\n\n  /* Find where variable starts */\n  for (s = hdr->p; s != NULL && s + n < end; s++)\n  {\n    if ((s == hdr->p || s[-1] == ch || s[-1] == ch1) && s[n] == '=' &&\n        !memcmp(s, var_name, n))\n      break;\n  }\n\n  if (s != NULL && &s[n + 1] < end)\n  {\n    s += n + 1;\n    if (*s == '\"' || *s == '\\'')\n    {\n      ch = ch1 = *s++;\n    }\n    p = s;\n    while (p < end && p[0] != ch && p[0] != ch1 && len < (int)buf_size)\n    {\n      if (ch != ' ' && p[0] == '\\\\' && p[1] == ch)\n        p++;\n      buf[len++] = *p++;\n    }\n    if (len >= (int)buf_size || (ch != ' ' && *p != ch))\n    {\n      len = 0;\n    }\n    else\n    {\n      if (len > 0 && s[len - 1] == ',')\n        len--;\n      if (len > 0 && s[len - 1] == ';')\n        len--;\n      buf[len] = '\\0';\n    }\n  }\n\n  return len;\n}\n\nint mg_get_http_basic_auth(struct http_message *hm, char *user, size_t user_len,\n                           char *pass, size_t pass_len)\n{\n  struct mg_str *hdr = mg_get_http_header(hm, \"Authorization\");\n  if (hdr == NULL)\n    return -1;\n  return mg_parse_http_basic_auth(hdr, user, user_len, pass, pass_len);\n}\n\nint mg_parse_http_basic_auth(struct mg_str *hdr, char *user, size_t user_len,\n                             char *pass, size_t pass_len)\n{\n  char *buf = NULL;\n  char fmt[64];\n  int res = 0;\n\n  if (mg_strncmp(*hdr, mg_mk_str(\"Basic \"), 6) != 0)\n    return -1;\n\n  buf = (char *)MG_MALLOC(hdr->len);\n  cs_base64_decode((unsigned char *)hdr->p + 6, hdr->len, buf);\n\n  /* e.g. \"%123[^:]:%321[^\\n]\" */\n  snprintf(fmt, sizeof(fmt), \"%%%\" SIZE_T_FMT \"[^:]:%%%\" SIZE_T_FMT \"[^\\n]\",\n           user_len - 1, pass_len - 1);\n  if (sscanf(buf, fmt, user, pass) == 0)\n  {\n    res = -1;\n  }\n\n  MG_FREE(buf);\n  return res;\n}\n\n#if MG_ENABLE_FILESYSTEM\nstatic int mg_is_file_hidden(const char *path,\n                             const struct mg_serve_http_opts *opts,\n                             int exclude_specials)\n{\n  const char *p1 = opts->per_directory_auth_file;\n  const char *p2 = opts->hidden_file_pattern;\n\n  /* Strip directory path from the file name */\n  const char *pdir = strrchr(path, DIRSEP);\n  if (pdir != NULL)\n  {\n    path = pdir + 1;\n  }\n\n  return (exclude_specials && (!strcmp(path, \".\") || !strcmp(path, \"..\"))) ||\n         (p1 != NULL &&\n          mg_match_prefix(p1, strlen(p1), path) == (int)strlen(p1)) ||\n         (p2 != NULL && mg_match_prefix(p2, strlen(p2), path) > 0);\n}\n\n#if !MG_DISABLE_HTTP_DIGEST_AUTH\nstatic void mg_mkmd5resp(const char *method, size_t method_len, const char *uri,\n                         size_t uri_len, const char *ha1, size_t ha1_len,\n                         const char *nonce, size_t nonce_len, const char *nc,\n                         size_t nc_len, const char *cnonce, size_t cnonce_len,\n                         const char *qop, size_t qop_len, char *resp)\n{\n  static const char colon[] = \":\";\n  static const size_t one = 1;\n  char ha2[33];\n\n  cs_md5(ha2, method, method_len, colon, one, uri, uri_len, NULL);\n  cs_md5(resp, ha1, ha1_len, colon, one, nonce, nonce_len, colon, one, nc,\n         nc_len, colon, one, cnonce, cnonce_len, colon, one, qop, qop_len,\n         colon, one, ha2, sizeof(ha2) - 1, NULL);\n}\n\nint mg_http_create_digest_auth_header(char *buf, size_t buf_len,\n                                      const char *method, const char *uri,\n                                      const char *auth_domain, const char *user,\n                                      const char *passwd)\n{\n  static const char colon[] = \":\", qop[] = \"auth\";\n  static const size_t one = 1;\n  char ha1[33], resp[33], cnonce[40];\n\n  snprintf(cnonce, sizeof(cnonce), \"%x\", (unsigned int)mg_time());\n  cs_md5(ha1, user, (size_t)strlen(user), colon, one, auth_domain,\n         (size_t)strlen(auth_domain), colon, one, passwd,\n         (size_t)strlen(passwd), NULL);\n  mg_mkmd5resp(method, strlen(method), uri, strlen(uri), ha1, sizeof(ha1) - 1,\n               cnonce, strlen(cnonce), \"1\", one, cnonce, strlen(cnonce), qop,\n               sizeof(qop) - 1, resp);\n  return snprintf(buf, buf_len,\n                  \"Authorization: Digest username=\\\"%s\\\",\"\n                  \"realm=\\\"%s\\\",uri=\\\"%s\\\",qop=%s,nc=1,cnonce=%s,\"\n                  \"nonce=%s,response=%s\\r\\n\",\n                  user, auth_domain, uri, qop, cnonce, cnonce, resp);\n}\n\n/*\n * Check for authentication timeout.\n * Clients send time stamp encoded in nonce. Make sure it is not too old,\n * to prevent replay attacks.\n * Assumption: nonce is a hexadecimal number of seconds since 1970.\n */\nstatic int mg_check_nonce(const char *nonce)\n{\n  unsigned long now = (unsigned long)mg_time();\n  unsigned long val = (unsigned long)strtoul(nonce, NULL, 16);\n  return now < val || now - val < 3600;\n}\n\nint mg_http_check_digest_auth(struct http_message *hm, const char *auth_domain,\n                              FILE *fp)\n{\n  struct mg_str *hdr;\n  char buf[128], f_user[sizeof(buf)], f_ha1[sizeof(buf)], f_domain[sizeof(buf)];\n  char user[50], cnonce[33], response[40], uri[200], qop[20], nc[20], nonce[30];\n  char expected_response[33];\n\n  /* Parse \"Authorization:\" header, fail fast on parse error */\n  if (hm == NULL || fp == NULL ||\n      (hdr = mg_get_http_header(hm, \"Authorization\")) == NULL ||\n      mg_http_parse_header(hdr, \"username\", user, sizeof(user)) == 0 ||\n      mg_http_parse_header(hdr, \"cnonce\", cnonce, sizeof(cnonce)) == 0 ||\n      mg_http_parse_header(hdr, \"response\", response, sizeof(response)) == 0 ||\n      mg_http_parse_header(hdr, \"uri\", uri, sizeof(uri)) == 0 ||\n      mg_http_parse_header(hdr, \"qop\", qop, sizeof(qop)) == 0 ||\n      mg_http_parse_header(hdr, \"nc\", nc, sizeof(nc)) == 0 ||\n      mg_http_parse_header(hdr, \"nonce\", nonce, sizeof(nonce)) == 0 ||\n      mg_check_nonce(nonce) == 0)\n  {\n    return 0;\n  }\n\n  /*\n   * Read passwords file line by line. If should have htdigest format,\n   * i.e. each line should be a colon-separated sequence:\n   * USER_NAME:DOMAIN_NAME:HA1_HASH_OF_USER_DOMAIN_AND_PASSWORD\n   */\n  while (fgets(buf, sizeof(buf), fp) != NULL)\n  {\n    if (sscanf(buf, \"%[^:]:%[^:]:%s\", f_user, f_domain, f_ha1) == 3 &&\n        strcmp(user, f_user) == 0 &&\n        /* NOTE(lsm): due to a bug in MSIE, we do not compare URIs */\n        strcmp(auth_domain, f_domain) == 0)\n    {\n      /* User and domain matched, check the password */\n      mg_mkmd5resp(\n          hm->method.p, hm->method.len, hm->uri.p,\n          hm->uri.len + (hm->query_string.len ? hm->query_string.len + 1 : 0),\n          f_ha1, strlen(f_ha1), nonce, strlen(nonce), nc, strlen(nc), cnonce,\n          strlen(cnonce), qop, strlen(qop), expected_response);\n      return mg_casecmp(response, expected_response) == 0;\n    }\n  }\n\n  /* None of the entries in the passwords file matched - return failure */\n  return 0;\n}\n\nstatic int mg_is_authorized(struct http_message *hm, const char *path,\n                            int is_directory, const char *domain,\n                            const char *passwords_file,\n                            int is_global_pass_file)\n{\n  char buf[MG_MAX_PATH];\n  const char *p;\n  FILE *fp;\n  int authorized = 1;\n\n  if (domain != NULL && passwords_file != NULL)\n  {\n    if (is_global_pass_file)\n    {\n      fp = fopen(passwords_file, \"r\");\n    }\n    else if (is_directory)\n    {\n      snprintf(buf, sizeof(buf), \"%s%c%s\", path, DIRSEP, passwords_file);\n      fp = fopen(buf, \"r\");\n    }\n    else\n    {\n      p = strrchr(path, DIRSEP);\n      if (p == NULL)\n        p = path;\n      snprintf(buf, sizeof(buf), \"%.*s%c%s\", (int)(p - path), path, DIRSEP,\n               passwords_file);\n      fp = fopen(buf, \"r\");\n    }\n\n    if (fp != NULL)\n    {\n      authorized = mg_http_check_digest_auth(hm, domain, fp);\n      fclose(fp);\n    }\n  }\n\n  DBG((\"%s %s %d %d\", path, passwords_file ? passwords_file : \"\",\n       is_global_pass_file, authorized));\n  return authorized;\n}\n#else\nstatic int mg_is_authorized(struct http_message *hm, const char *path,\n                            int is_directory, const char *domain,\n                            const char *passwords_file,\n                            int is_global_pass_file)\n{\n  (void)hm;\n  (void)path;\n  (void)is_directory;\n  (void)domain;\n  (void)passwords_file;\n  (void)is_global_pass_file;\n  return 1;\n}\n#endif\n\n#if MG_ENABLE_DIRECTORY_LISTING\nstatic size_t mg_url_encode(const char *src, size_t s_len, char *dst,\n                            size_t dst_len)\n{\n  static const char *dont_escape = \"._-$,;~()/\";\n  static const char *hex = \"0123456789abcdef\";\n  size_t i = 0, j = 0;\n\n  for (i = j = 0; dst_len > 0 && i < s_len && j + 2 < dst_len - 1; i++, j++)\n  {\n    if (isalnum(*(const unsigned char *)(src + i)) ||\n        strchr(dont_escape, *(const unsigned char *)(src + i)) != NULL)\n    {\n      dst[j] = src[i];\n    }\n    else if (j + 3 < dst_len)\n    {\n      dst[j] = '%';\n      dst[j + 1] = hex[(*(const unsigned char *)(src + i)) >> 4];\n      dst[j + 2] = hex[(*(const unsigned char *)(src + i)) & 0xf];\n      j += 2;\n    }\n  }\n\n  dst[j] = '\\0';\n  return j;\n}\n\nstatic void mg_escape(const char *src, char *dst, size_t dst_len)\n{\n  size_t n = 0;\n  while (*src != '\\0' && n + 5 < dst_len)\n  {\n    unsigned char ch = *(unsigned char *)src++;\n    if (ch == '<')\n    {\n      n += snprintf(dst + n, dst_len - n, \"%s\", \"&lt;\");\n    }\n    else\n    {\n      dst[n++] = ch;\n    }\n  }\n  dst[n] = '\\0';\n}\n\nstatic void mg_print_dir_entry(struct mg_connection *nc, const char *file_name,\n                               cs_stat_t *stp)\n{\n  char size[64], mod[64], href[MAX_PATH_SIZE * 3], path[MAX_PATH_SIZE];\n  int64_t fsize = stp->st_size;\n  int is_dir = S_ISDIR(stp->st_mode);\n  const char *slash = is_dir ? \"/\" : \"\";\n\n  if (is_dir)\n  {\n    snprintf(size, sizeof(size), \"%s\", \"[DIRECTORY]\");\n  }\n  else\n  {\n    /*\n     * We use (double) cast below because MSVC 6 compiler cannot\n     * convert unsigned __int64 to double.\n     */\n    if (fsize < 1024)\n    {\n      snprintf(size, sizeof(size), \"%d\", (int)fsize);\n    }\n    else if (fsize < 0x100000)\n    {\n      snprintf(size, sizeof(size), \"%.1fk\", (double)fsize / 1024.0);\n    }\n    else if (fsize < 0x40000000)\n    {\n      snprintf(size, sizeof(size), \"%.1fM\", (double)fsize / 1048576);\n    }\n    else\n    {\n      snprintf(size, sizeof(size), \"%.1fG\", (double)fsize / 1073741824);\n    }\n  }\n  strftime(mod, sizeof(mod), \"%d-%b-%Y %H:%M\", localtime(&stp->st_mtime));\n  mg_escape(file_name, path, sizeof(path));\n  mg_url_encode(file_name, strlen(file_name), href, sizeof(href));\n  mg_printf_http_chunk(nc,\n                       \"<tr><td><a href=\\\"%s%s\\\">%s%s</a></td>\"\n                       \"<td>%s</td><td name=%\" INT64_FMT \">%s</td></tr>\\n\",\n                       href, slash, path, slash, mod, is_dir ? -1 : fsize,\n                       size);\n}\n\nstatic void mg_scan_directory(struct mg_connection *nc, const char *dir,\n                              const struct mg_serve_http_opts *opts,\n                              void (*func)(struct mg_connection *, const char *,\n                                           cs_stat_t *))\n{\n  char path[MAX_PATH_SIZE];\n  cs_stat_t st;\n  struct dirent *dp;\n  DIR *dirp;\n\n  DBG((\"%p [%s]\", nc, dir));\n  if ((dirp = (opendir(dir))) != NULL)\n  {\n    while ((dp = readdir(dirp)) != NULL)\n    {\n      /* Do not show current dir and hidden files */\n      if (mg_is_file_hidden((const char *)dp->d_name, opts, 1))\n      {\n        continue;\n      }\n      snprintf(path, sizeof(path), \"%s/%s\", dir, dp->d_name);\n      if (mg_stat(path, &st) == 0)\n      {\n        func(nc, (const char *)dp->d_name, &st);\n      }\n    }\n    closedir(dirp);\n  }\n  else\n  {\n    DBG((\"%p opendir(%s) -> %d\", nc, dir, mg_get_errno()));\n  }\n}\n\nstatic void mg_send_directory_listing(struct mg_connection *nc, const char *dir,\n                                      struct http_message *hm,\n                                      struct mg_serve_http_opts *opts)\n{\n  static const char *sort_js_code =\n      \"<script>function srt(tb, sc, so, d) {\"\n      \"var tr = Array.prototype.slice.call(tb.rows, 0),\"\n      \"tr = tr.sort(function (a, b) { var c1 = a.cells[sc], c2 = b.cells[sc],\"\n      \"n1 = c1.getAttribute('name'), n2 = c2.getAttribute('name'), \"\n      \"t1 = a.cells[2].getAttribute('name'), \"\n      \"t2 = b.cells[2].getAttribute('name'); \"\n      \"return so * (t1 < 0 && t2 >= 0 ? -1 : t2 < 0 && t1 >= 0 ? 1 : \"\n      \"n1 ? parseInt(n2) - parseInt(n1) : \"\n      \"c1.textContent.trim().localeCompare(c2.textContent.trim())); });\";\n  static const char *sort_js_code2 =\n      \"for (var i = 0; i < tr.length; i++) tb.appendChild(tr[i]); \"\n      \"if (!d) window.location.hash = ('sc=' + sc + '&so=' + so); \"\n      \"};\"\n      \"window.onload = function() {\"\n      \"var tb = document.getElementById('tb');\"\n      \"var m = /sc=([012]).so=(1|-1)/.exec(window.location.hash) || [0, 2, 1];\"\n      \"var sc = m[1], so = m[2]; document.onclick = function(ev) { \"\n      \"var c = ev.target.rel; if (c) {if (c == sc) so *= -1; srt(tb, c, so); \"\n      \"sc = c; ev.preventDefault();}};\"\n      \"srt(tb, sc, so, true);\"\n      \"}\"\n      \"</script>\";\n\n  mg_send_response_line(nc, 200, opts->extra_headers);\n  mg_printf(nc, \"%s: %s\\r\\n%s: %s\\r\\n\\r\\n\", \"Transfer-Encoding\", \"chunked\",\n            \"Content-Type\", \"text/html; charset=utf-8\");\n\n  mg_printf_http_chunk(\n      nc,\n      \"<html><head><title>Index of %.*s</title>%s%s\"\n      \"<style>th,td {text-align: left; padding-right: 1em; \"\n      \"font-family: monospace; }</style></head>\\n\"\n      \"<body><h1>Index of %.*s</h1>\\n<table cellpadding=0><thead>\"\n      \"<tr><th><a href=# rel=0>Name</a></th><th>\"\n      \"<a href=# rel=1>Modified</a</th>\"\n      \"<th><a href=# rel=2>Size</a></th></tr>\"\n      \"<tr><td colspan=3><hr></td></tr>\\n\"\n      \"</thead>\\n\"\n      \"<tbody id=tb>\",\n      (int)hm->uri.len, hm->uri.p, sort_js_code, sort_js_code2,\n      (int)hm->uri.len, hm->uri.p);\n  mg_scan_directory(nc, dir, opts, mg_print_dir_entry);\n  mg_printf_http_chunk(nc,\n                       \"</tbody><tr><td colspan=3><hr></td></tr>\\n\"\n                       \"</table>\\n\"\n                       \"<address>%s</address>\\n\"\n                       \"</body></html>\",\n                       mg_version_header);\n  mg_send_http_chunk(nc, \"\", 0);\n  /* TODO(rojer): Remove when cesanta/dev/issues/197 is fixed. */\n  nc->flags |= MG_F_SEND_AND_CLOSE;\n}\n#endif /* MG_ENABLE_DIRECTORY_LISTING */\n\n/*\n * Given a directory path, find one of the files specified in the\n * comma-separated list of index files `list`.\n * First found index file wins. If an index file is found, then gets\n * appended to the `path`, stat-ed, and result of `stat()` passed to `stp`.\n * If index file is not found, then `path` and `stp` remain unchanged.\n */\nMG_INTERNAL void mg_find_index_file(const char *path, const char *list,\n                                    char **index_file, cs_stat_t *stp)\n{\n  struct mg_str vec;\n  size_t path_len = strlen(path);\n  int found = 0;\n  *index_file = NULL;\n\n  /* Traverse index files list. For each entry, append it to the given */\n  /* path and see if the file exists. If it exists, break the loop */\n  while ((list = mg_next_comma_list_entry(list, &vec, NULL)) != NULL)\n  {\n    cs_stat_t st;\n    size_t len = path_len + 1 + vec.len + 1;\n    *index_file = (char *)MG_REALLOC(*index_file, len);\n    if (*index_file == NULL)\n      break;\n    snprintf(*index_file, len, \"%s%c%.*s\", path, DIRSEP, (int)vec.len, vec.p);\n\n    /* Does it exist? Is it a file? */\n    if (mg_stat(*index_file, &st) == 0 && S_ISREG(st.st_mode))\n    {\n      /* Yes it does, break the loop */\n      *stp = st;\n      found = 1;\n      break;\n    }\n  }\n  if (!found)\n  {\n    MG_FREE(*index_file);\n    *index_file = NULL;\n  }\n  DBG((\"[%s] [%s]\", path, (*index_file ? *index_file : \"\")));\n}\n\n#if MG_ENABLE_HTTP_URL_REWRITES\nstatic int mg_http_send_port_based_redirect(\n    struct mg_connection *c, struct http_message *hm,\n    const struct mg_serve_http_opts *opts)\n{\n  const char *rewrites = opts->url_rewrites;\n  struct mg_str a, b;\n  char local_port[20] = {'%'};\n\n  mg_conn_addr_to_str(c, local_port + 1, sizeof(local_port) - 1,\n                      MG_SOCK_STRINGIFY_PORT);\n\n  while ((rewrites = mg_next_comma_list_entry(rewrites, &a, &b)) != NULL)\n  {\n    if (mg_vcmp(&a, local_port) == 0)\n    {\n      mg_send_response_line(c, 301, NULL);\n      mg_printf(c, \"Content-Length: 0\\r\\nLocation: %.*s%.*s\\r\\n\\r\\n\",\n                (int)b.len, b.p, (int)(hm->proto.p - hm->uri.p - 1),\n                hm->uri.p);\n      return 1;\n    }\n  }\n\n  return 0;\n}\n\nstatic void mg_reverse_proxy_handler(struct mg_connection *nc, int ev,\n                                     void *ev_data)\n{\n  struct http_message *hm = (struct http_message *)ev_data;\n  struct mg_connection *upstream = (struct mg_connection *)nc->user_data;\n\n  switch (ev)\n  {\n  case MG_EV_CONNECT:\n    if (*(int *)ev_data != 0)\n    {\n      mg_http_send_error(upstream, 502, NULL);\n    }\n    break;\n  /* TODO(mkm): handle streaming */\n  case MG_EV_HTTP_REPLY:\n    mg_send(upstream, hm->message.p, hm->message.len);\n    upstream->flags |= MG_F_SEND_AND_CLOSE;\n    nc->flags |= MG_F_CLOSE_IMMEDIATELY;\n    break;\n  case MG_EV_CLOSE:\n    upstream->flags |= MG_F_SEND_AND_CLOSE;\n    break;\n  }\n}\n\nvoid mg_http_reverse_proxy(struct mg_connection *nc,\n                           const struct http_message *hm, struct mg_str mount,\n                           struct mg_str upstream)\n{\n  struct mg_connection *be;\n  char burl[256], *purl = burl;\n  char *addr = NULL;\n  const char *path = NULL;\n  int i;\n  const char *error;\n  struct mg_connect_opts opts;\n  memset(&opts, 0, sizeof(opts));\n  opts.error_string = &error;\n\n  mg_asprintf(&purl, sizeof(burl), \"%.*s%.*s\", (int)upstream.len, upstream.p,\n              (int)(hm->uri.len - mount.len), hm->uri.p + mount.len);\n\n  be = mg_connect_http_base(nc->mgr, mg_reverse_proxy_handler, opts, \"http://\",\n                            \"https://\", purl, &path, NULL /* user */,\n                            NULL /* pass */, &addr);\n  DBG((\"Proxying %.*s to %s (rule: %.*s)\", (int)hm->uri.len, hm->uri.p, purl,\n       (int)mount.len, mount.p));\n\n  if (be == NULL)\n  {\n    LOG(LL_ERROR, (\"Error connecting to %s: %s\", purl, error));\n    mg_http_send_error(nc, 502, NULL);\n    goto cleanup;\n  }\n  be->user_data = nc;\n\n  /* send request upstream */\n  mg_printf(be, \"%.*s %s HTTP/1.1\\r\\n\", (int)hm->method.len, hm->method.p,\n            path);\n\n  mg_printf(be, \"Host: %s\\r\\n\", addr);\n  for (i = 0; i < MG_MAX_HTTP_HEADERS && hm->header_names[i].len > 0; i++)\n  {\n    struct mg_str hn = hm->header_names[i];\n    struct mg_str hv = hm->header_values[i];\n\n    /* we rewrite the host header */\n    if (mg_vcasecmp(&hn, \"Host\") == 0)\n      continue;\n    /*\n     * Don't pass chunked transfer encoding to the client because hm->body is\n     * already dechunked when we arrive here.\n     */\n    if (mg_vcasecmp(&hn, \"Transfer-encoding\") == 0 &&\n        mg_vcasecmp(&hv, \"chunked\") == 0)\n    {\n      mg_printf(be, \"Content-Length: %\" SIZE_T_FMT \"\\r\\n\", hm->body.len);\n      continue;\n    }\n    /* We don't support proxying Expect: 100-continue. */\n    if (mg_vcasecmp(&hn, \"Expect\") == 0 &&\n        mg_vcasecmp(&hv, \"100-continue\") == 0)\n    {\n      continue;\n    }\n\n    mg_printf(be, \"%.*s: %.*s\\r\\n\", (int)hn.len, hn.p, (int)hv.len, hv.p);\n  }\n\n  mg_send(be, \"\\r\\n\", 2);\n  mg_send(be, hm->body.p, hm->body.len);\n\ncleanup:\n  if (purl != burl)\n    MG_FREE(purl);\n}\n\nstatic int mg_http_handle_forwarding(struct mg_connection *nc,\n                                     struct http_message *hm,\n                                     const struct mg_serve_http_opts *opts)\n{\n  const char *rewrites = opts->url_rewrites;\n  struct mg_str a, b;\n  struct mg_str p1 = MG_MK_STR(\"http://\"), p2 = MG_MK_STR(\"https://\");\n\n  while ((rewrites = mg_next_comma_list_entry(rewrites, &a, &b)) != NULL)\n  {\n    if (mg_strncmp(a, hm->uri, a.len) == 0)\n    {\n      if (mg_strncmp(b, p1, p1.len) == 0 || mg_strncmp(b, p2, p2.len) == 0)\n      {\n        mg_http_reverse_proxy(nc, hm, a, b);\n        return 1;\n      }\n    }\n  }\n\n  return 0;\n}\n#endif\n\nMG_INTERNAL int mg_uri_to_local_path(struct http_message *hm,\n                                     const struct mg_serve_http_opts *opts,\n                                     char **local_path,\n                                     struct mg_str *remainder)\n{\n  int ok = 1;\n  const char *cp = hm->uri.p, *cp_end = hm->uri.p + hm->uri.len;\n  struct mg_str root = {NULL, 0};\n  const char *file_uri_start = cp;\n  *local_path = NULL;\n  remainder->p = NULL;\n  remainder->len = 0;\n\n  { /* 1. Determine which root to use. */\n\n#if MG_ENABLE_HTTP_URL_REWRITES\n    const char *rewrites = opts->url_rewrites;\n#else\n    const char *rewrites = \"\";\n#endif\n    struct mg_str *hh = mg_get_http_header(hm, \"Host\");\n    struct mg_str a, b;\n    /* Check rewrites first. */\n    while ((rewrites = mg_next_comma_list_entry(rewrites, &a, &b)) != NULL)\n    {\n      if (a.len > 1 && a.p[0] == '@')\n      {\n        /* Host rewrite. */\n        if (hh != NULL && hh->len == a.len - 1 &&\n            mg_ncasecmp(a.p + 1, hh->p, a.len - 1) == 0)\n        {\n          root = b;\n          break;\n        }\n      }\n      else\n      {\n        /* Regular rewrite, URI=directory */\n        int match_len = mg_match_prefix_n(a, hm->uri);\n        if (match_len > 0)\n        {\n          file_uri_start = hm->uri.p + match_len;\n          if (*file_uri_start == '/' || file_uri_start == cp_end)\n          {\n            /* Match ended at component boundary, ok. */\n          }\n          else if (*(file_uri_start - 1) == '/')\n          {\n            /* Pattern ends with '/', backtrack. */\n            file_uri_start--;\n          }\n          else\n          {\n            /* No match: must fall on the component boundary. */\n            continue;\n          }\n          root = b;\n          break;\n        }\n      }\n    }\n    /* If no rewrite rules matched, use DAV or regular document root. */\n    if (root.p == NULL)\n    {\n#if MG_ENABLE_HTTP_WEBDAV\n      if (opts->dav_document_root != NULL && mg_is_dav_request(&hm->method))\n      {\n        root.p = opts->dav_document_root;\n        root.len = strlen(opts->dav_document_root);\n      }\n      else\n#endif\n      {\n        root.p = opts->document_root;\n        root.len = strlen(opts->document_root);\n      }\n    }\n    assert(root.p != NULL && root.len > 0);\n  }\n\n  { /* 2. Find where in the canonical URI path the local path ends. */\n    const char *u = file_uri_start + 1;\n    char *lp = (char *)MG_MALLOC(root.len + hm->uri.len + 1);\n    char *lp_end = lp + root.len + hm->uri.len + 1;\n    char *p = lp, *ps;\n    int exists = 1;\n    if (lp == NULL)\n    {\n      ok = 0;\n      goto out;\n    }\n    memcpy(p, root.p, root.len);\n    p += root.len;\n    if (*(p - 1) == DIRSEP)\n      p--;\n    *p = '\\0';\n    ps = p;\n\n    /* Chop off URI path components one by one and build local path. */\n    while (u <= cp_end)\n    {\n      const char *next = u;\n      struct mg_str component;\n      if (exists)\n      {\n        cs_stat_t st;\n        exists = (mg_stat(lp, &st) == 0);\n        if (exists && S_ISREG(st.st_mode))\n        {\n          /* We found the terminal, the rest of the URI (if any) is path_info.\n           */\n          if (*(u - 1) == '/')\n            u--;\n          break;\n        }\n      }\n      if (u >= cp_end)\n        break;\n      parse_uri_component((const char **)&next, cp_end, '/', &component);\n      if (component.len > 0)\n      {\n        int len;\n        memmove(p + 1, component.p, component.len);\n        len = mg_url_decode(p + 1, component.len, p + 1, lp_end - p - 1, 0);\n        if (len <= 0)\n        {\n          ok = 0;\n          break;\n        }\n        component.p = p + 1;\n        component.len = len;\n        if (mg_vcmp(&component, \".\") == 0)\n        {\n          /* Yum. */\n        }\n        else if (mg_vcmp(&component, \"..\") == 0)\n        {\n          while (p > ps && *p != DIRSEP)\n            p--;\n          *p = '\\0';\n        }\n        else\n        {\n          size_t i;\n#ifdef _WIN32\n          /* On Windows, make sure it's valid Unicode (no funny stuff). */\n          wchar_t buf[MG_MAX_PATH * 2];\n          if (to_wchar(component.p, buf, MG_MAX_PATH) == 0)\n          {\n            DBG((\"[%.*s] smells funny\", (int)component.len, component.p));\n            ok = 0;\n            break;\n          }\n#endif\n          *p++ = DIRSEP;\n          /* No NULs and DIRSEPs in the component (percent-encoded). */\n          for (i = 0; i < component.len; i++, p++)\n          {\n            if (*p == '\\0' || *p == DIRSEP\n#ifdef _WIN32\n                /* On Windows, \"/\" is also accepted, so check for that too. */\n                ||\n                *p == '/'\n#endif\n            )\n            {\n              ok = 0;\n              break;\n            }\n          }\n        }\n      }\n      u = next;\n    }\n    if (ok)\n    {\n      *local_path = lp;\n      if (u > cp_end)\n        u = cp_end;\n      remainder->p = u;\n      remainder->len = cp_end - u;\n    }\n    else\n    {\n      MG_FREE(lp);\n    }\n  }\n\nout:\n  DBG((\"'%.*s' -> '%s' + '%.*s'\", (int)hm->uri.len, hm->uri.p,\n       *local_path ? *local_path : \"\", (int)remainder->len, remainder->p));\n  return ok;\n}\n\nstatic int mg_get_month_index(const char *s)\n{\n  static const char *month_names[] = {\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\",\n                                      \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"};\n  size_t i;\n\n  for (i = 0; i < ARRAY_SIZE(month_names); i++)\n    if (!strcmp(s, month_names[i]))\n      return (int)i;\n\n  return -1;\n}\n\nstatic int mg_num_leap_years(int year)\n{\n  return year / 4 - year / 100 + year / 400;\n}\n\n/* Parse UTC date-time string, and return the corresponding time_t value. */\nMG_INTERNAL time_t mg_parse_date_string(const char *datetime)\n{\n  static const unsigned short days_before_month[] = {\n      0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};\n  char month_str[32];\n  int second, minute, hour, day, month, year, leap_days, days;\n  time_t result = (time_t)0;\n\n  if (((sscanf(datetime, \"%d/%3s/%d %d:%d:%d\", &day, month_str, &year, &hour,\n               &minute, &second) == 6) ||\n       (sscanf(datetime, \"%d %3s %d %d:%d:%d\", &day, month_str, &year, &hour,\n               &minute, &second) == 6) ||\n       (sscanf(datetime, \"%*3s, %d %3s %d %d:%d:%d\", &day, month_str, &year,\n               &hour, &minute, &second) == 6) ||\n       (sscanf(datetime, \"%d-%3s-%d %d:%d:%d\", &day, month_str, &year, &hour,\n               &minute, &second) == 6)) &&\n      year > 1970 && (month = mg_get_month_index(month_str)) != -1)\n  {\n    leap_days = mg_num_leap_years(year) - mg_num_leap_years(1970);\n    year -= 1970;\n    days = year * 365 + days_before_month[month] + (day - 1) + leap_days;\n    result = days * 24 * 3600 + hour * 3600 + minute * 60 + second;\n  }\n\n  return result;\n}\n\nMG_INTERNAL int mg_is_not_modified(struct http_message *hm, cs_stat_t *st)\n{\n  struct mg_str *hdr;\n  if ((hdr = mg_get_http_header(hm, \"If-None-Match\")) != NULL)\n  {\n    char etag[64];\n    mg_http_construct_etag(etag, sizeof(etag), st);\n    return mg_vcasecmp(hdr, etag) == 0;\n  }\n  else if ((hdr = mg_get_http_header(hm, \"If-Modified-Since\")) != NULL)\n  {\n    return st->st_mtime <= mg_parse_date_string(hdr->p);\n  }\n  else\n  {\n    return 0;\n  }\n}\n\nstatic void mg_http_send_digest_auth_request(struct mg_connection *c,\n                                             const char *domain)\n{\n  mg_printf(c,\n            \"HTTP/1.1 401 Unauthorized\\r\\n\"\n            \"WWW-Authenticate: Digest qop=\\\"auth\\\", \"\n            \"realm=\\\"%s\\\", nonce=\\\"%lu\\\"\\r\\n\"\n            \"Content-Length: 0\\r\\n\\r\\n\",\n            domain, (unsigned long)mg_time());\n}\n\nstatic void mg_http_send_options(struct mg_connection *nc)\n{\n  mg_printf(nc, \"%s\",\n            \"HTTP/1.1 200 OK\\r\\nAllow: GET, POST, HEAD, CONNECT, OPTIONS\"\n#if MG_ENABLE_HTTP_WEBDAV\n            \", MKCOL, PUT, DELETE, PROPFIND, MOVE\\r\\nDAV: 1,2\"\n#endif\n            \"\\r\\n\\r\\n\");\n  nc->flags |= MG_F_SEND_AND_CLOSE;\n}\n\nstatic int mg_is_creation_request(const struct http_message *hm)\n{\n  return mg_vcmp(&hm->method, \"MKCOL\") == 0 || mg_vcmp(&hm->method, \"PUT\") == 0;\n}\n\nMG_INTERNAL void mg_send_http_file(struct mg_connection *nc, char *path,\n                                   const struct mg_str *path_info,\n                                   struct http_message *hm,\n                                   struct mg_serve_http_opts *opts)\n{\n  int exists, is_directory, is_cgi;\n#if MG_ENABLE_HTTP_WEBDAV\n  int is_dav = mg_is_dav_request(&hm->method);\n#else\n  int is_dav = 0;\n#endif\n  char *index_file = NULL;\n  cs_stat_t st;\n\n  exists = (mg_stat(path, &st) == 0);\n  is_directory = exists && S_ISDIR(st.st_mode);\n\n  if (is_directory)\n    mg_find_index_file(path, opts->index_files, &index_file, &st);\n\n  is_cgi =\n      (mg_match_prefix(opts->cgi_file_pattern, strlen(opts->cgi_file_pattern),\n                       index_file ? index_file : path) > 0);\n\n  DBG((\"%p %.*s [%s] exists=%d is_dir=%d is_dav=%d is_cgi=%d index=%s\", nc,\n       (int)hm->method.len, hm->method.p, path, exists, is_directory, is_dav,\n       is_cgi, index_file ? index_file : \"\"));\n\n  if (is_directory && hm->uri.p[hm->uri.len - 1] != '/' && !is_dav)\n  {\n    mg_printf(nc,\n              \"HTTP/1.1 301 Moved\\r\\nLocation: %.*s/\\r\\n\"\n              \"Content-Length: 0\\r\\n\\r\\n\",\n              (int)hm->uri.len, hm->uri.p);\n    MG_FREE(index_file);\n    return;\n  }\n\n  /* If we have path_info, the only way to handle it is CGI. */\n  if (path_info->len > 0 && !is_cgi)\n  {\n    mg_http_send_error(nc, 501, NULL);\n    MG_FREE(index_file);\n    return;\n  }\n\n  if (is_dav && opts->dav_document_root == NULL)\n  {\n    mg_http_send_error(nc, 501, NULL);\n  }\n  else if (!mg_is_authorized(hm, path, is_directory, opts->auth_domain,\n                             opts->global_auth_file, 1) ||\n           !mg_is_authorized(hm, path, is_directory, opts->auth_domain,\n                             opts->per_directory_auth_file, 0))\n  {\n    mg_http_send_digest_auth_request(nc, opts->auth_domain);\n  }\n  else if (is_cgi)\n  {\n#if MG_ENABLE_HTTP_CGI\n    mg_handle_cgi(nc, index_file ? index_file : path, path_info, hm, opts);\n#else\n    mg_http_send_error(nc, 501, NULL);\n#endif /* MG_ENABLE_HTTP_CGI */\n  }\n  else if ((!exists ||\n            mg_is_file_hidden(path, opts, 0 /* specials are ok */)) &&\n           !mg_is_creation_request(hm))\n  {\n    mg_http_send_error(nc, 404, NULL);\n#if MG_ENABLE_HTTP_WEBDAV\n  }\n  else if (!mg_vcmp(&hm->method, \"PROPFIND\"))\n  {\n    mg_handle_propfind(nc, path, &st, hm, opts);\n#if !MG_DISABLE_DAV_AUTH\n  }\n  else if (is_dav &&\n           (opts->dav_auth_file == NULL ||\n            (strcmp(opts->dav_auth_file, \"-\") != 0 &&\n             !mg_is_authorized(hm, path, is_directory, opts->auth_domain,\n                               opts->dav_auth_file, 1))))\n  {\n    mg_http_send_digest_auth_request(nc, opts->auth_domain);\n#endif\n  }\n  else if (!mg_vcmp(&hm->method, \"MKCOL\"))\n  {\n    mg_handle_mkcol(nc, path, hm);\n  }\n  else if (!mg_vcmp(&hm->method, \"DELETE\"))\n  {\n    mg_handle_delete(nc, opts, path);\n  }\n  else if (!mg_vcmp(&hm->method, \"PUT\"))\n  {\n    mg_handle_put(nc, path, hm);\n  }\n  else if (!mg_vcmp(&hm->method, \"MOVE\"))\n  {\n    mg_handle_move(nc, opts, path, hm);\n#if MG_ENABLE_FAKE_DAVLOCK\n  }\n  else if (!mg_vcmp(&hm->method, \"LOCK\"))\n  {\n    mg_handle_lock(nc, path);\n#endif\n#endif /* MG_ENABLE_HTTP_WEBDAV */\n  }\n  else if (!mg_vcmp(&hm->method, \"OPTIONS\"))\n  {\n    mg_http_send_options(nc);\n  }\n  else if (is_directory && index_file == NULL)\n  {\n#if MG_ENABLE_DIRECTORY_LISTING\n    if (strcmp(opts->enable_directory_listing, \"yes\") == 0)\n    {\n      mg_send_directory_listing(nc, path, hm, opts);\n    }\n    else\n    {\n      mg_http_send_error(nc, 403, NULL);\n    }\n#else\n    mg_http_send_error(nc, 501, NULL);\n#endif\n  }\n  else if (mg_is_not_modified(hm, &st))\n  {\n    mg_http_send_error(nc, 304, \"Not Modified\");\n  }\n  else\n  {\n    mg_http_serve_file2(nc, index_file ? index_file : path, hm, opts);\n  }\n  MG_FREE(index_file);\n}\n\nvoid mg_serve_http(struct mg_connection *nc, struct http_message *hm,\n                   struct mg_serve_http_opts opts)\n{\n  char *path = NULL;\n  struct mg_str *hdr, path_info;\n  uint32_t remote_ip = ntohl(*(uint32_t *)&nc->sa.sin.sin_addr);\n\n  if (mg_check_ip_acl(opts.ip_acl, remote_ip) != 1)\n  {\n    /* Not allowed to connect */\n    mg_http_send_error(nc, 403, NULL);\n    nc->flags |= MG_F_SEND_AND_CLOSE;\n    return;\n  }\n\n#if MG_ENABLE_HTTP_URL_REWRITES\n  if (mg_http_handle_forwarding(nc, hm, &opts))\n  {\n    return;\n  }\n\n  if (mg_http_send_port_based_redirect(nc, hm, &opts))\n  {\n    return;\n  }\n#endif\n\n  if (opts.document_root == NULL)\n  {\n    opts.document_root = \".\";\n  }\n  if (opts.per_directory_auth_file == NULL)\n  {\n    opts.per_directory_auth_file = \".htpasswd\";\n  }\n  if (opts.enable_directory_listing == NULL)\n  {\n    opts.enable_directory_listing = \"yes\";\n  }\n  if (opts.cgi_file_pattern == NULL)\n  {\n    opts.cgi_file_pattern = \"**.cgi$|**.php$\";\n  }\n  if (opts.ssi_pattern == NULL)\n  {\n    opts.ssi_pattern = \"**.shtml$|**.shtm$\";\n  }\n  if (opts.index_files == NULL)\n  {\n    opts.index_files = \"index.html,index.htm,index.shtml,index.cgi,index.php\";\n  }\n  /* Normalize path - resolve \".\" and \"..\" (in-place). */\n  if (!mg_normalize_uri_path(&hm->uri, &hm->uri))\n  {\n    mg_http_send_error(nc, 400, NULL);\n    return;\n  }\n  if (mg_uri_to_local_path(hm, &opts, &path, &path_info) == 0)\n  {\n    mg_http_send_error(nc, 404, NULL);\n    return;\n  }\n  mg_send_http_file(nc, path, &path_info, hm, &opts);\n\n  MG_FREE(path);\n  path = NULL;\n\n  /* Close connection for non-keep-alive requests */\n  if (mg_vcmp(&hm->proto, \"HTTP/1.1\") != 0 ||\n      ((hdr = mg_get_http_header(hm, \"Connection\")) != NULL &&\n       mg_vcmp(hdr, \"keep-alive\") != 0))\n  {\n#if 0\n    nc->flags |= MG_F_SEND_AND_CLOSE;\n#endif\n  }\n}\n\n#endif /* MG_ENABLE_FILESYSTEM */\n\n/* returns 0 on success, -1 on error */\nMG_INTERNAL int mg_http_common_url_parse(const char *url, const char *schema,\n                                         const char *schema_tls, int *use_ssl,\n                                         char **user, char **pass, char **addr,\n                                         int *port_i, const char **path)\n{\n  int addr_len = 0;\n  int auth_sep_pos = -1;\n  int user_sep_pos = -1;\n  int port_pos = -1;\n  (void)user;\n  (void)pass;\n\n  if (memcmp(url, schema, strlen(schema)) == 0)\n  {\n    url += strlen(schema);\n  }\n  else if (memcmp(url, schema_tls, strlen(schema_tls)) == 0)\n  {\n    url += strlen(schema_tls);\n    *use_ssl = 1;\n#if !MG_ENABLE_SSL\n    return -1; /* SSL is not enabled, cannot do HTTPS URLs */\n#endif\n  }\n\n  while (*url != '\\0')\n  {\n    *addr = (char *)MG_REALLOC(*addr, addr_len + 6 /* space for port too. */);\n    if (*addr == NULL)\n    {\n      DBG((\"OOM\"));\n      return -1;\n    }\n    if (*url == '/')\n    {\n      break;\n    }\n    if (*url == '@')\n    {\n      auth_sep_pos = addr_len;\n      user_sep_pos = port_pos;\n      port_pos = -1;\n    }\n    if (*url == ':')\n      port_pos = addr_len;\n    (*addr)[addr_len++] = *url;\n    (*addr)[addr_len] = '\\0';\n    url++;\n  }\n\n  if (addr_len == 0)\n    goto cleanup;\n  if (port_pos < 0)\n  {\n    *port_i = addr_len;\n    addr_len += sprintf(*addr + addr_len, \":%d\", *use_ssl ? 443 : 80);\n  }\n  else\n  {\n    *port_i = -1;\n  }\n\n  if (*path == NULL)\n    *path = url;\n\n  if (**path == '\\0')\n    *path = \"/\";\n\n  if (user != NULL && pass != NULL)\n  {\n    if (auth_sep_pos == -1)\n    {\n      *user = NULL;\n      *pass = NULL;\n    }\n    else\n    {\n      /* user is from 0 to user_sep_pos */\n      *user = (char *)MG_MALLOC(user_sep_pos + 1);\n      memcpy(*user, *addr, user_sep_pos);\n      (*user)[user_sep_pos] = '\\0';\n      /* pass is from user_sep_pos + 1 to auth_sep_pos */\n      *pass = (char *)MG_MALLOC(auth_sep_pos - user_sep_pos - 1 + 1);\n      memcpy(*pass, *addr + user_sep_pos + 1, auth_sep_pos - user_sep_pos - 1);\n      (*pass)[auth_sep_pos - user_sep_pos - 1] = '\\0';\n\n      /* move address proper to the front */\n      memmove(*addr, *addr + auth_sep_pos + 1, addr_len - auth_sep_pos);\n    }\n  }\n\n  DBG((\"%s %s\", *addr, *path));\n\n  return 0;\n\ncleanup:\n  MG_FREE(*addr);\n  return -1;\n}\n\nstruct mg_connection *mg_connect_http_base(\n    struct mg_mgr *mgr, mg_event_handler_t ev_handler,\n    struct mg_connect_opts opts, const char *schema, const char *schema_ssl,\n    const char *url, const char **path, char **user, char **pass, char **addr)\n{\n  struct mg_connection *nc = NULL;\n  int port_i = -1;\n  int use_ssl = 0;\n\n  if (mg_http_common_url_parse(url, schema, schema_ssl, &use_ssl, user, pass,\n                               addr, &port_i, path) < 0)\n  {\n    MG_SET_PTRPTR(opts.error_string, \"cannot parse url\");\n    return NULL;\n  }\n\n  LOG(LL_DEBUG, (\"%s use_ssl? %d\", url, use_ssl));\n  if (use_ssl)\n  {\n#if MG_ENABLE_SSL\n    /*\n     * Schema requires SSL, but no SSL parameters were provided in opts.\n     * In order to maintain backward compatibility, use a faux-SSL with no\n     * verification.\n     */\n    if (opts.ssl_ca_cert == NULL)\n    {\n      opts.ssl_ca_cert = \"*\";\n    }\n#else\n    MG_SET_PTRPTR(opts.error_string, \"ssl is disabled\");\n    if (user != NULL)\n      MG_FREE(*user);\n    if (pass != NULL)\n      MG_FREE(*pass);\n    MG_FREE(*addr);\n    return NULL;\n#endif\n  }\n\n  if ((nc = mg_connect_opt(mgr, *addr, ev_handler, opts)) != NULL)\n  {\n    mg_set_protocol_http_websocket(nc);\n    /* If the port was addred by us, restore the original host. */\n    if (port_i >= 0)\n      (*addr)[port_i] = '\\0';\n  }\n\n  return nc;\n}\n\nstruct mg_connection *mg_connect_http_opt(struct mg_mgr *mgr,\n                                          mg_event_handler_t ev_handler,\n                                          struct mg_connect_opts opts,\n                                          const char *url,\n                                          const char *extra_headers,\n                                          const char *post_data)\n{\n  char *user = NULL, *pass = NULL, *addr = NULL;\n  const char *path = NULL;\n  struct mbuf auth;\n  struct mg_connection *nc =\n      mg_connect_http_base(mgr, ev_handler, opts, \"http://\", \"https://\", url,\n                           &path, &user, &pass, &addr);\n\n  if (nc == NULL)\n  {\n    return NULL;\n  }\n\n  mbuf_init(&auth, 0);\n  if (user != NULL)\n  {\n    mg_basic_auth_header(user, pass, &auth);\n  }\n\n  mg_printf(nc, \"%s %s HTTP/1.1\\r\\nHost: %s\\r\\nContent-Length: %\" SIZE_T_FMT \"\\r\\n%.*s%s\\r\\n%s\",\n            post_data == NULL ? \"GET\" : \"POST\", path, addr,\n            post_data == NULL ? 0 : strlen(post_data), (int)auth.len,\n            (auth.buf == NULL ? \"\" : auth.buf),\n            extra_headers == NULL ? \"\" : extra_headers,\n            post_data == NULL ? \"\" : post_data);\n\n  mbuf_free(&auth);\n  MG_FREE(user);\n  MG_FREE(pass);\n  MG_FREE(addr);\n  return nc;\n}\n\nstruct mg_connection *mg_connect_http(struct mg_mgr *mgr,\n                                      mg_event_handler_t ev_handler,\n                                      const char *url,\n                                      const char *extra_headers,\n                                      const char *post_data)\n{\n  struct mg_connect_opts opts;\n  memset(&opts, 0, sizeof(opts));\n  return mg_connect_http_opt(mgr, ev_handler, opts, url, extra_headers,\n                             post_data);\n}\n\nsize_t mg_parse_multipart(const char *buf, size_t buf_len, char *var_name,\n                          size_t var_name_len, char *file_name,\n                          size_t file_name_len, const char **data,\n                          size_t *data_len)\n{\n  static const char cd[] = \"Content-Disposition: \";\n  size_t hl, bl, n, ll, pos, cdl = sizeof(cd) - 1;\n\n  if (buf == NULL || buf_len <= 0)\n    return 0;\n  if ((hl = mg_http_get_request_len(buf, buf_len)) <= 0)\n    return 0;\n  if (buf[0] != '-' || buf[1] != '-' || buf[2] == '\\n')\n    return 0;\n\n  /* Get boundary length */\n  bl = mg_get_line_len(buf, buf_len);\n\n  /* Loop through headers, fetch variable name and file name */\n  var_name[0] = file_name[0] = '\\0';\n  for (n = bl; (ll = mg_get_line_len(buf + n, hl - n)) > 0; n += ll)\n  {\n    if (mg_ncasecmp(cd, buf + n, cdl) == 0)\n    {\n      struct mg_str header;\n      header.p = buf + n + cdl;\n      header.len = ll - (cdl + 2);\n      mg_http_parse_header(&header, \"name\", var_name, var_name_len);\n      mg_http_parse_header(&header, \"filename\", file_name, file_name_len);\n    }\n  }\n\n  /* Scan through the body, search for terminating boundary */\n  for (pos = hl; pos + (bl - 2) < buf_len; pos++)\n  {\n    if (buf[pos] == '-' && !memcmp(buf, &buf[pos], bl - 2))\n    {\n      if (data_len != NULL)\n        *data_len = (pos - 2) - hl;\n      if (data != NULL)\n        *data = buf + hl;\n      return pos;\n    }\n  }\n\n  return 0;\n}\n\nvoid mg_register_http_endpoint(struct mg_connection *nc, const char *uri_path,\n                               mg_event_handler_t handler)\n{\n  struct mg_http_proto_data *pd = NULL;\n  struct mg_http_endpoint *new_ep = NULL;\n\n  if (nc == NULL)\n    return;\n  new_ep = (struct mg_http_endpoint *)calloc(1, sizeof(*new_ep));\n  if (new_ep == NULL)\n    return;\n\n  pd = mg_http_get_proto_data(nc);\n  new_ep->name = strdup(uri_path);\n  new_ep->name_len = strlen(new_ep->name);\n  new_ep->handler = handler;\n  new_ep->next = pd->endpoints;\n  pd->endpoints = new_ep;\n}\n\n#endif /* MG_ENABLE_HTTP */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/http_cgi.c\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#if MG_ENABLE_HTTP && MG_ENABLE_HTTP_CGI\n\n#ifndef MG_MAX_CGI_ENVIR_VARS\n#define MG_MAX_CGI_ENVIR_VARS 64\n#endif\n\n#ifndef MG_ENV_EXPORT_TO_CGI\n#define MG_ENV_EXPORT_TO_CGI \"MONGOOSE_CGI\"\n#endif\n\n/*\n * This structure helps to create an environment for the spawned CGI program.\n * Environment is an array of \"VARIABLE=VALUE\\0\" ASCIIZ strings,\n * last element must be NULL.\n * However, on Windows there is a requirement that all these VARIABLE=VALUE\\0\n * strings must reside in a contiguous buffer. The end of the buffer is\n * marked by two '\\0' characters.\n * We satisfy both worlds: we create an envp array (which is vars), all\n * entries are actually pointers inside buf.\n */\nstruct mg_cgi_env_block\n{\n  struct mg_connection *nc;\n  char buf[MG_CGI_ENVIRONMENT_SIZE];       /* Environment buffer */\n  const char *vars[MG_MAX_CGI_ENVIR_VARS]; /* char *envp[] */\n  int len;                                 /* Space taken */\n  int nvars;                               /* Number of variables in envp[] */\n};\n\n#ifdef _WIN32\nstruct mg_threadparam\n{\n  sock_t s;\n  HANDLE hPipe;\n};\n\nstatic int mg_wait_until_ready(sock_t sock, int for_read)\n{\n  fd_set set;\n  FD_ZERO(&set);\n  FD_SET(sock, &set);\n  return select(sock + 1, for_read ? &set : 0, for_read ? 0 : &set, 0, 0) == 1;\n}\n\nstatic void *mg_push_to_stdin(void *arg)\n{\n  struct mg_threadparam *tp = (struct mg_threadparam *)arg;\n  int n, sent, stop = 0;\n  DWORD k;\n  char buf[BUFSIZ];\n\n  while (!stop && mg_wait_until_ready(tp->s, 1) &&\n         (n = recv(tp->s, buf, sizeof(buf), 0)) > 0)\n  {\n    if (n == -1 && GetLastError() == WSAEWOULDBLOCK)\n      continue;\n    for (sent = 0; !stop && sent < n; sent += k)\n    {\n      if (!WriteFile(tp->hPipe, buf + sent, n - sent, &k, 0))\n        stop = 1;\n    }\n  }\n  DBG((\"%s\", \"FORWARED EVERYTHING TO CGI\"));\n  CloseHandle(tp->hPipe);\n  MG_FREE(tp);\n  return NULL;\n}\n\nstatic void *mg_pull_from_stdout(void *arg)\n{\n  struct mg_threadparam *tp = (struct mg_threadparam *)arg;\n  int k = 0, stop = 0;\n  DWORD n, sent;\n  char buf[BUFSIZ];\n\n  while (!stop && ReadFile(tp->hPipe, buf, sizeof(buf), &n, NULL))\n  {\n    for (sent = 0; !stop && sent < n; sent += k)\n    {\n      if (mg_wait_until_ready(tp->s, 0) &&\n          (k = send(tp->s, buf + sent, n - sent, 0)) <= 0)\n        stop = 1;\n    }\n  }\n  DBG((\"%s\", \"EOF FROM CGI\"));\n  CloseHandle(tp->hPipe);\n  shutdown(tp->s, 2); // Without this, IO thread may get truncated data\n  closesocket(tp->s);\n  MG_FREE(tp);\n  return NULL;\n}\n\nstatic void mg_spawn_stdio_thread(sock_t sock, HANDLE hPipe,\n                                  void *(*func)(void *))\n{\n  struct mg_threadparam *tp = (struct mg_threadparam *)MG_MALLOC(sizeof(*tp));\n  if (tp != NULL)\n  {\n    tp->s = sock;\n    tp->hPipe = hPipe;\n    mg_start_thread(func, tp);\n  }\n}\n\nstatic void mg_abs_path(const char *utf8_path, char *abs_path, size_t len)\n{\n  wchar_t buf[MAX_PATH_SIZE], buf2[MAX_PATH_SIZE];\n  to_wchar(utf8_path, buf, ARRAY_SIZE(buf));\n  GetFullPathNameW(buf, ARRAY_SIZE(buf2), buf2, NULL);\n  WideCharToMultiByte(CP_UTF8, 0, buf2, wcslen(buf2) + 1, abs_path, len, 0, 0);\n}\n\nstatic int mg_start_process(const char *interp, const char *cmd,\n                            const char *env, const char *envp[],\n                            const char *dir, sock_t sock)\n{\n  STARTUPINFOW si;\n  PROCESS_INFORMATION pi;\n  HANDLE a[2], b[2], me = GetCurrentProcess();\n  wchar_t wcmd[MAX_PATH_SIZE], full_dir[MAX_PATH_SIZE];\n  char buf[MAX_PATH_SIZE], buf2[MAX_PATH_SIZE], buf5[MAX_PATH_SIZE],\n      buf4[MAX_PATH_SIZE], cmdline[MAX_PATH_SIZE];\n  DWORD flags = DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS;\n  FILE *fp;\n\n  memset(&si, 0, sizeof(si));\n  memset(&pi, 0, sizeof(pi));\n\n  si.cb = sizeof(si);\n  si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;\n  si.wShowWindow = SW_HIDE;\n  si.hStdError = GetStdHandle(STD_ERROR_HANDLE);\n\n  CreatePipe(&a[0], &a[1], NULL, 0);\n  CreatePipe(&b[0], &b[1], NULL, 0);\n  DuplicateHandle(me, a[0], me, &si.hStdInput, 0, TRUE, flags);\n  DuplicateHandle(me, b[1], me, &si.hStdOutput, 0, TRUE, flags);\n\n  if (interp == NULL && (fp = fopen(cmd, \"r\")) != NULL)\n  {\n    buf[0] = buf[1] = '\\0';\n    fgets(buf, sizeof(buf), fp);\n    buf[sizeof(buf) - 1] = '\\0';\n    if (buf[0] == '#' && buf[1] == '!')\n    {\n      interp = buf + 2;\n      /* Trim leading spaces: https://github.com/cesanta/mongoose/issues/489 */\n      while (*interp != '\\0' && isspace(*(unsigned char *)interp))\n      {\n        interp++;\n      }\n    }\n    fclose(fp);\n  }\n\n  snprintf(buf, sizeof(buf), \"%s/%s\", dir, cmd);\n  mg_abs_path(buf, buf2, ARRAY_SIZE(buf2));\n\n  mg_abs_path(dir, buf5, ARRAY_SIZE(buf5));\n  to_wchar(dir, full_dir, ARRAY_SIZE(full_dir));\n\n  if (interp != NULL)\n  {\n    mg_abs_path(interp, buf4, ARRAY_SIZE(buf4));\n    snprintf(cmdline, sizeof(cmdline), \"%s \\\"%s\\\"\", buf4, buf2);\n  }\n  else\n  {\n    snprintf(cmdline, sizeof(cmdline), \"\\\"%s\\\"\", buf2);\n  }\n  to_wchar(cmdline, wcmd, ARRAY_SIZE(wcmd));\n\n  if (CreateProcessW(NULL, wcmd, NULL, NULL, TRUE, CREATE_NEW_PROCESS_GROUP,\n                     (void *)env, full_dir, &si, &pi) != 0)\n  {\n    mg_spawn_stdio_thread(sock, a[1], mg_push_to_stdin);\n    mg_spawn_stdio_thread(sock, b[0], mg_pull_from_stdout);\n\n    CloseHandle(si.hStdOutput);\n    CloseHandle(si.hStdInput);\n\n    CloseHandle(pi.hThread);\n    CloseHandle(pi.hProcess);\n  }\n  else\n  {\n    CloseHandle(a[1]);\n    CloseHandle(b[0]);\n    closesocket(sock);\n  }\n  DBG((\"CGI command: [%ls] -> %p\", wcmd, pi.hProcess));\n\n  /* Not closing a[0] and b[1] because we've used DUPLICATE_CLOSE_SOURCE */\n  (void)envp;\n  return (pi.hProcess != NULL);\n}\n#else\nstatic int mg_start_process(const char *interp, const char *cmd,\n                            const char *env, const char *envp[],\n                            const char *dir, sock_t sock)\n{\n  char buf[500];\n  pid_t pid = fork();\n  (void)env;\n\n  if (pid == 0)\n  {\n    /*\n     * In Linux `chdir` declared with `warn_unused_result` attribute\n     * To shutup compiler we have yo use result in some way\n     */\n    int tmp = chdir(dir);\n    (void)tmp;\n    (void)dup2(sock, 0);\n    (void)dup2(sock, 1);\n    closesocket(sock);\n\n    /*\n     * After exec, all signal handlers are restored to their default values,\n     * with one exception of SIGCHLD. According to POSIX.1-2001 and Linux's\n     * implementation, SIGCHLD's handler will leave unchanged after exec\n     * if it was set to be ignored. Restore it to default action.\n     */\n    signal(SIGCHLD, SIG_DFL);\n\n    if (interp == NULL)\n    {\n      execle(cmd, cmd, (char *)0, envp); /* (char *) 0 to squash warning */\n    }\n    else\n    {\n      execle(interp, interp, cmd, (char *)0, envp);\n    }\n    snprintf(buf, sizeof(buf),\n             \"Status: 500\\r\\n\\r\\n\"\n             \"500 Server Error: %s%s%s: %s\",\n             interp == NULL ? \"\" : interp, interp == NULL ? \"\" : \" \", cmd,\n             strerror(errno));\n    send(1, buf, strlen(buf), 0);\n    exit(EXIT_FAILURE); /* exec call failed */\n  }\n\n  return (pid != 0);\n}\n#endif /* _WIN32 */\n\n/*\n * Append VARIABLE=VALUE\\0 string to the buffer, and add a respective\n * pointer into the vars array.\n */\nstatic char *mg_addenv(struct mg_cgi_env_block *block, const char *fmt, ...)\n{\n  int n, space;\n  char *added = block->buf + block->len;\n  va_list ap;\n\n  /* Calculate how much space is left in the buffer */\n  space = sizeof(block->buf) - (block->len + 2);\n  if (space > 0)\n  {\n    /* Copy VARIABLE=VALUE\\0 string into the free space */\n    va_start(ap, fmt);\n    n = vsnprintf(added, (size_t)space, fmt, ap);\n    va_end(ap);\n\n    /* Make sure we do not overflow buffer and the envp array */\n    if (n > 0 && n + 1 < space &&\n        block->nvars < (int)ARRAY_SIZE(block->vars) - 2)\n    {\n      /* Append a pointer to the added string into the envp array */\n      block->vars[block->nvars++] = added;\n      /* Bump up used length counter. Include \\0 terminator */\n      block->len += n + 1;\n    }\n  }\n\n  return added;\n}\n\nstatic void mg_addenv2(struct mg_cgi_env_block *blk, const char *name)\n{\n  const char *s;\n  if ((s = getenv(name)) != NULL)\n    mg_addenv(blk, \"%s=%s\", name, s);\n}\n\nstatic void mg_prepare_cgi_environment(struct mg_connection *nc,\n                                       const char *prog,\n                                       const struct mg_str *path_info,\n                                       const struct http_message *hm,\n                                       const struct mg_serve_http_opts *opts,\n                                       struct mg_cgi_env_block *blk)\n{\n  const char *s;\n  struct mg_str *h;\n  char *p;\n  size_t i;\n  char buf[100];\n\n  blk->len = blk->nvars = 0;\n  blk->nc = nc;\n\n  if ((s = getenv(\"SERVER_NAME\")) != NULL)\n  {\n    mg_addenv(blk, \"SERVER_NAME=%s\", s);\n  }\n  else\n  {\n    mg_sock_to_str(nc->sock, buf, sizeof(buf), 3);\n    mg_addenv(blk, \"SERVER_NAME=%s\", buf);\n  }\n  mg_addenv(blk, \"SERVER_ROOT=%s\", opts->document_root);\n  mg_addenv(blk, \"DOCUMENT_ROOT=%s\", opts->document_root);\n  mg_addenv(blk, \"SERVER_SOFTWARE=%s/%s\", \"Mongoose\", MG_VERSION);\n\n  /* Prepare the environment block */\n  mg_addenv(blk, \"%s\", \"GATEWAY_INTERFACE=CGI/1.1\");\n  mg_addenv(blk, \"%s\", \"SERVER_PROTOCOL=HTTP/1.1\");\n  mg_addenv(blk, \"%s\", \"REDIRECT_STATUS=200\"); /* For PHP */\n\n  mg_addenv(blk, \"REQUEST_METHOD=%.*s\", (int)hm->method.len, hm->method.p);\n\n  mg_addenv(blk, \"REQUEST_URI=%.*s%s%.*s\", (int)hm->uri.len, hm->uri.p,\n            hm->query_string.len == 0 ? \"\" : \"?\", (int)hm->query_string.len,\n            hm->query_string.p);\n\n  mg_conn_addr_to_str(nc, buf, sizeof(buf),\n                      MG_SOCK_STRINGIFY_REMOTE | MG_SOCK_STRINGIFY_IP);\n  mg_addenv(blk, \"REMOTE_ADDR=%s\", buf);\n  mg_conn_addr_to_str(nc, buf, sizeof(buf), MG_SOCK_STRINGIFY_PORT);\n  mg_addenv(blk, \"SERVER_PORT=%s\", buf);\n\n  s = hm->uri.p + hm->uri.len - path_info->len - 1;\n  if (*s == '/')\n  {\n    const char *base_name = strrchr(prog, DIRSEP);\n    mg_addenv(blk, \"SCRIPT_NAME=%.*s/%s\", (int)(s - hm->uri.p), hm->uri.p,\n              (base_name != NULL ? base_name + 1 : prog));\n  }\n  else\n  {\n    mg_addenv(blk, \"SCRIPT_NAME=%.*s\", (int)(s - hm->uri.p + 1), hm->uri.p);\n  }\n  mg_addenv(blk, \"SCRIPT_FILENAME=%s\", prog);\n\n  if (path_info != NULL && path_info->len > 0)\n  {\n    mg_addenv(blk, \"PATH_INFO=%.*s\", (int)path_info->len, path_info->p);\n    /* Not really translated... */\n    mg_addenv(blk, \"PATH_TRANSLATED=%.*s\", (int)path_info->len, path_info->p);\n  }\n\n#if MG_ENABLE_SSL\n  mg_addenv(blk, \"HTTPS=%s\", (nc->flags & MG_F_SSL ? \"on\" : \"off\"));\n#else\n  mg_addenv(blk, \"HTTPS=off\");\n#endif\n\n  if ((h = mg_get_http_header((struct http_message *)hm, \"Content-Type\")) !=\n      NULL)\n  {\n    mg_addenv(blk, \"CONTENT_TYPE=%.*s\", (int)h->len, h->p);\n  }\n\n  if (hm->query_string.len > 0)\n  {\n    mg_addenv(blk, \"QUERY_STRING=%.*s\", (int)hm->query_string.len,\n              hm->query_string.p);\n  }\n\n  if ((h = mg_get_http_header((struct http_message *)hm, \"Content-Length\")) !=\n      NULL)\n  {\n    mg_addenv(blk, \"CONTENT_LENGTH=%.*s\", (int)h->len, h->p);\n  }\n\n  mg_addenv2(blk, \"PATH\");\n  mg_addenv2(blk, \"TMP\");\n  mg_addenv2(blk, \"TEMP\");\n  mg_addenv2(blk, \"TMPDIR\");\n  mg_addenv2(blk, \"PERLLIB\");\n  mg_addenv2(blk, MG_ENV_EXPORT_TO_CGI);\n\n#ifdef _WIN32\n  mg_addenv2(blk, \"COMSPEC\");\n  mg_addenv2(blk, \"SYSTEMROOT\");\n  mg_addenv2(blk, \"SystemDrive\");\n  mg_addenv2(blk, \"ProgramFiles\");\n  mg_addenv2(blk, \"ProgramFiles(x86)\");\n  mg_addenv2(blk, \"CommonProgramFiles(x86)\");\n#else\n  mg_addenv2(blk, \"LD_LIBRARY_PATH\");\n#endif /* _WIN32 */\n\n  /* Add all headers as HTTP_* variables */\n  for (i = 0; hm->header_names[i].len > 0; i++)\n  {\n    p = mg_addenv(blk, \"HTTP_%.*s=%.*s\", (int)hm->header_names[i].len,\n                  hm->header_names[i].p, (int)hm->header_values[i].len,\n                  hm->header_values[i].p);\n\n    /* Convert variable name into uppercase, and change - to _ */\n    for (; *p != '=' && *p != '\\0'; p++)\n    {\n      if (*p == '-')\n        *p = '_';\n      *p = (char)toupper(*(unsigned char *)p);\n    }\n  }\n\n  blk->vars[blk->nvars++] = NULL;\n  blk->buf[blk->len++] = '\\0';\n}\n\nstatic void mg_cgi_ev_handler(struct mg_connection *cgi_nc, int ev,\n                              void *ev_data)\n{\n  struct mg_connection *nc = (struct mg_connection *)cgi_nc->user_data;\n  (void)ev_data;\n\n  if (nc == NULL)\n    return;\n\n  switch (ev)\n  {\n  case MG_EV_RECV:\n    /*\n       * CGI script does not output reply line, like \"HTTP/1.1 CODE XXXXX\\n\"\n       * It outputs headers, then body. Headers might include \"Status\"\n       * header, which changes CODE, and it might include \"Location\" header\n       * which changes CODE to 302.\n       *\n       * Therefore we do not send the output from the CGI script to the user\n       * until all CGI headers are received.\n       *\n       * Here we parse the output from the CGI script, and if all headers has\n       * been received, send appropriate reply line, and forward all\n       * received headers to the client.\n       */\n    if (nc->flags & MG_F_USER_1)\n    {\n      struct mbuf *io = &cgi_nc->recv_mbuf;\n      int len = mg_http_get_request_len(io->buf, io->len);\n\n      if (len == 0)\n        break;\n      if (len < 0 || io->len > MG_MAX_HTTP_REQUEST_SIZE)\n      {\n        cgi_nc->flags |= MG_F_CLOSE_IMMEDIATELY;\n        mg_http_send_error(nc, 500, \"Bad headers\");\n      }\n      else\n      {\n        struct http_message hm;\n        struct mg_str *h;\n        mg_http_parse_headers(io->buf, io->buf + io->len, io->len, &hm);\n        if (mg_get_http_header(&hm, \"Location\") != NULL)\n        {\n          mg_printf(nc, \"%s\", \"HTTP/1.1 302 Moved\\r\\n\");\n        }\n        else if ((h = mg_get_http_header(&hm, \"Status\")) != NULL)\n        {\n          mg_printf(nc, \"HTTP/1.1 %.*s\\r\\n\", (int)h->len, h->p);\n        }\n        else\n        {\n          mg_printf(nc, \"%s\", \"HTTP/1.1 200 OK\\r\\n\");\n        }\n      }\n      nc->flags &= ~MG_F_USER_1;\n    }\n    if (!(nc->flags & MG_F_USER_1))\n    {\n      mg_forward(cgi_nc, nc);\n    }\n    break;\n  case MG_EV_CLOSE:\n    mg_http_free_proto_data_cgi(&mg_http_get_proto_data(cgi_nc)->cgi);\n    nc->flags |= MG_F_SEND_AND_CLOSE;\n    break;\n  }\n}\n\nMG_INTERNAL void mg_handle_cgi(struct mg_connection *nc, const char *prog,\n                               const struct mg_str *path_info,\n                               const struct http_message *hm,\n                               const struct mg_serve_http_opts *opts)\n{\n  struct mg_cgi_env_block blk;\n  char dir[MAX_PATH_SIZE];\n  const char *p;\n  sock_t fds[2];\n\n  DBG((\"%p [%s]\", nc, prog));\n  mg_prepare_cgi_environment(nc, prog, path_info, hm, opts, &blk);\n  /*\n   * CGI must be executed in its own directory. 'dir' must point to the\n   * directory containing executable program, 'p' must point to the\n   * executable program name relative to 'dir'.\n   */\n  if ((p = strrchr(prog, DIRSEP)) == NULL)\n  {\n    snprintf(dir, sizeof(dir), \"%s\", \".\");\n  }\n  else\n  {\n    snprintf(dir, sizeof(dir), \"%.*s\", (int)(p - prog), prog);\n    prog = p + 1;\n  }\n\n  /*\n   * Try to create sockucnair in a loop until success. mg_sockucnair()\n   * can be interrupted by a signal and fail.\n   * TODO(lsm): use sigaction to restart interrupted syscall\n   */\n  do\n  {\n    mg_sockucnair(fds, SOCK_STREAM);\n  } while (fds[0] == INVALID_SOCKET);\n\n  if (mg_start_process(opts->cgi_interpreter, prog, blk.buf, blk.vars, dir,\n                       fds[1]) != 0)\n  {\n    size_t n = nc->recv_mbuf.len - (hm->message.len - hm->body.len);\n    struct mg_connection *cgi_nc =\n        mg_add_sock(nc->mgr, fds[0], mg_cgi_ev_handler);\n    struct mg_http_proto_data *cgi_pd = mg_http_get_proto_data(cgi_nc);\n    cgi_pd->cgi.cgi_nc = cgi_nc;\n    cgi_pd->cgi.cgi_nc->user_data = nc;\n    nc->flags |= MG_F_USER_1;\n    /* Push POST data to the CGI */\n    if (n > 0 && n < nc->recv_mbuf.len)\n    {\n      mg_send(cgi_pd->cgi.cgi_nc, hm->body.p, n);\n    }\n    mbuf_remove(&nc->recv_mbuf, nc->recv_mbuf.len);\n  }\n  else\n  {\n    closesocket(fds[0]);\n    mg_http_send_error(nc, 500, \"CGI failure\");\n  }\n\n#ifndef _WIN32\n  closesocket(fds[1]); /* On Windows, CGI stdio thread closes that socket */\n#endif\n}\n\nMG_INTERNAL void mg_http_free_proto_data_cgi(struct mg_http_proto_data_cgi *d)\n{\n  if (d != NULL)\n  {\n    if (d->cgi_nc != NULL)\n      d->cgi_nc->flags |= MG_F_CLOSE_IMMEDIATELY;\n    memset(d, 0, sizeof(struct mg_http_proto_data_cgi));\n  }\n}\n\n#endif /* MG_ENABLE_HTTP && MG_ENABLE_HTTP_CGI */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/http_ssi.c\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#if MG_ENABLE_HTTP && MG_ENABLE_HTTP_SSI && MG_ENABLE_FILESYSTEM\n\nstatic void mg_send_ssi_file(struct mg_connection *nc, struct http_message *hm,\n                             const char *path, FILE *fp, int include_level,\n                             const struct mg_serve_http_opts *opts);\n\nstatic void mg_send_file_data(struct mg_connection *nc, FILE *fp)\n{\n  char buf[BUFSIZ];\n  size_t n;\n  while ((n = fread(buf, 1, sizeof(buf), fp)) > 0)\n  {\n    mg_send(nc, buf, n);\n  }\n}\n\nstatic void mg_do_ssi_include(struct mg_connection *nc, struct http_message *hm,\n                              const char *ssi, char *tag, int include_level,\n                              const struct mg_serve_http_opts *opts)\n{\n  char file_name[BUFSIZ], path[MAX_PATH_SIZE], *p;\n  FILE *fp;\n\n  /*\n   * sscanf() is safe here, since send_ssi_file() also uses buffer\n   * of size MG_BUF_LEN to get the tag. So strlen(tag) is always < MG_BUF_LEN.\n   */\n  if (sscanf(tag, \" virtual=\\\"%[^\\\"]\\\"\", file_name) == 1)\n  {\n    /* File name is relative to the webserver root */\n    snprintf(path, sizeof(path), \"%s/%s\", opts->document_root, file_name);\n  }\n  else if (sscanf(tag, \" abspath=\\\"%[^\\\"]\\\"\", file_name) == 1)\n  {\n    /*\n     * File name is relative to the webserver working directory\n     * or it is absolute system path\n     */\n    snprintf(path, sizeof(path), \"%s\", file_name);\n  }\n  else if (sscanf(tag, \" file=\\\"%[^\\\"]\\\"\", file_name) == 1 ||\n           sscanf(tag, \" \\\"%[^\\\"]\\\"\", file_name) == 1)\n  {\n    /* File name is relative to the currect document */\n    snprintf(path, sizeof(path), \"%s\", ssi);\n    if ((p = strrchr(path, DIRSEP)) != NULL)\n    {\n      p[1] = '\\0';\n    }\n    snprintf(path + strlen(path), sizeof(path) - strlen(path), \"%s\", file_name);\n  }\n  else\n  {\n    mg_printf(nc, \"Bad SSI #include: [%s]\", tag);\n    return;\n  }\n\n  if ((fp = fopen(path, \"rb\")) == NULL)\n  {\n    mg_printf(nc, \"SSI include error: fopen(%s): %s\", path,\n              strerror(mg_get_errno()));\n  }\n  else\n  {\n    mg_set_close_on_exec((sock_t)fileno(fp));\n    if (mg_match_prefix(opts->ssi_pattern, strlen(opts->ssi_pattern), path) >\n        0)\n    {\n      mg_send_ssi_file(nc, hm, path, fp, include_level + 1, opts);\n    }\n    else\n    {\n      mg_send_file_data(nc, fp);\n    }\n    fclose(fp);\n  }\n}\n\n#if MG_ENABLE_HTTP_SSI_EXEC\nstatic void do_ssi_exec(struct mg_connection *nc, char *tag)\n{\n  char cmd[BUFSIZ];\n  FILE *fp;\n\n  if (sscanf(tag, \" \\\"%[^\\\"]\\\"\", cmd) != 1)\n  {\n    mg_printf(nc, \"Bad SSI #exec: [%s]\", tag);\n  }\n  else if ((fp = popen(cmd, \"r\")) == NULL)\n  {\n    mg_printf(nc, \"Cannot SSI #exec: [%s]: %s\", cmd, strerror(mg_get_errno()));\n  }\n  else\n  {\n    mg_send_file_data(nc, fp);\n    pclose(fp);\n  }\n}\n#endif /* MG_ENABLE_HTTP_SSI_EXEC */\n\n/*\n * SSI directive has the following format:\n * <!--#directive parameter=value parameter=value -->\n */\nstatic void mg_send_ssi_file(struct mg_connection *nc, struct http_message *hm,\n                             const char *path, FILE *fp, int include_level,\n                             const struct mg_serve_http_opts *opts)\n{\n  static const struct mg_str btag = MG_MK_STR(\"<!--#\");\n  static const struct mg_str d_include = MG_MK_STR(\"include\");\n  static const struct mg_str d_call = MG_MK_STR(\"call\");\n#if MG_ENABLE_HTTP_SSI_EXEC\n  static const struct mg_str d_exec = MG_MK_STR(\"exec\");\n#endif\n  char buf[BUFSIZ], *p = buf + btag.len; /* p points to SSI directive */\n  int ch, len, in_ssi_tag;\n\n  if (include_level > 10)\n  {\n    mg_printf(nc, \"SSI #include level is too deep (%s)\", path);\n    return;\n  }\n\n  in_ssi_tag = len = 0;\n  while ((ch = fgetc(fp)) != EOF)\n  {\n    if (in_ssi_tag && ch == '>' && buf[len - 1] == '-' && buf[len - 2] == '-')\n    {\n      size_t i = len - 2;\n      in_ssi_tag = 0;\n\n      /* Trim closing --> */\n      buf[i--] = '\\0';\n      while (i > 0 && buf[i] == ' ')\n      {\n        buf[i--] = '\\0';\n      }\n\n      /* Handle known SSI directives */\n      if (memcmp(p, d_include.p, d_include.len) == 0)\n      {\n        mg_do_ssi_include(nc, hm, path, p + d_include.len + 1, include_level,\n                          opts);\n      }\n      else if (memcmp(p, d_call.p, d_call.len) == 0)\n      {\n        struct mg_ssi_call_ctx cctx;\n        memset(&cctx, 0, sizeof(cctx));\n        cctx.req = hm;\n        cctx.file = mg_mk_str(path);\n        cctx.arg = mg_mk_str(p + d_call.len + 1);\n        mg_call(nc, NULL, MG_EV_SSI_CALL,\n                (void *)cctx.arg.p); /* NUL added above */\n        mg_call(nc, NULL, MG_EV_SSI_CALL_CTX, &cctx);\n#if MG_ENABLE_HTTP_SSI_EXEC\n      }\n      else if (memcmp(p, d_exec.p, d_exec.len) == 0)\n      {\n        do_ssi_exec(nc, p + d_exec.len + 1);\n#endif\n      }\n      else\n      {\n        /* Silently ignore unknown SSI directive. */\n      }\n      len = 0;\n    }\n    else if (ch == '<')\n    {\n      in_ssi_tag = 1;\n      if (len > 0)\n      {\n        mg_send(nc, buf, (size_t)len);\n      }\n      len = 0;\n      buf[len++] = ch & 0xff;\n    }\n    else if (in_ssi_tag)\n    {\n      if (len == (int)btag.len && memcmp(buf, btag.p, btag.len) != 0)\n      {\n        /* Not an SSI tag */\n        in_ssi_tag = 0;\n      }\n      else if (len == (int)sizeof(buf) - 2)\n      {\n        mg_printf(nc, \"%s: SSI tag is too large\", path);\n        len = 0;\n      }\n      buf[len++] = ch & 0xff;\n    }\n    else\n    {\n      buf[len++] = ch & 0xff;\n      if (len == (int)sizeof(buf))\n      {\n        mg_send(nc, buf, (size_t)len);\n        len = 0;\n      }\n    }\n  }\n\n  /* Send the rest of buffered data */\n  if (len > 0)\n  {\n    mg_send(nc, buf, (size_t)len);\n  }\n}\n\nMG_INTERNAL void mg_handle_ssi_request(struct mg_connection *nc,\n                                       struct http_message *hm,\n                                       const char *path,\n                                       const struct mg_serve_http_opts *opts)\n{\n  FILE *fp;\n  struct mg_str mime_type;\n  DBG((\"%p %s\", nc, path));\n\n  if ((fp = fopen(path, \"rb\")) == NULL)\n  {\n    mg_http_send_error(nc, 404, NULL);\n  }\n  else\n  {\n    mg_set_close_on_exec((sock_t)fileno(fp));\n\n    mime_type = mg_get_mime_type(path, \"text/plain\", opts);\n    mg_send_response_line(nc, 200, opts->extra_headers);\n    mg_printf(nc,\n              \"Content-Type: %.*s\\r\\n\"\n              \"Connection: close\\r\\n\\r\\n\",\n              (int)mime_type.len, mime_type.p);\n    mg_send_ssi_file(nc, hm, path, fp, 0, opts);\n    fclose(fp);\n    nc->flags |= MG_F_SEND_AND_CLOSE;\n  }\n}\n\n#endif /* MG_ENABLE_HTTP_SSI && MG_ENABLE_HTTP && MG_ENABLE_FILESYSTEM */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/http_webdav.c\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#if MG_ENABLE_HTTP && MG_ENABLE_HTTP_WEBDAV\n\nMG_INTERNAL int mg_is_dav_request(const struct mg_str *s)\n{\n  static const char *methods[] = {\n    \"PUT\",\n    \"DELETE\",\n    \"MKCOL\",\n    \"PROPFIND\",\n    \"MOVE\"\n#if MG_ENABLE_FAKE_DAVLOCK\n    ,\n    \"LOCK\",\n    \"UNLOCK\"\n#endif\n  };\n  size_t i;\n\n  for (i = 0; i < ARRAY_SIZE(methods); i++)\n  {\n    if (mg_vcmp(s, methods[i]) == 0)\n    {\n      return 1;\n    }\n  }\n\n  return 0;\n}\n\nstatic int mg_mkdir(const char *path, uint32_t mode)\n{\n#ifndef _WIN32\n  return mkdir(path, mode);\n#else\n  (void)mode;\n  return _mkdir(path);\n#endif\n}\n\nstatic void mg_print_props(struct mg_connection *nc, const char *name,\n                           cs_stat_t *stp)\n{\n  char mtime[64], buf[MAX_PATH_SIZE * 3];\n  time_t t = stp->st_mtime; /* store in local variable for NDK compile */\n  mg_gmt_time_string(mtime, sizeof(mtime), &t);\n  mg_url_encode(name, strlen(name), buf, sizeof(buf));\n  mg_printf(nc,\n            \"<d:response>\"\n            \"<d:href>%s</d:href>\"\n            \"<d:propstat>\"\n            \"<d:prop>\"\n            \"<d:resourcetype>%s</d:resourcetype>\"\n            \"<d:getcontentlength>%\" INT64_FMT\n            \"</d:getcontentlength>\"\n            \"<d:getlastmodified>%s</d:getlastmodified>\"\n            \"</d:prop>\"\n            \"<d:status>HTTP/1.1 200 OK</d:status>\"\n            \"</d:propstat>\"\n            \"</d:response>\\n\",\n            buf, S_ISDIR(stp->st_mode) ? \"<d:collection/>\" : \"\",\n            (int64_t)stp->st_size, mtime);\n}\n\nMG_INTERNAL void mg_handle_propfind(struct mg_connection *nc, const char *path,\n                                    cs_stat_t *stp, struct http_message *hm,\n                                    struct mg_serve_http_opts *opts)\n{\n  static const char header[] =\n      \"HTTP/1.1 207 Multi-Status\\r\\n\"\n      \"Connection: close\\r\\n\"\n      \"Content-Type: text/xml; charset=utf-8\\r\\n\\r\\n\"\n      \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\"\n      \"<d:multistatus xmlns:d='DAV:'>\\n\";\n  static const char footer[] = \"</d:multistatus>\\n\";\n  const struct mg_str *depth = mg_get_http_header(hm, \"Depth\");\n\n  /* Print properties for the requested resource itself */\n  if (S_ISDIR(stp->st_mode) &&\n      strcmp(opts->enable_directory_listing, \"yes\") != 0)\n  {\n    mg_printf(nc, \"%s\", \"HTTP/1.1 403 Directory Listing Denied\\r\\n\\r\\n\");\n  }\n  else\n  {\n    char uri[MAX_PATH_SIZE];\n    mg_send(nc, header, sizeof(header) - 1);\n    snprintf(uri, sizeof(uri), \"%.*s\", (int)hm->uri.len, hm->uri.p);\n    mg_print_props(nc, uri, stp);\n    if (S_ISDIR(stp->st_mode) && (depth == NULL || mg_vcmp(depth, \"0\") != 0))\n    {\n      mg_scan_directory(nc, path, opts, mg_print_props);\n    }\n    mg_send(nc, footer, sizeof(footer) - 1);\n    nc->flags |= MG_F_SEND_AND_CLOSE;\n  }\n}\n\n#if MG_ENABLE_FAKE_DAVLOCK\n/*\n * Windows explorer (probably there are another WebDav clients like it)\n * requires LOCK support in webdav. W/out this, it still works, but fails\n * to save file: shows error message and offers \"Save As\".\n * \"Save as\" works, but this message is very annoying.\n * This is fake lock, which doesn't lock something, just returns LOCK token,\n * UNLOCK always answers \"OK\".\n * With this fake LOCK Windows Explorer looks happy and saves file.\n * NOTE: that is not DAV LOCK imlementation, it is just a way to shut up\n * Windows native DAV client. This is why FAKE LOCK is not enabed by default\n */\nMG_INTERNAL void mg_handle_lock(struct mg_connection *nc, const char *path)\n{\n  static const char *reply =\n      \"HTTP/1.1 207 Multi-Status\\r\\n\"\n      \"Connection: close\\r\\n\"\n      \"Content-Type: text/xml; charset=utf-8\\r\\n\\r\\n\"\n      \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\"\n      \"<d:multistatus xmlns:d='DAV:'>\\n\"\n      \"<D:lockdiscovery>\\n\"\n      \"<D:activelock>\\n\"\n      \"<D:locktoken>\\n\"\n      \"<D:href>\\n\"\n      \"opaquelocktoken:%s%u\"\n      \"</D:href>\"\n      \"</D:locktoken>\"\n      \"</D:activelock>\\n\"\n      \"</D:lockdiscovery>\"\n      \"</d:multistatus>\\n\";\n  mg_printf(nc, reply, path, (unsigned int)mg_time());\n  nc->flags |= MG_F_SEND_AND_CLOSE;\n}\n#endif\n\nMG_INTERNAL void mg_handle_mkcol(struct mg_connection *nc, const char *path,\n                                 struct http_message *hm)\n{\n  int status_code = 500;\n  if (hm->body.len != (size_t)~0 && hm->body.len > 0)\n  {\n    status_code = 415;\n  }\n  else if (!mg_mkdir(path, 0755))\n  {\n    status_code = 201;\n  }\n  else if (errno == EEXIST)\n  {\n    status_code = 405;\n  }\n  else if (errno == EACCES)\n  {\n    status_code = 403;\n  }\n  else if (errno == ENOENT)\n  {\n    status_code = 409;\n  }\n  else\n  {\n    status_code = 500;\n  }\n  mg_http_send_error(nc, status_code, NULL);\n}\n\nstatic int mg_remove_directory(const struct mg_serve_http_opts *opts,\n                               const char *dir)\n{\n  char path[MAX_PATH_SIZE];\n  struct dirent *dp;\n  cs_stat_t st;\n  DIR *dirp;\n\n  if ((dirp = opendir(dir)) == NULL)\n    return 0;\n\n  while ((dp = readdir(dirp)) != NULL)\n  {\n    if (mg_is_file_hidden((const char *)dp->d_name, opts, 1))\n    {\n      continue;\n    }\n    snprintf(path, sizeof(path), \"%s%c%s\", dir, '/', dp->d_name);\n    mg_stat(path, &st);\n    if (S_ISDIR(st.st_mode))\n    {\n      mg_remove_directory(opts, path);\n    }\n    else\n    {\n      remove(path);\n    }\n  }\n  closedir(dirp);\n  rmdir(dir);\n\n  return 1;\n}\n\nMG_INTERNAL void mg_handle_move(struct mg_connection *c,\n                                const struct mg_serve_http_opts *opts,\n                                const char *path, struct http_message *hm)\n{\n  const struct mg_str *dest = mg_get_http_header(hm, \"Destination\");\n  if (dest == NULL)\n  {\n    mg_http_send_error(c, 411, NULL);\n  }\n  else\n  {\n    const char *p = (char *)memchr(dest->p, '/', dest->len);\n    if (p != NULL && p[1] == '/' &&\n        (p = (char *)memchr(p + 2, '/', dest->p + dest->len - p)) != NULL)\n    {\n      char buf[MAX_PATH_SIZE];\n      snprintf(buf, sizeof(buf), \"%s%.*s\", opts->dav_document_root,\n               (int)(dest->p + dest->len - p), p);\n      if (rename(path, buf) == 0)\n      {\n        mg_http_send_error(c, 200, NULL);\n      }\n      else\n      {\n        mg_http_send_error(c, 418, NULL);\n      }\n    }\n    else\n    {\n      mg_http_send_error(c, 500, NULL);\n    }\n  }\n}\n\nMG_INTERNAL void mg_handle_delete(struct mg_connection *nc,\n                                  const struct mg_serve_http_opts *opts,\n                                  const char *path)\n{\n  cs_stat_t st;\n  if (mg_stat(path, &st) != 0)\n  {\n    mg_http_send_error(nc, 404, NULL);\n  }\n  else if (S_ISDIR(st.st_mode))\n  {\n    mg_remove_directory(opts, path);\n    mg_http_send_error(nc, 204, NULL);\n  }\n  else if (remove(path) == 0)\n  {\n    mg_http_send_error(nc, 204, NULL);\n  }\n  else\n  {\n    mg_http_send_error(nc, 423, NULL);\n  }\n}\n\n/* Return -1 on error, 1 on success. */\nstatic int mg_create_itermediate_directories(const char *path)\n{\n  const char *s;\n\n  /* Create intermediate directories if they do not exist */\n  for (s = path + 1; *s != '\\0'; s++)\n  {\n    if (*s == '/')\n    {\n      char buf[MAX_PATH_SIZE];\n      cs_stat_t st;\n      snprintf(buf, sizeof(buf), \"%.*s\", (int)(s - path), path);\n      buf[sizeof(buf) - 1] = '\\0';\n      if (mg_stat(buf, &st) != 0 && mg_mkdir(buf, 0755) != 0)\n      {\n        return -1;\n      }\n    }\n  }\n\n  return 1;\n}\n\nMG_INTERNAL void mg_handle_put(struct mg_connection *nc, const char *path,\n                               struct http_message *hm)\n{\n  struct mg_http_proto_data *pd = mg_http_get_proto_data(nc);\n  cs_stat_t st;\n  const struct mg_str *cl_hdr = mg_get_http_header(hm, \"Content-Length\");\n  int rc, status_code = mg_stat(path, &st) == 0 ? 200 : 201;\n\n  mg_http_free_proto_data_file(&pd->file);\n  if ((rc = mg_create_itermediate_directories(path)) == 0)\n  {\n    mg_printf(nc, \"HTTP/1.1 %d OK\\r\\nContent-Length: 0\\r\\n\\r\\n\", status_code);\n  }\n  else if (rc == -1)\n  {\n    mg_http_send_error(nc, 500, NULL);\n  }\n  else if (cl_hdr == NULL)\n  {\n    mg_http_send_error(nc, 411, NULL);\n  }\n  else if ((pd->file.fp = fopen(path, \"w+b\")) == NULL)\n  {\n    mg_http_send_error(nc, 500, NULL);\n  }\n  else\n  {\n    const struct mg_str *range_hdr = mg_get_http_header(hm, \"Content-Range\");\n    int64_t r1 = 0, r2 = 0;\n    pd->file.type = DATA_PUT;\n    mg_set_close_on_exec((sock_t)fileno(pd->file.fp));\n    pd->file.cl = to64(cl_hdr->p);\n    if (range_hdr != NULL &&\n        mg_http_parse_range_header(range_hdr, &r1, &r2) > 0)\n    {\n      status_code = 206;\n      fseeko(pd->file.fp, r1, SEEK_SET);\n      pd->file.cl = r2 > r1 ? r2 - r1 + 1 : pd->file.cl - r1;\n    }\n    mg_printf(nc, \"HTTP/1.1 %d OK\\r\\nContent-Length: 0\\r\\n\\r\\n\", status_code);\n    /* Remove HTTP request from the mbuf, leave only payload */\n    mbuf_remove(&nc->recv_mbuf, hm->message.len - hm->body.len);\n    mg_http_transfer_file_data(nc);\n  }\n}\n\n#endif /* MG_ENABLE_HTTP && MG_ENABLE_HTTP_WEBDAV */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/http_websocket.c\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n */\n\n#if MG_ENABLE_HTTP && MG_ENABLE_HTTP_WEBSOCKET\n\n#ifndef MG_WEBSOCKET_PING_INTERVAL_SECONDS\n#define MG_WEBSOCKET_PING_INTERVAL_SECONDS 5\n#endif\n\n#define MG_WS_NO_HOST_HEADER_MAGIC ((char *)0x1)\n\nstatic int mg_is_ws_fragment(unsigned char flags)\n{\n  return (flags & 0x80) == 0 || (flags & 0x0f) == 0;\n}\n\nstatic int mg_is_ws_first_fragment(unsigned char flags)\n{\n  return (flags & 0x80) == 0 && (flags & 0x0f) != 0;\n}\n\nstatic void mg_handle_incoming_websocket_frame(struct mg_connection *nc,\n                                               struct websocket_message *wsm)\n{\n  if (wsm->flags & 0x8)\n  {\n    mg_call(nc, nc->handler, MG_EV_WEBSOCKET_CONTROL_FRAME, wsm);\n  }\n  else\n  {\n    mg_call(nc, nc->handler, MG_EV_WEBSOCKET_FRAME, wsm);\n  }\n}\n\nstatic int mg_deliver_websocket_data(struct mg_connection *nc)\n{\n  /* Using unsigned char *, cause of integer arithmetic below */\n  uint64_t i, data_len = 0, frame_len = 0, buf_len = nc->recv_mbuf.len, len,\n              mask_len = 0, header_len = 0;\n  unsigned char *p = (unsigned char *)nc->recv_mbuf.buf, *buf = p,\n                *e = p + buf_len;\n  unsigned *sizep = (unsigned *)&p[1]; /* Size ptr for defragmented frames */\n  int ok, reass = buf_len > 0 && mg_is_ws_fragment(p[0]) &&\n                  !(nc->flags & MG_F_WEBSOCKET_NO_DEFRAG);\n\n  /* If that's a continuation frame that must be reassembled, handle it */\n  if (reass && !mg_is_ws_first_fragment(p[0]) &&\n      buf_len >= 1 + sizeof(*sizep) && buf_len >= 1 + sizeof(*sizep) + *sizep)\n  {\n    buf += 1 + sizeof(*sizep) + *sizep;\n    buf_len -= 1 + sizeof(*sizep) + *sizep;\n  }\n\n  if (buf_len >= 2)\n  {\n    len = buf[1] & 127;\n    mask_len = buf[1] & 128 ? 4 : 0;\n    if (len < 126 && buf_len >= mask_len)\n    {\n      data_len = len;\n      header_len = 2 + mask_len;\n    }\n    else if (len == 126 && buf_len >= 4 + mask_len)\n    {\n      header_len = 4 + mask_len;\n      data_len = ntohs(*(uint16_t *)&buf[2]);\n    }\n    else if (buf_len >= 10 + mask_len)\n    {\n      header_len = 10 + mask_len;\n      data_len = (((uint64_t)ntohl(*(uint32_t *)&buf[2])) << 32) +\n                 ntohl(*(uint32_t *)&buf[6]);\n    }\n  }\n\n  frame_len = header_len + data_len;\n  ok = frame_len > 0 && frame_len <= buf_len;\n\n  if (ok)\n  {\n    struct websocket_message wsm;\n\n    wsm.size = (size_t)data_len;\n    wsm.data = buf + header_len;\n    wsm.flags = buf[0];\n\n    /* Apply mask if necessary */\n    if (mask_len > 0)\n    {\n      for (i = 0; i < data_len; i++)\n      {\n        buf[i + header_len] ^= (buf + header_len - mask_len)[i % 4];\n      }\n    }\n\n    if (reass)\n    {\n      /* On first fragmented frame, nullify size */\n      if (mg_is_ws_first_fragment(wsm.flags))\n      {\n        mbuf_resize(&nc->recv_mbuf, nc->recv_mbuf.size + sizeof(*sizep));\n        p[0] &= ~0x0f; /* Next frames will be treated as continuation */\n        buf = p + 1 + sizeof(*sizep);\n        *sizep = 0; /* TODO(lsm): fix. this can stomp over frame data */\n      }\n\n      /* Append this frame to the reassembled buffer */\n      memmove(buf, wsm.data, e - wsm.data);\n      (*sizep) += wsm.size;\n      nc->recv_mbuf.len -= wsm.data - buf;\n\n      /* On last fragmented frame - call user handler and remove data */\n      if (wsm.flags & 0x80)\n      {\n        wsm.data = p + 1 + sizeof(*sizep);\n        wsm.size = *sizep;\n        mg_handle_incoming_websocket_frame(nc, &wsm);\n        mbuf_remove(&nc->recv_mbuf, 1 + sizeof(*sizep) + *sizep);\n      }\n    }\n    else\n    {\n      /* TODO(lsm): properly handle OOB control frames during defragmentation */\n      mg_handle_incoming_websocket_frame(nc, &wsm);\n      mbuf_remove(&nc->recv_mbuf, (size_t)frame_len); /* Cleanup frame */\n    }\n\n    /* If client closes, close too */\n    if ((buf[0] & 0x0f) == WEBSOCKET_OP_CLOSE)\n    {\n      nc->flags |= MG_F_SEND_AND_CLOSE;\n    }\n  }\n\n  return ok;\n}\n\nstruct ws_mask_ctx\n{\n  size_t pos; /* zero means unmasked */\n  uint32_t mask;\n};\n\nstatic uint32_t mg_ws_random_mask(void)\n{\n  uint32_t mask;\n/*\n * The spec requires WS client to generate hard to\n * guess mask keys. From RFC6455, Section 5.3:\n *\n * The unpredictability of the masking key is essential to prevent\n * authors of malicious applications from selecting the bytes that appear on\n * the wire.\n *\n * Hence this feature is essential when the actual end user of this API\n * is untrusted code that wouldn't have access to a lower level net API\n * anyway (e.g. web browsers). Hence this feature is low prio for most\n * mongoose use cases and thus can be disabled, e.g. when porting to a platform\n * that lacks rand().\n */\n#if MG_DISABLE_WS_RANDOM_MASK\n  mask = 0xefbeadde; /* generated with a random number generator, I swear */\n#else\n  if (sizeof(long) >= 4)\n  {\n    mask = (uint32_t)rand();\n  }\n  else if (sizeof(long) == 2)\n  {\n    mask = (uint32_t)rand() << 16 | (uint32_t)rand();\n  }\n#endif\n  return mask;\n}\n\nstatic void mg_send_ws_header(struct mg_connection *nc, int op, size_t len,\n                              struct ws_mask_ctx *ctx)\n{\n  int header_len;\n  unsigned char header[10];\n\n  header[0] = (op & WEBSOCKET_DONT_FIN ? 0x0 : 0x80) + (op & 0x0f);\n  if (len < 126)\n  {\n    header[1] = (unsigned char)len;\n    header_len = 2;\n  }\n  else if (len < 65535)\n  {\n    uint16_t tmp = htons((uint16_t)len);\n    header[1] = 126;\n    memcpy(&header[2], &tmp, sizeof(tmp));\n    header_len = 4;\n  }\n  else\n  {\n    uint32_t tmp;\n    header[1] = 127;\n    tmp = htonl((uint32_t)((uint64_t)len >> 32));\n    memcpy(&header[2], &tmp, sizeof(tmp));\n    tmp = htonl((uint32_t)(len & 0xffffffff));\n    memcpy(&header[6], &tmp, sizeof(tmp));\n    header_len = 10;\n  }\n\n  /* client connections enable masking */\n  if (nc->listener == NULL)\n  {\n    header[1] |= 1 << 7; /* set masking flag */\n    mg_send(nc, header, header_len);\n    ctx->mask = mg_ws_random_mask();\n    mg_send(nc, &ctx->mask, sizeof(ctx->mask));\n    ctx->pos = nc->send_mbuf.len;\n  }\n  else\n  {\n    mg_send(nc, header, header_len);\n    ctx->pos = 0;\n  }\n}\n\nstatic void mg_ws_mask_frame(struct mbuf *mbuf, struct ws_mask_ctx *ctx)\n{\n  size_t i;\n  if (ctx->pos == 0)\n    return;\n  for (i = 0; i < (mbuf->len - ctx->pos); i++)\n  {\n    mbuf->buf[ctx->pos + i] ^= ((char *)&ctx->mask)[i % 4];\n  }\n}\n\nvoid mg_send_websocket_frame(struct mg_connection *nc, int op, const void *data,\n                             size_t len)\n{\n  struct ws_mask_ctx ctx;\n  DBG((\"%p %d %d\", nc, op, (int)len));\n  mg_send_ws_header(nc, op, len, &ctx);\n  mg_send(nc, data, len);\n\n  mg_ws_mask_frame(&nc->send_mbuf, &ctx);\n\n  if (op == WEBSOCKET_OP_CLOSE)\n  {\n    nc->flags |= MG_F_SEND_AND_CLOSE;\n  }\n}\n\nvoid mg_send_websocket_framev(struct mg_connection *nc, int op,\n                              const struct mg_str *strv, int strvcnt)\n{\n  struct ws_mask_ctx ctx;\n  int i;\n  int len = 0;\n  for (i = 0; i < strvcnt; i++)\n  {\n    len += strv[i].len;\n  }\n\n  mg_send_ws_header(nc, op, len, &ctx);\n\n  for (i = 0; i < strvcnt; i++)\n  {\n    mg_send(nc, strv[i].p, strv[i].len);\n  }\n\n  mg_ws_mask_frame(&nc->send_mbuf, &ctx);\n\n  if (op == WEBSOCKET_OP_CLOSE)\n  {\n    nc->flags |= MG_F_SEND_AND_CLOSE;\n  }\n}\n\nvoid mg_printf_websocket_frame(struct mg_connection *nc, int op,\n                               const char *fmt, ...)\n{\n  char mem[MG_VPRINTF_BUFFER_SIZE], *buf = mem;\n  va_list ap;\n  int len;\n\n  va_start(ap, fmt);\n  if ((len = mg_avprintf(&buf, sizeof(mem), fmt, ap)) > 0)\n  {\n    mg_send_websocket_frame(nc, op, buf, len);\n  }\n  va_end(ap);\n\n  if (buf != mem && buf != NULL)\n  {\n    MG_FREE(buf);\n  }\n}\n\nMG_INTERNAL void mg_ws_handler(struct mg_connection *nc, int ev,\n                               void *ev_data)\n{\n  mg_call(nc, nc->handler, ev, ev_data);\n\n  switch (ev)\n  {\n  case MG_EV_RECV:\n    do\n    {\n    } while (mg_deliver_websocket_data(nc));\n    break;\n  case MG_EV_POLL:\n    /* Ping idle websocket connections */\n    {\n      time_t now = *(time_t *)ev_data;\n      if (nc->flags & MG_F_IS_WEBSOCKET &&\n          now > nc->last_io_time + MG_WEBSOCKET_PING_INTERVAL_SECONDS)\n      {\n        mg_send_websocket_frame(nc, WEBSOCKET_OP_PING, \"\", 0);\n      }\n    }\n    break;\n  default:\n    break;\n  }\n}\n\n#ifndef MG_EXT_SHA1\nstatic void mg_hash_sha1_v(size_t num_msgs, const uint8_t *msgs[],\n                           const size_t *msg_lens, uint8_t *digest)\n{\n  size_t i;\n  cs_sha1_ctx sha_ctx;\n  cs_sha1_init(&sha_ctx);\n  for (i = 0; i < num_msgs; i++)\n  {\n    cs_sha1_update(&sha_ctx, msgs[i], msg_lens[i]);\n  }\n  cs_sha1_final(digest, &sha_ctx);\n}\n#else\nextern void mg_hash_sha1_v(size_t num_msgs, const uint8_t *msgs[],\n                           const size_t *msg_lens, uint8_t *digest);\n#endif\n\nMG_INTERNAL void mg_ws_handshake(struct mg_connection *nc,\n                                 const struct mg_str *key)\n{\n  static const char *magic = \"258EAFA5-E914-47DA-95CA-C5AB0DC85B11\";\n  const uint8_t *msgs[2] = {(const uint8_t *)key->p, (const uint8_t *)magic};\n  const size_t msg_lens[2] = {key->len, 36};\n  unsigned char sha[20];\n  char b64_sha[30];\n\n  mg_hash_sha1_v(2, msgs, msg_lens, sha);\n  mg_base64_encode(sha, sizeof(sha), b64_sha);\n  mg_printf(nc, \"%s%s%s\",\n            \"HTTP/1.1 101 Switching Protocols\\r\\n\"\n            \"Upgrade: websocket\\r\\n\"\n            \"Connection: Upgrade\\r\\n\"\n            \"Sec-WebSocket-Accept: \",\n            b64_sha, \"\\r\\n\\r\\n\");\n  DBG((\"%p %.*s %s\", nc, (int)key->len, key->p, b64_sha));\n}\n\nvoid mg_send_websocket_handshake2(struct mg_connection *nc, const char *path,\n                                  const char *host, const char *protocol,\n                                  const char *extra_headers)\n{\n  mg_send_websocket_handshake3(nc, path, host, protocol, extra_headers, NULL,\n                               NULL);\n}\n\nvoid mg_send_websocket_handshake3(struct mg_connection *nc, const char *path,\n                                  const char *host, const char *protocol,\n                                  const char *extra_headers, const char *user,\n                                  const char *pass)\n{\n  struct mbuf auth;\n  char key[25];\n  uint32_t nonce[4];\n  nonce[0] = mg_ws_random_mask();\n  nonce[1] = mg_ws_random_mask();\n  nonce[2] = mg_ws_random_mask();\n  nonce[3] = mg_ws_random_mask();\n  mg_base64_encode((unsigned char *)&nonce, sizeof(nonce), key);\n\n  mbuf_init(&auth, 0);\n  if (user != NULL)\n  {\n    mg_basic_auth_header(user, pass, &auth);\n  }\n\n  /*\n   * NOTE: the  (auth.buf == NULL ? \"\" : auth.buf) is because cc3200 libc is\n   * broken: it doesn't like zero length to be passed to %.*s\n   * i.e. sprintf(\"f%.*so\", (int)0, NULL), yields `f\\0o`.\n   * because it handles NULL specially (and incorrectly).\n   */\n  mg_printf(nc,\n            \"GET %s HTTP/1.1\\r\\n\"\n            \"Upgrade: websocket\\r\\n\"\n            \"Connection: Upgrade\\r\\n\"\n            \"%.*s\"\n            \"Sec-WebSocket-Version: 13\\r\\n\"\n            \"Sec-WebSocket-Key: %s\\r\\n\",\n            path, (int)auth.len, (auth.buf == NULL ? \"\" : auth.buf), key);\n\n  /* TODO(mkm): take default hostname from http proto data if host == NULL */\n  if (host != MG_WS_NO_HOST_HEADER_MAGIC)\n  {\n    mg_printf(nc, \"Host: %s\\r\\n\", host);\n  }\n  if (protocol != NULL)\n  {\n    mg_printf(nc, \"Sec-WebSocket-Protocol: %s\\r\\n\", protocol);\n  }\n  if (extra_headers != NULL)\n  {\n    mg_printf(nc, \"%s\", extra_headers);\n  }\n  mg_printf(nc, \"\\r\\n\");\n\n  mbuf_free(&auth);\n}\n\nvoid mg_send_websocket_handshake(struct mg_connection *nc, const char *path,\n                                 const char *extra_headers)\n{\n  mg_send_websocket_handshake2(nc, path, MG_WS_NO_HOST_HEADER_MAGIC, NULL,\n                               extra_headers);\n}\n\nstruct mg_connection *mg_connect_ws_opt(struct mg_mgr *mgr,\n                                        mg_event_handler_t ev_handler,\n                                        struct mg_connect_opts opts,\n                                        const char *url, const char *protocol,\n                                        const char *extra_headers)\n{\n  char *user = NULL, *pass = NULL, *addr = NULL;\n  const char *path = NULL;\n  struct mg_connection *nc =\n      mg_connect_http_base(mgr, ev_handler, opts, \"ws://\", \"wss://\", url, &path,\n                           &user, &pass, &addr);\n\n  if (nc != NULL)\n  {\n    mg_send_websocket_handshake3(nc, path, addr, protocol, extra_headers, user,\n                                 pass);\n  }\n\n  MG_FREE(addr);\n  MG_FREE(user);\n  MG_FREE(pass);\n  return nc;\n}\n\nstruct mg_connection *mg_connect_ws(struct mg_mgr *mgr,\n                                    mg_event_handler_t ev_handler,\n                                    const char *url, const char *protocol,\n                                    const char *extra_headers)\n{\n  struct mg_connect_opts opts;\n  memset(&opts, 0, sizeof(opts));\n  return mg_connect_ws_opt(mgr, ev_handler, opts, url, protocol, extra_headers);\n}\n#endif /* MG_ENABLE_HTTP && MG_ENABLE_HTTP_WEBSOCKET */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/util.c\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n */\n\n/* Amalgamated: #include \"common/base64.h\" */\n/* Amalgamated: #include \"mongoose/src/internal.h\" */\n/* Amalgamated: #include \"mongoose/src/util.h\" */\n\n/* For platforms with limited libc */\n#ifndef MAX\n#define MAX(a, b) ((a) > (b) ? (a) : (b))\n#endif\n\nconst char *mg_skip(const char *s, const char *end, const char *delims,\n                    struct mg_str *v)\n{\n  v->p = s;\n  while (s < end && strchr(delims, *(unsigned char *)s) == NULL)\n    s++;\n  v->len = s - v->p;\n  while (s < end && strchr(delims, *(unsigned char *)s) != NULL)\n    s++;\n  return s;\n}\n\nstatic int lowercase(const char *s)\n{\n  return tolower(*(const unsigned char *)s);\n}\n\n#if MG_ENABLE_FILESYSTEM\nint mg_stat(const char *path, cs_stat_t *st)\n{\n#ifdef _WIN32\n  wchar_t wpath[MAX_PATH_SIZE];\n  to_wchar(path, wpath, ARRAY_SIZE(wpath));\n  DBG((\"[%ls] -> %d\", wpath, _wstati64(wpath, st)));\n  return _wstati64(wpath, (struct _stati64 *)st);\n#else\n  return stat(path, st);\n#endif\n}\n\nFILE *mg_fopen(const char *path, const char *mode)\n{\n#ifdef _WIN32\n  wchar_t wpath[MAX_PATH_SIZE], wmode[10];\n  to_wchar(path, wpath, ARRAY_SIZE(wpath));\n  to_wchar(mode, wmode, ARRAY_SIZE(wmode));\n  return _wfopen(wpath, wmode);\n#else\n  return fopen(path, mode);\n#endif\n}\n\nint mg_open(const char *path, int flag, int mode)\n{ /* LCOV_EXCL_LINE */\n#if defined(_WIN32) && !defined(WINCE)\n  wchar_t wpath[MAX_PATH_SIZE];\n  to_wchar(path, wpath, ARRAY_SIZE(wpath));\n  return _wopen(wpath, flag, mode);\n#else\n  return open(path, flag, mode); /* LCOV_EXCL_LINE */\n#endif\n}\n#endif\n\nvoid mg_base64_encode(const unsigned char *src, int src_len, char *dst)\n{\n  cs_base64_encode(src, src_len, dst);\n}\n\nint mg_base64_decode(const unsigned char *s, int len, char *dst)\n{\n  return cs_base64_decode(s, len, dst);\n}\n\n#if MG_ENABLE_THREADS\nvoid *mg_start_thread(void *(*f)(void *), void *p)\n{\n#ifdef WINCE\n  return (void *)CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)f, p, 0, NULL);\n#elif defined(_WIN32)\n  return (void *)_beginthread((void(__cdecl *)(void *))f, 0, p);\n#else\n  pthread_t thread_id = (pthread_t)0;\n  pthread_attr_t attr;\n\n  (void)pthread_attr_init(&attr);\n  (void)pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);\n\n#if defined(MG_STACK_SIZE) && MG_STACK_SIZE > 1\n  (void)pthread_attr_setstacksize(&attr, MG_STACK_SIZE);\n#endif\n\n  pthread_create(&thread_id, &attr, f, p);\n  pthread_attr_destroy(&attr);\n\n  return (void *)thread_id;\n#endif\n}\n#endif /* MG_ENABLE_THREADS */\n\n/* Set close-on-exec bit for a given socket. */\nvoid mg_set_close_on_exec(sock_t sock)\n{\n#if defined(_WIN32) && !defined(WINCE)\n  (void)SetHandleInformation((HANDLE)sock, HANDLE_FLAG_INHERIT, 0);\n#elif defined(__unix__)\n  fcntl(sock, F_SETFD, FD_CLOEXEC);\n#else\n  (void)sock;\n#endif\n}\n\nvoid mg_sock_addr_to_str(const union socket_address *sa, char *buf, size_t len,\n                         int flags)\n{\n  int is_v6;\n  if (buf == NULL || len <= 0)\n    return;\n  buf[0] = '\\0';\n#if MG_ENABLE_IPV6\n  is_v6 = sa->sa.sa_family == AF_INET6;\n#else\n  is_v6 = 0;\n#endif\n  if (flags & MG_SOCK_STRINGIFY_IP)\n  {\n#if MG_ENABLE_IPV6\n    const void *addr = NULL;\n    char *start = buf;\n    socklen_t capacity = len;\n    if (!is_v6)\n    {\n      addr = &sa->sin.sin_addr;\n    }\n    else\n    {\n      addr = (void *)&sa->sin6.sin6_addr;\n      if (flags & MG_SOCK_STRINGIFY_PORT)\n      {\n        *buf = '[';\n        start++;\n        capacity--;\n      }\n    }\n    if (inet_ntop(sa->sa.sa_family, addr, start, capacity) == NULL)\n    {\n      *buf = '\\0';\n    }\n#elif defined(_WIN32) || MG_LWIP || (MG_NET_IF == MG_NET_IF_PIC32_HARMONY)\n    /* Only Windoze Vista (and newer) have inet_ntop() */\n    strncpy(buf, inet_ntoa(sa->sin.sin_addr), len);\n#else\n    inet_ntop(AF_INET, (void *)&sa->sin.sin_addr, buf, len);\n#endif\n  }\n  if (flags & MG_SOCK_STRINGIFY_PORT)\n  {\n    int port = ntohs(sa->sin.sin_port);\n    if (flags & MG_SOCK_STRINGIFY_IP)\n    {\n      snprintf(buf + strlen(buf), len - (strlen(buf) + 1), \"%s:%d\",\n               (is_v6 ? \"]\" : \"\"), port);\n    }\n    else\n    {\n      snprintf(buf, len, \"%d\", port);\n    }\n  }\n}\n\nvoid mg_conn_addr_to_str(struct mg_connection *nc, char *buf, size_t len,\n                         int flags)\n{\n  union socket_address sa;\n  memset(&sa, 0, sizeof(sa));\n  mg_if_get_conn_addr(nc, flags & MG_SOCK_STRINGIFY_REMOTE, &sa);\n  mg_sock_addr_to_str(&sa, buf, len, flags);\n}\n\n#if MG_ENABLE_HEXDUMP\nint mg_hexdump(const void *buf, int len, char *dst, int dst_len)\n{\n  const unsigned char *p = (const unsigned char *)buf;\n  char ascii[17] = \"\";\n  int i, idx, n = 0;\n\n  for (i = 0; i < len; i++)\n  {\n    idx = i % 16;\n    if (idx == 0)\n    {\n      if (i > 0)\n        n += snprintf(dst + n, MAX(dst_len - n, 0), \"  %s\\n\", ascii);\n      n += snprintf(dst + n, MAX(dst_len - n, 0), \"%04x \", i);\n    }\n    if (dst_len - n < 0)\n    {\n      return n;\n    }\n    n += snprintf(dst + n, MAX(dst_len - n, 0), \" %02x\", p[i]);\n    ascii[idx] = p[i] < 0x20 || p[i] > 0x7e ? '.' : p[i];\n    ascii[idx + 1] = '\\0';\n  }\n\n  while (i++ % 16)\n    n += snprintf(dst + n, MAX(dst_len - n, 0), \"%s\", \"   \");\n  n += snprintf(dst + n, MAX(dst_len - n, 0), \"  %s\\n\\n\", ascii);\n\n  return n;\n}\n\nvoid mg_hexdump_connection(struct mg_connection *nc, const char *path,\n                           const void *buf, int num_bytes, int ev)\n{\n  FILE *fp = NULL;\n  char *hexbuf, src[60], dst[60];\n  int buf_size = num_bytes * 5 + 100;\n\n  if (strcmp(path, \"-\") == 0)\n  {\n    fp = stdout;\n  }\n  else if (strcmp(path, \"--\") == 0)\n  {\n    fp = stderr;\n#if MG_ENABLE_FILESYSTEM\n  }\n  else\n  {\n    fp = fopen(path, \"a\");\n#endif\n  }\n  if (fp == NULL)\n    return;\n\n  mg_conn_addr_to_str(nc, src, sizeof(src),\n                      MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT);\n  mg_conn_addr_to_str(nc, dst, sizeof(dst), MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT | MG_SOCK_STRINGIFY_REMOTE);\n  fprintf(\n      fp, \"%lu %p %s %s %s %d\\n\", (unsigned long)mg_time(), (void *)nc, src,\n      ev == MG_EV_RECV ? \"<-\" : ev == MG_EV_SEND ? \"->\" : ev == MG_EV_ACCEPT ? \"<A\" : ev == MG_EV_CONNECT ? \"C>\" : \"XX\",\n      dst, num_bytes);\n  if (num_bytes > 0 && (hexbuf = (char *)MG_MALLOC(buf_size)) != NULL)\n  {\n    mg_hexdump(buf, num_bytes, hexbuf, buf_size);\n    fprintf(fp, \"%s\", hexbuf);\n    MG_FREE(hexbuf);\n  }\n  if (fp != stdin && fp != stdout)\n    fclose(fp);\n}\n#endif\n\nint mg_is_big_endian(void)\n{\n  static const int n = 1;\n  /* TODO(mkm) use compiletime check with 4-byte char literal */\n  return ((char *)&n)[0] == 0;\n}\n\nconst char *mg_next_comma_list_entry(const char *list, struct mg_str *val,\n                                     struct mg_str *eq_val)\n{\n  if (list == NULL || *list == '\\0')\n  {\n    /* End of the list */\n    list = NULL;\n  }\n  else\n  {\n    val->p = list;\n    if ((list = strchr(val->p, ',')) != NULL)\n    {\n      /* Comma found. Store length and shift the list ptr */\n      val->len = list - val->p;\n      list++;\n    }\n    else\n    {\n      /* This value is the last one */\n      list = val->p + strlen(val->p);\n      val->len = list - val->p;\n    }\n\n    if (eq_val != NULL)\n    {\n      /* Value has form \"x=y\", adjust pointers and lengths */\n      /* so that val points to \"x\", and eq_val points to \"y\". */\n      eq_val->len = 0;\n      eq_val->p = (const char *)memchr(val->p, '=', val->len);\n      if (eq_val->p != NULL)\n      {\n        eq_val->p++; /* Skip over '=' character */\n        eq_val->len = val->p + val->len - eq_val->p;\n        val->len = (eq_val->p - val->p) - 1;\n      }\n    }\n  }\n\n  return list;\n}\n\nint mg_match_prefix_n(const struct mg_str pattern, const struct mg_str str)\n{\n  const char *or_str;\n  size_t len, i = 0, j = 0;\n  int res;\n\n  if ((or_str = (const char *)memchr(pattern.p, '|', pattern.len)) != NULL)\n  {\n    struct mg_str pstr = {pattern.p, (size_t)(or_str - pattern.p)};\n    res = mg_match_prefix_n(pstr, str);\n    if (res > 0)\n      return res;\n    pstr.p = or_str + 1;\n    pstr.len = (pattern.p + pattern.len) - (or_str + 1);\n    return mg_match_prefix_n(pstr, str);\n  }\n\n  for (; i < pattern.len; i++, j++)\n  {\n    if (pattern.p[i] == '?' && j != str.len)\n    {\n      continue;\n    }\n    else if (pattern.p[i] == '$')\n    {\n      return j == str.len ? (int)j : -1;\n    }\n    else if (pattern.p[i] == '*')\n    {\n      i++;\n      if (pattern.p[i] == '*')\n      {\n        i++;\n        len = str.len - j;\n      }\n      else\n      {\n        len = 0;\n        while (j + len != str.len && str.p[j + len] != '/')\n        {\n          len++;\n        }\n      }\n      if (i == pattern.len)\n      {\n        return j + len;\n      }\n      do\n      {\n        const struct mg_str pstr = {pattern.p + i, pattern.len - i};\n        const struct mg_str sstr = {str.p + j + len, str.len - j - len};\n        res = mg_match_prefix_n(pstr, sstr);\n      } while (res == -1 && len-- > 0);\n      return res == -1 ? -1 : (int)(j + res + len);\n    }\n    else if (lowercase(&pattern.p[i]) != lowercase(&str.p[j]))\n    {\n      return -1;\n    }\n  }\n  return j;\n}\n\nint mg_match_prefix(const char *pattern, int pattern_len, const char *str)\n{\n  const struct mg_str pstr = {pattern, (size_t)pattern_len};\n  return mg_match_prefix_n(pstr, mg_mk_str(str));\n}\n\nMG_INTERNAL int mg_get_errno(void)\n{\n#ifndef WINCE\n  return errno;\n#else\n  /* TODO(alashkin): translate error codes? */\n  return GetLastError();\n#endif\n}\n\nvoid mg_mbuf_append_base64_putc(char ch, void *user_data)\n{\n  struct mbuf *mbuf = (struct mbuf *)user_data;\n  mbuf_append(mbuf, &ch, sizeof(ch));\n}\n\nvoid mg_mbuf_append_base64(struct mbuf *mbuf, const void *data, size_t len)\n{\n  struct cs_base64_ctx ctx;\n  cs_base64_init(&ctx, mg_mbuf_append_base64_putc, mbuf);\n  cs_base64_update(&ctx, (const char *)data, len);\n  cs_base64_finish(&ctx);\n}\n\nvoid mg_basic_auth_header(const char *user, const char *pass,\n                          struct mbuf *buf)\n{\n  const char *header_prefix = \"Authorization: Basic \";\n  const char *header_suffix = \"\\r\\n\";\n\n  struct cs_base64_ctx ctx;\n  cs_base64_init(&ctx, mg_mbuf_append_base64_putc, buf);\n\n  mbuf_append(buf, header_prefix, strlen(header_prefix));\n\n  cs_base64_update(&ctx, user, strlen(user));\n  if (pass != NULL)\n  {\n    cs_base64_update(&ctx, \":\", 1);\n    cs_base64_update(&ctx, pass, strlen(pass));\n  }\n  cs_base64_finish(&ctx);\n  mbuf_append(buf, header_suffix, strlen(header_suffix));\n}\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/mqtt.c\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n */\n\n#if MG_ENABLE_MQTT\n\n#include <string.h>\n\n/* Amalgamated: #include \"mongoose/src/internal.h\" */\n/* Amalgamated: #include \"mongoose/src/mqtt.h\" */\n\nstatic const char *scanto(const char *p, struct mg_str *s)\n{\n  s->len = ntohs(*(uint16_t *)p);\n  s->p = p + 2;\n  return p + 2 + s->len;\n}\n\nMG_INTERNAL int parse_mqtt(struct mbuf *io, struct mg_mqtt_message *mm)\n{\n  uint8_t header;\n  size_t len = 0;\n  int cmd;\n  const char *p = &io->buf[1], *end;\n\n  if (io->len < 2)\n    return -1;\n  header = io->buf[0];\n  cmd = header >> 4;\n\n  /* decode mqtt variable length */\n  do\n  {\n    len += (*p & 127) << 7 * (p - &io->buf[1]);\n  } while ((*p++ & 128) != 0 && ((size_t)(p - io->buf) <= io->len));\n\n  end = p + len;\n  if (end > io->buf + io->len + 1)\n  {\n    return -1;\n  }\n\n  mm->cmd = cmd;\n  mm->qos = MG_MQTT_GET_QOS(header);\n\n  switch (cmd)\n  {\n  case MG_MQTT_CMD_CONNECT:\n  {\n    p = scanto(p, &mm->protocol_name);\n    mm->protocol_version = *(uint8_t *)p++;\n    mm->connect_flags = *(uint8_t *)p++;\n    mm->keep_alive_timer = ntohs(*(uint16_t *)p);\n    p += 2;\n    if (p < end)\n      p = scanto(p, &mm->client_id);\n    if (p < end && (mm->connect_flags & MG_MQTT_HAS_WILL))\n      p = scanto(p, &mm->will_topic);\n    if (p < end && (mm->connect_flags & MG_MQTT_HAS_WILL))\n      p = scanto(p, &mm->will_message);\n    if (p < end && (mm->connect_flags & MG_MQTT_HAS_USER_NAME))\n      p = scanto(p, &mm->user_name);\n    if (p < end && (mm->connect_flags & MG_MQTT_HAS_PASSWORD))\n      p = scanto(p, &mm->password);\n\n    LOG(LL_DEBUG,\n        (\"%d %2x %d proto [%.*s] client_id [%.*s] will_topic [%.*s] \"\n         \"will_msg [%.*s] user_name [%.*s] password [%.*s]\",\n         len, (int)mm->connect_flags, (int)mm->keep_alive_timer,\n         (int)mm->protocol_name.len, mm->protocol_name.p,\n         (int)mm->client_id.len, mm->client_id.p, (int)mm->will_topic.len,\n         mm->will_topic.p, (int)mm->will_message.len, mm->will_message.p,\n         (int)mm->user_name.len, mm->user_name.p, (int)mm->password.len,\n         mm->password.p));\n    break;\n  }\n  case MG_MQTT_CMD_CONNACK:\n    mm->connack_ret_code = p[1];\n    break;\n  case MG_MQTT_CMD_PUBACK:\n  case MG_MQTT_CMD_PUBREC:\n  case MG_MQTT_CMD_PUBREL:\n  case MG_MQTT_CMD_PUBCOMP:\n  case MG_MQTT_CMD_SUBACK:\n    mm->message_id = ntohs(*(uint16_t *)p);\n    break;\n  case MG_MQTT_CMD_PUBLISH:\n  {\n    if (MG_MQTT_GET_QOS(header) > 0)\n    {\n      mm->message_id = ntohs(*(uint16_t *)io->buf);\n      p += 2;\n    }\n    p = scanto(p, &mm->topic);\n\n    mm->payload.p = p;\n    mm->payload.len = end - p;\n    break;\n  }\n  case MG_MQTT_CMD_SUBSCRIBE:\n    mm->message_id = ntohs(*(uint16_t *)p);\n    p += 2;\n    /*\n       * topic expressions are left in the payload and can be parsed with\n       * `mg_mqtt_next_subscribe_topic`\n       */\n    mm->payload.p = p;\n    mm->payload.len = end - p;\n    break;\n  default:\n    /* Unhandled command */\n    break;\n  }\n\n  return end - io->buf;\n}\n\nstatic void mqtt_handler(struct mg_connection *nc, int ev, void *ev_data)\n{\n  int len;\n  struct mbuf *io = &nc->recv_mbuf;\n  struct mg_mqtt_message mm;\n  memset(&mm, 0, sizeof(mm));\n\n  nc->handler(nc, ev, ev_data);\n\n  switch (ev)\n  {\n  case MG_EV_RECV:\n    len = parse_mqtt(io, &mm);\n    if (len == -1)\n      break; /* not fully buffered */\n    nc->handler(nc, MG_MQTT_EVENT_BASE + mm.cmd, &mm);\n    mbuf_remove(io, len);\n    break;\n  }\n}\n\nstatic void mg_mqtt_proto_data_destructor(void *proto_data)\n{\n  MG_FREE(proto_data);\n}\n\nvoid mg_set_protocol_mqtt(struct mg_connection *nc)\n{\n  nc->proto_handler = mqtt_handler;\n  nc->proto_data = MG_CALLOC(1, sizeof(struct mg_mqtt_proto_data));\n  nc->proto_data_destructor = mg_mqtt_proto_data_destructor;\n}\n\nvoid mg_send_mqtt_handshake(struct mg_connection *nc, const char *client_id)\n{\n  static struct mg_send_mqtt_handshake_opts opts;\n  mg_send_mqtt_handshake_opt(nc, client_id, opts);\n}\n\nvoid mg_send_mqtt_handshake_opt(struct mg_connection *nc, const char *client_id,\n                                struct mg_send_mqtt_handshake_opts opts)\n{\n  uint8_t header = MG_MQTT_CMD_CONNECT << 4;\n  uint8_t rem_len;\n  uint16_t keep_alive;\n  uint16_t len;\n  struct mg_mqtt_proto_data *pd = (struct mg_mqtt_proto_data *)nc->proto_data;\n\n  /*\n   * 9: version_header(len, magic_string, version_number), 1: flags, 2:\n   * keep-alive timer,\n   * 2: client_identifier_len, n: client_id\n   */\n  rem_len = 9 + 1 + 2 + 2 + (uint8_t)strlen(client_id);\n\n  if (opts.user_name != NULL)\n  {\n    opts.flags |= MG_MQTT_HAS_USER_NAME;\n    rem_len += (uint8_t)strlen(opts.user_name) + 2;\n  }\n  if (opts.password != NULL)\n  {\n    opts.flags |= MG_MQTT_HAS_PASSWORD;\n    rem_len += (uint8_t)strlen(opts.password) + 2;\n  }\n\n  mg_send(nc, &header, 1);\n  mg_send(nc, &rem_len, 1);\n  mg_send(nc, \"\\00\\06MQIsdp\\03\", 9);\n  mg_send(nc, &opts.flags, 1);\n\n  if (opts.keep_alive == 0)\n  {\n    opts.keep_alive = 60;\n  }\n\n  keep_alive = htons(opts.keep_alive);\n  mg_send(nc, &keep_alive, 2);\n\n  len = htons((uint16_t)strlen(client_id));\n  mg_send(nc, &len, 2);\n  mg_send(nc, client_id, strlen(client_id));\n\n  if (opts.flags & MG_MQTT_HAS_USER_NAME)\n  {\n    len = htons((uint16_t)strlen(opts.user_name));\n    mg_send(nc, &len, 2);\n    mg_send(nc, opts.user_name, strlen(opts.user_name));\n  }\n  if (opts.flags & MG_MQTT_HAS_PASSWORD)\n  {\n    len = htons((uint16_t)strlen(opts.password));\n    mg_send(nc, &len, 2);\n    mg_send(nc, opts.password, strlen(opts.password));\n  }\n\n  if (pd != NULL)\n  {\n    pd->keep_alive = opts.keep_alive;\n  }\n}\n\nstatic void mg_mqtt_prepend_header(struct mg_connection *nc, uint8_t cmd,\n                                   uint8_t flags, size_t len)\n{\n  size_t off = nc->send_mbuf.len - len;\n  uint8_t header = cmd << 4 | (uint8_t)flags;\n\n  uint8_t buf[1 + sizeof(size_t)];\n  uint8_t *vlen = &buf[1];\n\n  assert(nc->send_mbuf.len >= len);\n\n  buf[0] = header;\n\n  /* mqtt variable length encoding */\n  do\n  {\n    *vlen = len % 0x80;\n    len /= 0x80;\n    if (len > 0)\n      *vlen |= 0x80;\n    vlen++;\n  } while (len > 0);\n\n  mbuf_insert(&nc->send_mbuf, off, buf, vlen - buf);\n}\n\nvoid mg_mqtt_publish(struct mg_connection *nc, const char *topic,\n                     uint16_t message_id, int flags, const void *data,\n                     size_t len)\n{\n  size_t old_len = nc->send_mbuf.len;\n\n  uint16_t topic_len = htons((uint16_t)strlen(topic));\n  uint16_t message_id_net = htons(message_id);\n\n  mg_send(nc, &topic_len, 2);\n  mg_send(nc, topic, strlen(topic));\n  if (MG_MQTT_GET_QOS(flags) > 0)\n  {\n    mg_send(nc, &message_id_net, 2);\n  }\n  mg_send(nc, data, len);\n\n  mg_mqtt_prepend_header(nc, MG_MQTT_CMD_PUBLISH, flags,\n                         nc->send_mbuf.len - old_len);\n}\n\nvoid mg_mqtt_subscribe(struct mg_connection *nc,\n                       const struct mg_mqtt_topic_expression *topics,\n                       size_t topics_len, uint16_t message_id)\n{\n  size_t old_len = nc->send_mbuf.len;\n\n  uint16_t message_id_n = htons(message_id);\n  size_t i;\n\n  mg_send(nc, (char *)&message_id_n, 2);\n  for (i = 0; i < topics_len; i++)\n  {\n    uint16_t topic_len_n = htons((uint16_t)strlen(topics[i].topic));\n    mg_send(nc, &topic_len_n, 2);\n    mg_send(nc, topics[i].topic, strlen(topics[i].topic));\n    mg_send(nc, &topics[i].qos, 1);\n  }\n\n  mg_mqtt_prepend_header(nc, MG_MQTT_CMD_SUBSCRIBE, MG_MQTT_QOS(1),\n                         nc->send_mbuf.len - old_len);\n}\n\nint mg_mqtt_next_subscribe_topic(struct mg_mqtt_message *msg,\n                                 struct mg_str *topic, uint8_t *qos, int pos)\n{\n  unsigned char *buf = (unsigned char *)msg->payload.p + pos;\n\n  if ((size_t)pos >= msg->payload.len)\n  {\n    return -1;\n  }\n\n  topic->len = buf[0] << 8 | buf[1];\n  topic->p = (char *)buf + 2;\n  *qos = buf[2 + topic->len];\n  return pos + 2 + topic->len + 1;\n}\n\nvoid mg_mqtt_unsubscribe(struct mg_connection *nc, char **topics,\n                         size_t topics_len, uint16_t message_id)\n{\n  size_t old_len = nc->send_mbuf.len;\n\n  uint16_t message_id_n = htons(message_id);\n  size_t i;\n\n  mg_send(nc, (char *)&message_id_n, 2);\n  for (i = 0; i < topics_len; i++)\n  {\n    uint16_t topic_len_n = htons((uint16_t)strlen(topics[i]));\n    mg_send(nc, &topic_len_n, 2);\n    mg_send(nc, topics[i], strlen(topics[i]));\n  }\n\n  mg_mqtt_prepend_header(nc, MG_MQTT_CMD_UNSUBSCRIBE, MG_MQTT_QOS(1),\n                         nc->send_mbuf.len - old_len);\n}\n\nvoid mg_mqtt_connack(struct mg_connection *nc, uint8_t return_code)\n{\n  uint8_t unused = 0;\n  mg_send(nc, &unused, 1);\n  mg_send(nc, &return_code, 1);\n  mg_mqtt_prepend_header(nc, MG_MQTT_CMD_CONNACK, 0, 2);\n}\n\n/*\n * Sends a command which contains only a `message_id` and a QoS level of 1.\n *\n * Helper function.\n */\nstatic void mg_send_mqtt_short_command(struct mg_connection *nc, uint8_t cmd,\n                                       uint16_t message_id)\n{\n  uint16_t message_id_net = htons(message_id);\n  mg_send(nc, &message_id_net, 2);\n  mg_mqtt_prepend_header(nc, cmd, MG_MQTT_QOS(1), 2);\n}\n\nvoid mg_mqtt_puback(struct mg_connection *nc, uint16_t message_id)\n{\n  mg_send_mqtt_short_command(nc, MG_MQTT_CMD_PUBACK, message_id);\n}\n\nvoid mg_mqtt_pubrec(struct mg_connection *nc, uint16_t message_id)\n{\n  mg_send_mqtt_short_command(nc, MG_MQTT_CMD_PUBREC, message_id);\n}\n\nvoid mg_mqtt_pubrel(struct mg_connection *nc, uint16_t message_id)\n{\n  mg_send_mqtt_short_command(nc, MG_MQTT_CMD_PUBREL, message_id);\n}\n\nvoid mg_mqtt_pubcomp(struct mg_connection *nc, uint16_t message_id)\n{\n  mg_send_mqtt_short_command(nc, MG_MQTT_CMD_PUBCOMP, message_id);\n}\n\nvoid mg_mqtt_suback(struct mg_connection *nc, uint8_t *qoss, size_t qoss_len,\n                    uint16_t message_id)\n{\n  size_t i;\n  uint16_t message_id_net = htons(message_id);\n  mg_send(nc, &message_id_net, 2);\n  for (i = 0; i < qoss_len; i++)\n  {\n    mg_send(nc, &qoss[i], 1);\n  }\n  mg_mqtt_prepend_header(nc, MG_MQTT_CMD_SUBACK, MG_MQTT_QOS(1), 2 + qoss_len);\n}\n\nvoid mg_mqtt_unsuback(struct mg_connection *nc, uint16_t message_id)\n{\n  mg_send_mqtt_short_command(nc, MG_MQTT_CMD_UNSUBACK, message_id);\n}\n\nvoid mg_mqtt_ping(struct mg_connection *nc)\n{\n  mg_mqtt_prepend_header(nc, MG_MQTT_CMD_PINGREQ, 0, 0);\n}\n\nvoid mg_mqtt_pong(struct mg_connection *nc)\n{\n  mg_mqtt_prepend_header(nc, MG_MQTT_CMD_PINGRESP, 0, 0);\n}\n\nvoid mg_mqtt_disconnect(struct mg_connection *nc)\n{\n  mg_mqtt_prepend_header(nc, MG_MQTT_CMD_DISCONNECT, 0, 0);\n}\n\n#endif /* MG_ENABLE_MQTT */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/mqtt_server.c\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n */\n\n/* Amalgamated: #include \"mongoose/src/internal.h\" */\n/* Amalgamated: #include \"mongoose/src/mqtt-server.h\" */\n\n#if MG_ENABLE_MQTT_BROKER\n\nstatic void mg_mqtt_session_init(struct mg_mqtt_broker *brk,\n                                 struct mg_mqtt_session *s,\n                                 struct mg_connection *nc)\n{\n  s->brk = brk;\n  s->subscriptions = NULL;\n  s->num_subscriptions = 0;\n  s->nc = nc;\n}\n\nstatic void mg_mqtt_add_session(struct mg_mqtt_session *s)\n{\n  LIST_INSERT_HEAD(&s->brk->sessions, s, link);\n}\n\nstatic void mg_mqtt_remove_session(struct mg_mqtt_session *s)\n{\n  LIST_REMOVE(s, link);\n}\n\nstatic void mg_mqtt_destroy_session(struct mg_mqtt_session *s)\n{\n  size_t i;\n  for (i = 0; i < s->num_subscriptions; i++)\n  {\n    MG_FREE((void *)s->subscriptions[i].topic);\n  }\n  MG_FREE(s->subscriptions);\n  MG_FREE(s);\n}\n\nstatic void mg_mqtt_close_session(struct mg_mqtt_session *s)\n{\n  mg_mqtt_remove_session(s);\n  mg_mqtt_destroy_session(s);\n}\n\nvoid mg_mqtt_broker_init(struct mg_mqtt_broker *brk, void *user_data)\n{\n  LIST_INIT(&brk->sessions);\n  brk->user_data = user_data;\n}\n\nstatic void mg_mqtt_broker_handle_connect(struct mg_mqtt_broker *brk,\n                                          struct mg_connection *nc)\n{\n  struct mg_mqtt_session *s = (struct mg_mqtt_session *)calloc(1, sizeof *s);\n  if (s == NULL)\n  {\n    /* LCOV_EXCL_START */\n    mg_mqtt_connack(nc, MG_EV_MQTT_CONNACK_SERVER_UNAVAILABLE);\n    return;\n    /* LCOV_EXCL_STOP */\n  }\n\n  /* TODO(mkm): check header (magic and version) */\n\n  mg_mqtt_session_init(brk, s, nc);\n  s->user_data = nc->user_data;\n  nc->user_data = s;\n  mg_mqtt_add_session(s);\n\n  mg_mqtt_connack(nc, MG_EV_MQTT_CONNACK_ACCEPTED);\n}\n\nstatic void mg_mqtt_broker_handle_subscribe(struct mg_connection *nc,\n                                            struct mg_mqtt_message *msg)\n{\n  struct mg_mqtt_session *ss = (struct mg_mqtt_session *)nc->user_data;\n  uint8_t qoss[512];\n  size_t qoss_len = 0;\n  struct mg_str topic;\n  uint8_t qos;\n  int pos;\n  struct mg_mqtt_topic_expression *te;\n\n  for (pos = 0;\n       (pos = mg_mqtt_next_subscribe_topic(msg, &topic, &qos, pos)) != -1;)\n  {\n    qoss[qoss_len++] = qos;\n  }\n\n  ss->subscriptions = (struct mg_mqtt_topic_expression *)realloc(\n      ss->subscriptions, sizeof(*ss->subscriptions) * qoss_len);\n  for (pos = 0;\n       (pos = mg_mqtt_next_subscribe_topic(msg, &topic, &qos, pos)) != -1;\n       ss->num_subscriptions++)\n  {\n    te = &ss->subscriptions[ss->num_subscriptions];\n    te->topic = (char *)malloc(topic.len + 1);\n    te->qos = qos;\n    strncpy((char *)te->topic, topic.p, topic.len + 1);\n  }\n\n  mg_mqtt_suback(nc, qoss, qoss_len, msg->message_id);\n}\n\n/*\n * Matches a topic against a topic expression\n *\n * See http://goo.gl/iWk21X\n *\n * Returns 1 if it matches; 0 otherwise.\n */\nstatic int mg_mqtt_match_topic_expression(const char *exp,\n                                          const struct mg_str *topic)\n{\n  /* TODO(mkm): implement real matching */\n  size_t len = strlen(exp);\n  if (strchr(exp, '#'))\n  {\n    len -= 2;\n    if (topic->len < len)\n    {\n      len = topic->len;\n    }\n  }\n  return strncmp(topic->p, exp, len) == 0;\n}\n\nstatic void mg_mqtt_broker_handle_publish(struct mg_mqtt_broker *brk,\n                                          struct mg_mqtt_message *msg)\n{\n  struct mg_mqtt_session *s;\n  size_t i;\n\n  for (s = mg_mqtt_next(brk, NULL); s != NULL; s = mg_mqtt_next(brk, s))\n  {\n    for (i = 0; i < s->num_subscriptions; i++)\n    {\n      if (mg_mqtt_match_topic_expression(s->subscriptions[i].topic,\n                                         &msg->topic))\n      {\n        char buf[100], *p = buf;\n        mg_asprintf(&p, sizeof(buf), \"%.*s\", (int)msg->topic.len,\n                    msg->topic.p);\n        if (p == NULL)\n        {\n          return;\n        }\n        mg_mqtt_publish(s->nc, p, 0, 0, msg->payload.p, msg->payload.len);\n        if (p != buf)\n        {\n          MG_FREE(p);\n        }\n        break;\n      }\n    }\n  }\n}\n\nvoid mg_mqtt_broker(struct mg_connection *nc, int ev, void *data)\n{\n  struct mg_mqtt_message *msg = (struct mg_mqtt_message *)data;\n  struct mg_mqtt_broker *brk;\n\n  if (nc->listener)\n  {\n    brk = (struct mg_mqtt_broker *)nc->listener->user_data;\n  }\n  else\n  {\n    brk = (struct mg_mqtt_broker *)nc->user_data;\n  }\n\n  switch (ev)\n  {\n  case MG_EV_ACCEPT:\n    mg_set_protocol_mqtt(nc);\n    nc->user_data = NULL; /* Clear up the inherited pointer to broker */\n    break;\n  case MG_EV_MQTT_CONNECT:\n    mg_mqtt_broker_handle_connect(brk, nc);\n    break;\n  case MG_EV_MQTT_SUBSCRIBE:\n    mg_mqtt_broker_handle_subscribe(nc, msg);\n    break;\n  case MG_EV_MQTT_PUBLISH:\n    mg_mqtt_broker_handle_publish(brk, msg);\n    break;\n  case MG_EV_CLOSE:\n    if (nc->listener && nc->user_data != NULL)\n    {\n      mg_mqtt_close_session((struct mg_mqtt_session *)nc->user_data);\n    }\n    break;\n  }\n}\n\nstruct mg_mqtt_session *mg_mqtt_next(struct mg_mqtt_broker *brk,\n                                     struct mg_mqtt_session *s)\n{\n  return s == NULL ? LIST_FIRST(&brk->sessions) : LIST_NEXT(s, link);\n}\n\n#endif /* MG_ENABLE_MQTT_BROKER */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/dns.c\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n */\n\n#if MG_ENABLE_DNS\n\n/* Amalgamated: #include \"mongoose/src/internal.h\" */\n/* Amalgamated: #include \"mongoose/src/dns.h\" */\n\nstatic int mg_dns_tid = 0xa0;\n\nstruct mg_dns_header\n{\n  uint16_t transaction_id;\n  uint16_t flags;\n  uint16_t num_questions;\n  uint16_t num_answers;\n  uint16_t num_authority_prs;\n  uint16_t num_other_prs;\n};\n\nstruct mg_dns_resource_record *mg_dns_next_record(\n    struct mg_dns_message *msg, int query,\n    struct mg_dns_resource_record *prev)\n{\n  struct mg_dns_resource_record *rr;\n\n  for (rr = (prev == NULL ? msg->answers : prev + 1);\n       rr - msg->answers < msg->num_answers; rr++)\n  {\n    if (rr->rtype == query)\n    {\n      return rr;\n    }\n  }\n  return NULL;\n}\n\nint mg_dns_parse_record_data(struct mg_dns_message *msg,\n                             struct mg_dns_resource_record *rr, void *data,\n                             size_t data_len)\n{\n  switch (rr->rtype)\n  {\n  case MG_DNS_A_RECORD:\n    if (data_len < sizeof(struct in_addr))\n    {\n      return -1;\n    }\n    if (rr->rdata.p + data_len > msg->pkt.p + msg->pkt.len)\n    {\n      return -1;\n    }\n    memcpy(data, rr->rdata.p, data_len);\n    return 0;\n#if MG_ENABLE_IPV6\n  case MG_DNS_AAAA_RECORD:\n    if (data_len < sizeof(struct in6_addr))\n    {\n      return -1; /* LCOV_EXCL_LINE */\n    }\n    memcpy(data, rr->rdata.p, data_len);\n    return 0;\n#endif\n  case MG_DNS_CNAME_RECORD:\n    mg_dns_uncompress_name(msg, &rr->rdata, (char *)data, data_len);\n    return 0;\n  }\n\n  return -1;\n}\n\nint mg_dns_insert_header(struct mbuf *io, size_t pos,\n                         struct mg_dns_message *msg)\n{\n  struct mg_dns_header header;\n\n  memset(&header, 0, sizeof(header));\n  header.transaction_id = msg->transaction_id;\n  header.flags = htons(msg->flags);\n  header.num_questions = htons(msg->num_questions);\n  header.num_answers = htons(msg->num_answers);\n\n  return mbuf_insert(io, pos, &header, sizeof(header));\n}\n\nint mg_dns_copy_questions(struct mbuf *io, struct mg_dns_message *msg)\n{\n  unsigned char *begin, *end;\n  struct mg_dns_resource_record *last_q;\n  if (msg->num_questions <= 0)\n    return 0;\n  begin = (unsigned char *)msg->pkt.p + sizeof(struct mg_dns_header);\n  last_q = &msg->questions[msg->num_questions - 1];\n  end = (unsigned char *)last_q->name.p + last_q->name.len + 4;\n  return mbuf_append(io, begin, end - begin);\n}\n\nint mg_dns_encode_name(struct mbuf *io, const char *name, size_t len)\n{\n  const char *s;\n  unsigned char n;\n  size_t pos = io->len;\n\n  do\n  {\n    if ((s = strchr(name, '.')) == NULL)\n    {\n      s = name + len;\n    }\n\n    if (s - name > 127)\n    {\n      return -1; /* TODO(mkm) cover */\n    }\n    n = s - name;           /* chunk length */\n    mbuf_append(io, &n, 1); /* send length */\n    mbuf_append(io, name, n);\n\n    if (*s == '.')\n    {\n      n++;\n    }\n\n    name += n;\n    len -= n;\n  } while (*s != '\\0');\n  mbuf_append(io, \"\\0\", 1); /* Mark end of host name */\n\n  return io->len - pos;\n}\n\nint mg_dns_encode_record(struct mbuf *io, struct mg_dns_resource_record *rr,\n                         const char *name, size_t nlen, const void *rdata,\n                         size_t rlen)\n{\n  size_t pos = io->len;\n  uint16_t u16;\n  uint32_t u32;\n\n  if (rr->kind == MG_DNS_INVALID_RECORD)\n  {\n    return -1; /* LCOV_EXCL_LINE */\n  }\n\n  if (mg_dns_encode_name(io, name, nlen) == -1)\n  {\n    return -1;\n  }\n\n  u16 = htons(rr->rtype);\n  mbuf_append(io, &u16, 2);\n  u16 = htons(rr->rclass);\n  mbuf_append(io, &u16, 2);\n\n  if (rr->kind == MG_DNS_ANSWER)\n  {\n    u32 = htonl(rr->ttl);\n    mbuf_append(io, &u32, 4);\n\n    if (rr->rtype == MG_DNS_CNAME_RECORD)\n    {\n      int clen;\n      /* fill size after encoding */\n      size_t off = io->len;\n      mbuf_append(io, &u16, 2);\n      if ((clen = mg_dns_encode_name(io, (const char *)rdata, rlen)) == -1)\n      {\n        return -1;\n      }\n      u16 = clen;\n      io->buf[off] = u16 >> 8;\n      io->buf[off + 1] = u16 & 0xff;\n    }\n    else\n    {\n      u16 = htons((uint16_t)rlen);\n      mbuf_append(io, &u16, 2);\n      mbuf_append(io, rdata, rlen);\n    }\n  }\n\n  return io->len - pos;\n}\n\nvoid mg_send_dns_query(struct mg_connection *nc, const char *name,\n                       int query_type)\n{\n  struct mg_dns_message *msg =\n      (struct mg_dns_message *)MG_CALLOC(1, sizeof(*msg));\n  struct mbuf pkt;\n  struct mg_dns_resource_record *rr = &msg->questions[0];\n\n  DBG((\"%s %d\", name, query_type));\n\n  mbuf_init(&pkt, 64 /* Start small, it'll grow as needed. */);\n\n  msg->transaction_id = ++mg_dns_tid;\n  msg->flags = 0x100;\n  msg->num_questions = 1;\n\n  mg_dns_insert_header(&pkt, 0, msg);\n\n  rr->rtype = query_type;\n  rr->rclass = 1; /* Class: inet */\n  rr->kind = MG_DNS_QUESTION;\n\n  if (mg_dns_encode_record(&pkt, rr, name, strlen(name), NULL, 0) == -1)\n  {\n    /* TODO(mkm): return an error code */\n    goto cleanup; /* LCOV_EXCL_LINE */\n  }\n\n  /* TCP DNS requires messages to be prefixed with len */\n  if (!(nc->flags & MG_F_UDP))\n  {\n    uint16_t len = htons((uint16_t)pkt.len);\n    mbuf_insert(&pkt, 0, &len, 2);\n  }\n\n  mg_send(nc, pkt.buf, pkt.len);\n  mbuf_free(&pkt);\n\ncleanup:\n  MG_FREE(msg);\n}\n\nstatic unsigned char *mg_parse_dns_resource_record(\n    unsigned char *data, unsigned char *end, struct mg_dns_resource_record *rr,\n    int reply)\n{\n  unsigned char *name = data;\n  int chunk_len, data_len;\n\n  while (data < end && (chunk_len = *data))\n  {\n    if (((unsigned char *)data)[0] & 0xc0)\n    {\n      data += 1;\n      break;\n    }\n    data += chunk_len + 1;\n  }\n\n  if (data > end - 5)\n  {\n    return NULL;\n  }\n\n  rr->name.p = (char *)name;\n  rr->name.len = data - name + 1;\n  data++;\n\n  rr->rtype = data[0] << 8 | data[1];\n  data += 2;\n\n  rr->rclass = data[0] << 8 | data[1];\n  data += 2;\n\n  rr->kind = reply ? MG_DNS_ANSWER : MG_DNS_QUESTION;\n  if (reply)\n  {\n    if (data >= end - 6)\n    {\n      return NULL;\n    }\n\n    rr->ttl = (uint32_t)data[0] << 24 | (uint32_t)data[1] << 16 |\n              data[2] << 8 | data[3];\n    data += 4;\n\n    data_len = *data << 8 | *(data + 1);\n    data += 2;\n\n    rr->rdata.p = (char *)data;\n    rr->rdata.len = data_len;\n    data += data_len;\n  }\n  return data;\n}\n\nint mg_parse_dns(const char *buf, int len, struct mg_dns_message *msg)\n{\n  struct mg_dns_header *header = (struct mg_dns_header *)buf;\n  unsigned char *data = (unsigned char *)buf + sizeof(*header);\n  unsigned char *end = (unsigned char *)buf + len;\n  int i;\n\n  memset(msg, 0, sizeof(*msg));\n  msg->pkt.p = buf;\n  msg->pkt.len = len;\n\n  if (len < (int)sizeof(*header))\n    return -1;\n\n  msg->transaction_id = header->transaction_id;\n  msg->flags = ntohs(header->flags);\n  msg->num_questions = ntohs(header->num_questions);\n  if (msg->num_questions > (int)ARRAY_SIZE(msg->questions))\n  {\n    msg->num_questions = (int)ARRAY_SIZE(msg->questions);\n  }\n  msg->num_answers = ntohs(header->num_answers);\n  if (msg->num_answers > (int)ARRAY_SIZE(msg->answers))\n  {\n    msg->num_answers = (int)ARRAY_SIZE(msg->answers);\n  }\n\n  for (i = 0; i < msg->num_questions; i++)\n  {\n    data = mg_parse_dns_resource_record(data, end, &msg->questions[i], 0);\n    if (data == NULL)\n      return -1;\n  }\n\n  for (i = 0; i < msg->num_answers; i++)\n  {\n    data = mg_parse_dns_resource_record(data, end, &msg->answers[i], 1);\n    if (data == NULL)\n      return -1;\n  }\n\n  return 0;\n}\n\nsize_t mg_dns_uncompress_name(struct mg_dns_message *msg, struct mg_str *name,\n                              char *dst, int dst_len)\n{\n  int chunk_len;\n  char *old_dst = dst;\n  const unsigned char *data = (unsigned char *)name->p;\n  const unsigned char *end = (unsigned char *)msg->pkt.p + msg->pkt.len;\n\n  if (data >= end)\n  {\n    return 0;\n  }\n\n  while ((chunk_len = *data++))\n  {\n    int leeway = dst_len - (dst - old_dst);\n    if (data >= end)\n    {\n      return 0;\n    }\n\n    if (chunk_len & 0xc0)\n    {\n      uint16_t off = (data[-1] & (~0xc0)) << 8 | data[0];\n      if (off >= msg->pkt.len)\n      {\n        return 0;\n      }\n      data = (unsigned char *)msg->pkt.p + off;\n      continue;\n    }\n    if (chunk_len > leeway)\n    {\n      chunk_len = leeway;\n    }\n\n    if (data + chunk_len >= end)\n    {\n      return 0;\n    }\n\n    memcpy(dst, data, chunk_len);\n    data += chunk_len;\n    dst += chunk_len;\n    leeway -= chunk_len;\n    if (leeway == 0)\n    {\n      return dst - old_dst;\n    }\n    *dst++ = '.';\n  }\n\n  if (dst != old_dst)\n  {\n    *--dst = 0;\n  }\n  return dst - old_dst;\n}\n\nstatic void dns_handler(struct mg_connection *nc, int ev, void *ev_data)\n{\n  struct mbuf *io = &nc->recv_mbuf;\n  struct mg_dns_message msg;\n\n  /* Pass low-level events to the user handler */\n  nc->handler(nc, ev, ev_data);\n\n  switch (ev)\n  {\n  case MG_EV_RECV:\n    if (!(nc->flags & MG_F_UDP))\n    {\n      mbuf_remove(&nc->recv_mbuf, 2);\n    }\n    if (mg_parse_dns(nc->recv_mbuf.buf, nc->recv_mbuf.len, &msg) == -1)\n    {\n      /* reply + recursion allowed + format error */\n      memset(&msg, 0, sizeof(msg));\n      msg.flags = 0x8081;\n      mg_dns_insert_header(io, 0, &msg);\n      if (!(nc->flags & MG_F_UDP))\n      {\n        uint16_t len = htons((uint16_t)io->len);\n        mbuf_insert(io, 0, &len, 2);\n      }\n      mg_send(nc, io->buf, io->len);\n    }\n    else\n    {\n      /* Call user handler with parsed message */\n      nc->handler(nc, MG_DNS_MESSAGE, &msg);\n    }\n    mbuf_remove(io, io->len);\n    break;\n  }\n}\n\nvoid mg_set_protocol_dns(struct mg_connection *nc)\n{\n  nc->proto_handler = dns_handler;\n}\n\n#endif /* MG_ENABLE_DNS */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/dns_server.c\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n */\n\n#if MG_ENABLE_DNS_SERVER\n\n/* Amalgamated: #include \"mongoose/src/internal.h\" */\n/* Amalgamated: #include \"mongoose/src/dns-server.h\" */\n\nstruct mg_dns_reply mg_dns_create_reply(struct mbuf *io,\n                                        struct mg_dns_message *msg)\n{\n  struct mg_dns_reply rep;\n  rep.msg = msg;\n  rep.io = io;\n  rep.start = io->len;\n\n  /* reply + recursion allowed */\n  msg->flags |= 0x8080;\n  mg_dns_copy_questions(io, msg);\n\n  msg->num_answers = 0;\n  return rep;\n}\n\nvoid mg_dns_send_reply(struct mg_connection *nc, struct mg_dns_reply *r)\n{\n  size_t sent = r->io->len - r->start;\n  mg_dns_insert_header(r->io, r->start, r->msg);\n  if (!(nc->flags & MG_F_UDP))\n  {\n    uint16_t len = htons((uint16_t)sent);\n    mbuf_insert(r->io, r->start, &len, 2);\n  }\n\n  if (&nc->send_mbuf != r->io)\n  {\n    mg_send(nc, r->io->buf + r->start, r->io->len - r->start);\n    r->io->len = r->start;\n  }\n}\n\nint mg_dns_reply_record(struct mg_dns_reply *reply,\n                        struct mg_dns_resource_record *question,\n                        const char *name, int rtype, int ttl, const void *rdata,\n                        size_t rdata_len)\n{\n  struct mg_dns_message *msg = (struct mg_dns_message *)reply->msg;\n  char rname[512];\n  struct mg_dns_resource_record *ans = &msg->answers[msg->num_answers];\n  if (msg->num_answers >= MG_MAX_DNS_ANSWERS)\n  {\n    return -1; /* LCOV_EXCL_LINE */\n  }\n\n  if (name == NULL)\n  {\n    name = rname;\n    rname[511] = 0;\n    mg_dns_uncompress_name(msg, &question->name, rname, sizeof(rname) - 1);\n  }\n\n  *ans = *question;\n  ans->kind = MG_DNS_ANSWER;\n  ans->rtype = rtype;\n  ans->ttl = ttl;\n\n  if (mg_dns_encode_record(reply->io, ans, name, strlen(name), rdata,\n                           rdata_len) == -1)\n  {\n    return -1; /* LCOV_EXCL_LINE */\n  };\n\n  msg->num_answers++;\n  return 0;\n}\n\n#endif /* MG_ENABLE_DNS_SERVER */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/resolv.c\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n */\n\n#if MG_ENABLE_ASYNC_RESOLVER\n\n/* Amalgamated: #include \"mongoose/src/internal.h\" */\n/* Amalgamated: #include \"mongoose/src/resolv.h\" */\n\n#ifndef MG_DEFAULT_NAMESERVER\n#define MG_DEFAULT_NAMESERVER \"8.8.8.8\"\n#endif\n\nstatic const char *mg_default_dns_server = \"udp://\" MG_DEFAULT_NAMESERVER \":53\";\n\nMG_INTERNAL char mg_dns_server[256];\n\nstruct mg_resolve_async_request\n{\n  char name[1024];\n  int query;\n  mg_resolve_callback_t callback;\n  void *data;\n  time_t timeout;\n  int max_retries;\n  enum mg_resolve_err err;\n\n  /* state */\n  time_t last_time;\n  int retries;\n};\n\n/*\n * Find what nameserver to use.\n *\n * Return 0 if OK, -1 if error\n */\nstatic int mg_get_ip_address_of_nameserver(char *name, size_t name_len)\n{\n  int ret = -1;\n\n#ifdef _WIN32\n  int i;\n  LONG err;\n  HKEY hKey, hSub;\n  wchar_t subkey[512], value[128],\n      *key = L\"SYSTEM\\\\ControlSet001\\\\Services\\\\Tcpip\\\\Parameters\\\\Interfaces\";\n\n  if ((err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hKey)) !=\n      ERROR_SUCCESS)\n  {\n    fprintf(stderr, \"cannot open reg key %S: %ld\\n\", key, err);\n    ret = -1;\n  }\n  else\n  {\n    for (ret = -1, i = 0; 1; i++)\n    {\n      DWORD subkey_size = sizeof(subkey), type, len = sizeof(value);\n      if (RegEnumKeyExW(hKey, i, subkey, &subkey_size, NULL, NULL, NULL,\n                        NULL) != ERROR_SUCCESS)\n      {\n        break;\n      }\n      if (RegOpenKeyExW(hKey, subkey, 0, KEY_READ, &hSub) == ERROR_SUCCESS &&\n          (RegQueryValueExW(hSub, L\"NameServer\", 0, &type, (void *)value,\n                            &len) == ERROR_SUCCESS ||\n           RegQueryValueExW(hSub, L\"DhcpNameServer\", 0, &type, (void *)value,\n                            &len) == ERROR_SUCCESS))\n      {\n        /*\n         * See https://github.com/cesanta/mongoose/issues/176\n         * The value taken from the registry can be empty, a single\n         * IP address, or multiple IP addresses separated by comma.\n         * If it's empty, check the next interface.\n         * If it's multiple IP addresses, take the first one.\n         */\n        wchar_t *comma = wcschr(value, ',');\n        if (value[0] == '\\0')\n        {\n          continue;\n        }\n        if (comma != NULL)\n        {\n          *comma = '\\0';\n        }\n        snprintf(name, name_len, \"udp://%S:53\", value);\n        ret = 0;\n        RegCloseKey(hSub);\n        break;\n      }\n    }\n    RegCloseKey(hKey);\n  }\n#elif MG_ENABLE_FILESYSTEM\n  FILE *fp;\n  char line[512];\n\n  if ((fp = fopen(\"/etc/resolv.conf\", \"r\")) == NULL)\n  {\n    ret = -1;\n  }\n  else\n  {\n    /* Try to figure out what nameserver to use */\n    for (ret = -1; fgets(line, sizeof(line), fp) != NULL;)\n    {\n      char buf[256];\n      if (sscanf(line, \"nameserver %255[^\\n\\t #]s\", buf) == 1)\n      {\n        snprintf(name, name_len, \"udp://%s:53\", buf);\n        ret = 0;\n        break;\n      }\n    }\n    (void)fclose(fp);\n  }\n#else\n  snprintf(name, name_len, \"%s\", mg_default_dns_server);\n#endif /* _WIN32 */\n\n  return ret;\n}\n\nint mg_resolve_from_hosts_file(const char *name, union socket_address *usa)\n{\n#if MG_ENABLE_FILESYSTEM\n  /* TODO(mkm) cache /etc/hosts */\n  FILE *fp;\n  char line[1024];\n  char *p;\n  char alias[256];\n  unsigned int a, b, c, d;\n  int len = 0;\n\n  if ((fp = fopen(\"/etc/hosts\", \"r\")) == NULL)\n  {\n    return -1;\n  }\n\n  for (; fgets(line, sizeof(line), fp) != NULL;)\n  {\n    if (line[0] == '#')\n      continue;\n\n    if (sscanf(line, \"%u.%u.%u.%u%n\", &a, &b, &c, &d, &len) == 0)\n    {\n      /* TODO(mkm): handle ipv6 */\n      continue;\n    }\n    for (p = line + len; sscanf(p, \"%s%n\", alias, &len) == 1; p += len)\n    {\n      if (strcmp(alias, name) == 0)\n      {\n        usa->sin.sin_addr.s_addr = htonl(a << 24 | b << 16 | c << 8 | d);\n        fclose(fp);\n        return 0;\n      }\n    }\n  }\n\n  fclose(fp);\n#else\n  (void)name;\n  (void)usa;\n#endif\n\n  return -1;\n}\n\nstatic void mg_resolve_async_eh(struct mg_connection *nc, int ev, void *data)\n{\n  time_t now = (time_t)mg_time();\n  struct mg_resolve_async_request *req;\n  struct mg_dns_message *msg;\n  int first = 0;\n\n  DBG((\"ev=%d user_data=%p\", ev, nc->user_data));\n\n  req = (struct mg_resolve_async_request *)nc->user_data;\n\n  if (req == NULL)\n  {\n    return;\n  }\n\n  switch (ev)\n  {\n  case MG_EV_CONNECT:\n    /* don't depend on timer not being at epoch for sending out first req */\n    first = 1;\n  /* fallthrough */\n  case MG_EV_POLL:\n    if (req->retries > req->max_retries)\n    {\n      req->err = MG_RESOLVE_EXCEEDED_RETRY_COUNT;\n      nc->flags |= MG_F_CLOSE_IMMEDIATELY;\n      break;\n    }\n    if (first || now - req->last_time >= req->timeout)\n    {\n      mg_send_dns_query(nc, req->name, req->query);\n      req->last_time = now;\n      req->retries++;\n    }\n    break;\n  case MG_EV_RECV:\n    msg = (struct mg_dns_message *)MG_MALLOC(sizeof(*msg));\n    if (mg_parse_dns(nc->recv_mbuf.buf, *(int *)data, msg) == 0 &&\n        msg->num_answers > 0)\n    {\n      req->callback(msg, req->data, MG_RESOLVE_OK);\n      nc->user_data = NULL;\n      MG_FREE(req);\n    }\n    else\n    {\n      req->err = MG_RESOLVE_NO_ANSWERS;\n    }\n    MG_FREE(msg);\n    nc->flags |= MG_F_CLOSE_IMMEDIATELY;\n    break;\n  case MG_EV_SEND:\n    /*\n       * If a send error occurs, prevent closing of the connection by the core.\n       * We will retry after timeout.\n       */\n    nc->flags &= ~MG_F_CLOSE_IMMEDIATELY;\n    mbuf_remove(&nc->send_mbuf, nc->send_mbuf.len);\n    break;\n  case MG_EV_TIMER:\n    req->err = MG_RESOLVE_TIMEOUT;\n    nc->flags |= MG_F_CLOSE_IMMEDIATELY;\n    break;\n  case MG_EV_CLOSE:\n    /* If we got here with request still not done, fire an error callback. */\n    if (req != NULL)\n    {\n      req->callback(NULL, req->data, req->err);\n      nc->user_data = NULL;\n      MG_FREE(req);\n    }\n    break;\n  }\n}\n\nint mg_resolve_async(struct mg_mgr *mgr, const char *name, int query,\n                     mg_resolve_callback_t cb, void *data)\n{\n  struct mg_resolve_async_opts opts;\n  memset(&opts, 0, sizeof(opts));\n  return mg_resolve_async_opt(mgr, name, query, cb, data, opts);\n}\n\nint mg_resolve_async_opt(struct mg_mgr *mgr, const char *name, int query,\n                         mg_resolve_callback_t cb, void *data,\n                         struct mg_resolve_async_opts opts)\n{\n  struct mg_resolve_async_request *req;\n  struct mg_connection *dns_nc;\n  const char *nameserver = opts.nameserver_url;\n\n  DBG((\"%s %d %p\", name, query, opts.dns_conn));\n\n  /* resolve with DNS */\n  req = (struct mg_resolve_async_request *)MG_CALLOC(1, sizeof(*req));\n  if (req == NULL)\n  {\n    return -1;\n  }\n\n  strncpy(req->name, name, sizeof(req->name));\n  req->query = query;\n  req->callback = cb;\n  req->data = data;\n  /* TODO(mkm): parse defaults out of resolve.conf */\n  req->max_retries = opts.max_retries ? opts.max_retries : 2;\n  req->timeout = opts.timeout ? opts.timeout : 5;\n\n  /* Lazily initialize dns server */\n  if (nameserver == NULL && mg_dns_server[0] == '\\0' &&\n      mg_get_ip_address_of_nameserver(mg_dns_server, sizeof(mg_dns_server)) ==\n          -1)\n  {\n    strncpy(mg_dns_server, mg_default_dns_server, sizeof(mg_dns_server));\n  }\n\n  if (nameserver == NULL)\n  {\n    nameserver = mg_dns_server;\n  }\n\n  dns_nc = mg_connect(mgr, nameserver, mg_resolve_async_eh);\n  if (dns_nc == NULL)\n  {\n    free(req);\n    return -1;\n  }\n  dns_nc->user_data = req;\n  if (opts.dns_conn != NULL)\n  {\n    *opts.dns_conn = dns_nc;\n  }\n\n  return 0;\n}\n\n#endif /* MG_ENABLE_ASYNC_RESOLVER */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/coap.c\"\n#endif\n/*\n * Copyright (c) 2015 Cesanta Software Limited\n * All rights reserved\n * This software is dual-licensed: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation. For the terms of this\n * license, see <http://www.gnu.org/licenses/>.\n *\n * You are free to use this software under the terms of the GNU General\n * Public License, but WITHOUT ANY WARRANTY; without even the implied\n * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n * See the GNU General Public License for more details.\n *\n * Alternatively, you can license this software under a commercial\n * license, as set out in <https://www.cesanta.com/license>.\n */\n\n/* Amalgamated: #include \"mongoose/src/internal.h\" */\n/* Amalgamated: #include \"mongoose/src/coap.h\" */\n\n#if MG_ENABLE_COAP\n\nvoid mg_coap_free_options(struct mg_coap_message *cm)\n{\n  while (cm->options != NULL)\n  {\n    struct mg_coap_option *next = cm->options->next;\n    MG_FREE(cm->options);\n    cm->options = next;\n  }\n}\n\nstruct mg_coap_option *mg_coap_add_option(struct mg_coap_message *cm,\n                                          uint32_t number, char *value,\n                                          size_t len)\n{\n  struct mg_coap_option *new_option =\n      (struct mg_coap_option *)MG_CALLOC(1, sizeof(*new_option));\n\n  new_option->number = number;\n  new_option->value.p = value;\n  new_option->value.len = len;\n\n  if (cm->options == NULL)\n  {\n    cm->options = cm->optiomg_tail = new_option;\n  }\n  else\n  {\n    /*\n     * A very simple attention to help clients to compose options:\n     * CoAP wants to see options ASC ordered.\n     * Could be change by using sort in coap_compose\n     */\n    if (cm->optiomg_tail->number <= new_option->number)\n    {\n      /* if option is already ordered just add it */\n      cm->optiomg_tail = cm->optiomg_tail->next = new_option;\n    }\n    else\n    {\n      /* looking for appropriate position */\n      struct mg_coap_option *current_opt = cm->options;\n      struct mg_coap_option *prev_opt = 0;\n\n      while (current_opt != NULL)\n      {\n        if (current_opt->number > new_option->number)\n        {\n          break;\n        }\n        prev_opt = current_opt;\n        current_opt = current_opt->next;\n      }\n\n      if (prev_opt != NULL)\n      {\n        prev_opt->next = new_option;\n        new_option->next = current_opt;\n      }\n      else\n      {\n        /* insert new_option to the beginning */\n        new_option->next = cm->options;\n        cm->options = new_option;\n      }\n    }\n  }\n\n  return new_option;\n}\n\n/*\n * Fills CoAP header in mg_coap_message.\n *\n * Helper function.\n */\nstatic char *coap_parse_header(char *ptr, struct mbuf *io,\n                               struct mg_coap_message *cm)\n{\n  if (io->len < sizeof(uint32_t))\n  {\n    cm->flags |= MG_COAP_NOT_ENOUGH_DATA;\n    return NULL;\n  }\n\n  /*\n   * Version (Ver):  2-bit unsigned integer.  Indicates the CoAP version\n   * number.  Implementations of this specification MUST set this field\n   * to 1 (01 binary).  Other values are reserved for future versions.\n   * Messages with unknown version numbers MUST be silently ignored.\n   */\n  if (((uint8_t)*ptr >> 6) != 1)\n  {\n    cm->flags |= MG_COAP_IGNORE;\n    return NULL;\n  }\n\n  /*\n   * Type (T):  2-bit unsigned integer.  Indicates if this message is of\n   * type Confirmable (0), Non-confirmable (1), Acknowledgement (2), or\n   * Reset (3).\n   */\n  cm->msg_type = ((uint8_t)*ptr & 0x30) >> 4;\n  cm->flags |= MG_COAP_MSG_TYPE_FIELD;\n\n  /*\n   * Token Length (TKL):  4-bit unsigned integer.  Indicates the length of\n   * the variable-length Token field (0-8 bytes).  Lengths 9-15 are\n   * reserved, MUST NOT be sent, and MUST be processed as a message\n   * format error.\n   */\n  cm->token.len = *ptr & 0x0F;\n  if (cm->token.len > 8)\n  {\n    cm->flags |= MG_COAP_FORMAT_ERROR;\n    return NULL;\n  }\n\n  ptr++;\n\n  /*\n   * Code:  8-bit unsigned integer, split into a 3-bit class (most\n   * significant bits) and a 5-bit detail (least significant bits)\n   */\n  cm->code_class = (uint8_t)*ptr >> 5;\n  cm->code_detail = *ptr & 0x1F;\n  cm->flags |= (MG_COAP_CODE_CLASS_FIELD | MG_COAP_CODE_DETAIL_FIELD);\n\n  ptr++;\n\n  /* Message ID:  16-bit unsigned integer in network byte order. */\n  cm->msg_id = (uint8_t)*ptr << 8 | (uint8_t) * (ptr + 1);\n  cm->flags |= MG_COAP_MSG_ID_FIELD;\n\n  ptr += 2;\n\n  return ptr;\n}\n\n/*\n * Fills token information in mg_coap_message.\n *\n * Helper function.\n */\nstatic char *coap_get_token(char *ptr, struct mbuf *io,\n                            struct mg_coap_message *cm)\n{\n  if (cm->token.len != 0)\n  {\n    if (ptr + cm->token.len > io->buf + io->len)\n    {\n      cm->flags |= MG_COAP_NOT_ENOUGH_DATA;\n      return NULL;\n    }\n    else\n    {\n      cm->token.p = ptr;\n      ptr += cm->token.len;\n      cm->flags |= MG_COAP_TOKEN_FIELD;\n    }\n  }\n\n  return ptr;\n}\n\n/*\n * Returns Option Delta or Length.\n *\n * Helper function.\n */\nstatic int coap_get_ext_opt(char *ptr, struct mbuf *io, uint16_t *opt_info)\n{\n  int ret = 0;\n\n  if (*opt_info == 13)\n  {\n    /*\n     * 13:  An 8-bit unsigned integer follows the initial byte and\n     * indicates the Option Delta/Length minus 13.\n     */\n    if (ptr < io->buf + io->len)\n    {\n      *opt_info = (uint8_t)*ptr + 13;\n      ret = sizeof(uint8_t);\n    }\n    else\n    {\n      ret = -1; /* LCOV_EXCL_LINE */\n    }\n  }\n  else if (*opt_info == 14)\n  {\n    /*\n     * 14:  A 16-bit unsigned integer in network byte order follows the\n     * initial byte and indicates the Option Delta/Length minus 269.\n     */\n    if (ptr + sizeof(uint8_t) < io->buf + io->len)\n    {\n      *opt_info = ((uint8_t)*ptr << 8 | (uint8_t) * (ptr + 1)) + 269;\n      ret = sizeof(uint16_t);\n    }\n    else\n    {\n      ret = -1; /* LCOV_EXCL_LINE */\n    }\n  }\n\n  return ret;\n}\n\n/*\n * Fills options in mg_coap_message.\n *\n * Helper function.\n *\n * General options format:\n * +---------------+---------------+\n * | Option Delta  | Option Length |  1 byte\n * +---------------+---------------+\n * \\    Option Delta (extended)    \\  0-2 bytes\n * +-------------------------------+\n * / Option Length  (extended)     \\  0-2 bytes\n * +-------------------------------+\n * \\         Option Value          \\  0 or more bytes\n * +-------------------------------+\n */\nstatic char *coap_get_options(char *ptr, struct mbuf *io,\n                              struct mg_coap_message *cm)\n{\n  uint16_t prev_opt = 0;\n\n  if (ptr == io->buf + io->len)\n  {\n    /* end of packet, ok */\n    return NULL;\n  }\n\n  /* 0xFF is payload marker */\n  while (ptr < io->buf + io->len && (uint8_t)*ptr != 0xFF)\n  {\n    uint16_t option_delta, option_lenght;\n    int optinfo_len;\n\n    /* Option Delta:  4-bit unsigned integer */\n    option_delta = ((uint8_t)*ptr & 0xF0) >> 4;\n    /* Option Length:  4-bit unsigned integer */\n    option_lenght = *ptr & 0x0F;\n\n    if (option_delta == 15 || option_lenght == 15)\n    {\n      /*\n       * 15:  Reserved for future use.  If the field is set to this value,\n       * it MUST be processed as a message format error\n       */\n      cm->flags |= MG_COAP_FORMAT_ERROR;\n      break;\n    }\n\n    ptr++;\n\n    /* check for extended option delta */\n    optinfo_len = coap_get_ext_opt(ptr, io, &option_delta);\n    if (optinfo_len == -1)\n    {\n      cm->flags |= MG_COAP_NOT_ENOUGH_DATA; /* LCOV_EXCL_LINE */\n      break;                                /* LCOV_EXCL_LINE */\n    }\n\n    ptr += optinfo_len;\n\n    /* check or extended option lenght */\n    optinfo_len = coap_get_ext_opt(ptr, io, &option_lenght);\n    if (optinfo_len == -1)\n    {\n      cm->flags |= MG_COAP_NOT_ENOUGH_DATA; /* LCOV_EXCL_LINE */\n      break;                                /* LCOV_EXCL_LINE */\n    }\n\n    ptr += optinfo_len;\n\n    /*\n     * Instead of specifying the Option Number directly, the instances MUST\n     * appear in order of their Option Numbers and a delta encoding is used\n     * between them.\n     */\n    option_delta += prev_opt;\n\n    mg_coap_add_option(cm, option_delta, ptr, option_lenght);\n\n    prev_opt = option_delta;\n\n    if (ptr + option_lenght > io->buf + io->len)\n    {\n      cm->flags |= MG_COAP_NOT_ENOUGH_DATA; /* LCOV_EXCL_LINE */\n      break;                                /* LCOV_EXCL_LINE */\n    }\n\n    ptr += option_lenght;\n  }\n\n  if ((cm->flags & MG_COAP_ERROR) != 0)\n  {\n    mg_coap_free_options(cm);\n    return NULL;\n  }\n\n  cm->flags |= MG_COAP_OPTIOMG_FIELD;\n\n  if (ptr == io->buf + io->len)\n  {\n    /* end of packet, ok */\n    return NULL;\n  }\n\n  ptr++;\n\n  return ptr;\n}\n\nuint32_t mg_coap_parse(struct mbuf *io, struct mg_coap_message *cm)\n{\n  char *ptr;\n\n  memset(cm, 0, sizeof(*cm));\n\n  if ((ptr = coap_parse_header(io->buf, io, cm)) == NULL)\n  {\n    return cm->flags;\n  }\n\n  if ((ptr = coap_get_token(ptr, io, cm)) == NULL)\n  {\n    return cm->flags;\n  }\n\n  if ((ptr = coap_get_options(ptr, io, cm)) == NULL)\n  {\n    return cm->flags;\n  }\n\n  /* the rest is payload */\n  cm->payload.len = io->len - (ptr - io->buf);\n  if (cm->payload.len != 0)\n  {\n    cm->payload.p = ptr;\n    cm->flags |= MG_COAP_PAYLOAD_FIELD;\n  }\n\n  return cm->flags;\n}\n\n/*\n * Calculates extended size of given Opt Number/Length in coap message.\n *\n * Helper function.\n */\nstatic size_t coap_get_ext_opt_size(uint32_t value)\n{\n  int ret = 0;\n\n  if (value >= 13 && value <= 0xFF + 13)\n  {\n    ret = sizeof(uint8_t);\n  }\n  else if (value > 0xFF + 13 && value <= 0xFFFF + 269)\n  {\n    ret = sizeof(uint16_t);\n  }\n\n  return ret;\n}\n\n/*\n * Splits given Opt Number/Length into base and ext values.\n *\n * Helper function.\n */\nstatic int coap_split_opt(uint32_t value, uint8_t *base, uint16_t *ext)\n{\n  int ret = 0;\n\n  if (value < 13)\n  {\n    *base = value;\n  }\n  else if (value >= 13 && value <= 0xFF + 13)\n  {\n    *base = 13;\n    *ext = value - 13;\n    ret = sizeof(uint8_t);\n  }\n  else if (value > 0xFF + 13 && value <= 0xFFFF + 269)\n  {\n    *base = 14;\n    *ext = value - 269;\n    ret = sizeof(uint16_t);\n  }\n\n  return ret;\n}\n\n/*\n * Puts uint16_t (in network order) into given char stream.\n *\n * Helper function.\n */\nstatic char *coap_add_uint16(char *ptr, uint16_t val)\n{\n  *ptr = val >> 8;\n  ptr++;\n  *ptr = val & 0x00FF;\n  ptr++;\n  return ptr;\n}\n\n/*\n * Puts extended value of Opt Number/Length into given char stream.\n *\n * Helper function.\n */\nstatic char *coap_add_opt_info(char *ptr, uint16_t val, size_t len)\n{\n  if (len == sizeof(uint8_t))\n  {\n    *ptr = (char)val;\n    ptr++;\n  }\n  else if (len == sizeof(uint16_t))\n  {\n    ptr = coap_add_uint16(ptr, val);\n  }\n\n  return ptr;\n}\n\n/*\n * Verifies given mg_coap_message and calculates message size for it.\n *\n * Helper function.\n */\nstatic uint32_t coap_calculate_packet_size(struct mg_coap_message *cm,\n                                           size_t *len)\n{\n  struct mg_coap_option *opt;\n  uint32_t prev_opt_number;\n\n  *len = 4; /* header */\n  if (cm->msg_type > MG_COAP_MSG_MAX)\n  {\n    return MG_COAP_ERROR | MG_COAP_MSG_TYPE_FIELD;\n  }\n  if (cm->token.len > 8)\n  {\n    return MG_COAP_ERROR | MG_COAP_TOKEN_FIELD;\n  }\n  if (cm->code_class > 7)\n  {\n    return MG_COAP_ERROR | MG_COAP_CODE_CLASS_FIELD;\n  }\n  if (cm->code_detail > 31)\n  {\n    return MG_COAP_ERROR | MG_COAP_CODE_DETAIL_FIELD;\n  }\n\n  *len += cm->token.len;\n  if (cm->payload.len != 0)\n  {\n    *len += cm->payload.len + 1; /* ... + 1; add payload marker */\n  }\n\n  opt = cm->options;\n  prev_opt_number = 0;\n  while (opt != NULL)\n  {\n    *len += 1; /* basic delta/length */\n    *len += coap_get_ext_opt_size(opt->number - prev_opt_number);\n    *len += coap_get_ext_opt_size((uint32_t)opt->value.len);\n    /*\n     * Current implementation performs check if\n     * option_number > previous option_number and produces an error\n     * TODO(alashkin): write design doc with limitations\n     * May be resorting is more suitable solution.\n     */\n    if ((opt->next != NULL && opt->number > opt->next->number) ||\n        opt->value.len > 0xFFFF + 269 ||\n        opt->number - prev_opt_number > 0xFFFF + 269)\n    {\n      return MG_COAP_ERROR | MG_COAP_OPTIOMG_FIELD;\n    }\n    *len += opt->value.len;\n    prev_opt_number = opt->number;\n    opt = opt->next;\n  }\n\n  return 0;\n}\n\nuint32_t mg_coap_compose(struct mg_coap_message *cm, struct mbuf *io)\n{\n  struct mg_coap_option *opt;\n  uint32_t res, prev_opt_number;\n  size_t prev_io_len, packet_size;\n  char *ptr;\n\n  res = coap_calculate_packet_size(cm, &packet_size);\n  if (res != 0)\n  {\n    return res;\n  }\n\n  /* saving previous lenght to handle non-empty mbuf */\n  prev_io_len = io->len;\n  mbuf_append(io, NULL, packet_size);\n  ptr = io->buf + prev_io_len;\n\n  /*\n   * since cm is verified, it is possible to use bits shift operator\n   * without additional zeroing of unused bits\n   */\n\n  /* ver: 2 bits, msg_type: 2 bits, toklen: 4 bits */\n  *ptr = (1 << 6) | (cm->msg_type << 4) | (uint8_t)(cm->token.len);\n  ptr++;\n\n  /* code class: 3 bits, code detail: 5 bits */\n  *ptr = (cm->code_class << 5) | (cm->code_detail);\n  ptr++;\n\n  ptr = coap_add_uint16(ptr, cm->msg_id);\n\n  if (cm->token.len != 0)\n  {\n    memcpy(ptr, cm->token.p, cm->token.len);\n    ptr += cm->token.len;\n  }\n\n  opt = cm->options;\n  prev_opt_number = 0;\n  while (opt != NULL)\n  {\n    uint8_t delta_base = 0, length_base = 0;\n    uint16_t delta_ext = 0, length_ext = 0;\n\n    size_t opt_delta_len =\n        coap_split_opt(opt->number - prev_opt_number, &delta_base, &delta_ext);\n    size_t opt_lenght_len =\n        coap_split_opt((uint32_t)opt->value.len, &length_base, &length_ext);\n\n    *ptr = (delta_base << 4) | length_base;\n    ptr++;\n\n    ptr = coap_add_opt_info(ptr, delta_ext, opt_delta_len);\n    ptr = coap_add_opt_info(ptr, length_ext, opt_lenght_len);\n\n    if (opt->value.len != 0)\n    {\n      memcpy(ptr, opt->value.p, opt->value.len);\n      ptr += opt->value.len;\n    }\n\n    prev_opt_number = opt->number;\n    opt = opt->next;\n  }\n\n  if (cm->payload.len != 0)\n  {\n    *ptr = (char)-1;\n    ptr++;\n    memcpy(ptr, cm->payload.p, cm->payload.len);\n  }\n\n  return 0;\n}\n\nuint32_t mg_coap_send_message(struct mg_connection *nc,\n                              struct mg_coap_message *cm)\n{\n  struct mbuf packet_out;\n  uint32_t compose_res;\n\n  mbuf_init(&packet_out, 0);\n  compose_res = mg_coap_compose(cm, &packet_out);\n  if (compose_res != 0)\n  {\n    return compose_res; /* LCOV_EXCL_LINE */\n  }\n\n  mg_send(nc, packet_out.buf, (int)packet_out.len);\n  mbuf_free(&packet_out);\n\n  return 0;\n}\n\nuint32_t mg_coap_send_ack(struct mg_connection *nc, uint16_t msg_id)\n{\n  struct mg_coap_message cm;\n  memset(&cm, 0, sizeof(cm));\n  cm.msg_type = MG_COAP_MSG_ACK;\n  cm.msg_id = msg_id;\n\n  return mg_coap_send_message(nc, &cm);\n}\n\nstatic void coap_handler(struct mg_connection *nc, int ev, void *ev_data)\n{\n  struct mbuf *io = &nc->recv_mbuf;\n  struct mg_coap_message cm;\n  uint32_t parse_res;\n\n  memset(&cm, 0, sizeof(cm));\n\n  nc->handler(nc, ev, ev_data);\n\n  switch (ev)\n  {\n  case MG_EV_RECV:\n    parse_res = mg_coap_parse(io, &cm);\n    if ((parse_res & MG_COAP_IGNORE) == 0)\n    {\n      if ((cm.flags & MG_COAP_NOT_ENOUGH_DATA) != 0)\n      {\n        /*\n           * Since we support UDP only\n           * MG_COAP_NOT_ENOUGH_DATA == MG_COAP_FORMAT_ERROR\n           */\n        cm.flags |= MG_COAP_FORMAT_ERROR; /* LCOV_EXCL_LINE */\n      }                                   /* LCOV_EXCL_LINE */\n      nc->handler(nc, MG_COAP_EVENT_BASE + cm.msg_type, &cm);\n    }\n\n    mg_coap_free_options(&cm);\n    mbuf_remove(io, io->len);\n    break;\n  }\n}\n/*\n * Attach built-in CoAP event handler to the given connection.\n *\n * The user-defined event handler will receive following extra events:\n *\n * - MG_EV_COAP_CON\n * - MG_EV_COAP_NOC\n * - MG_EV_COAP_ACK\n * - MG_EV_COAP_RST\n */\nint mg_set_protocol_coap(struct mg_connection *nc)\n{\n  /* supports UDP only */\n  if ((nc->flags & MG_F_UDP) == 0)\n  {\n    return -1;\n  }\n\n  nc->proto_handler = coap_handler;\n\n  return 0;\n}\n\n#endif /* MG_ENABLE_COAP */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/tun.c\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n */\n\n#if MG_ENABLE_TUN\n\n/* Amalgamated: #include \"common/cs_dbg.h\" */\n/* Amalgamated: #include \"mongoose/src/http.h\" */\n/* Amalgamated: #include \"mongoose/src/internal.h\" */\n/* Amalgamated: #include \"mongoose/src/net.h\" */\n/* Amalgamated: #include \"mongoose/src/net_if_tun.h\" */\n/* Amalgamated: #include \"mongoose/src/tun.h\" */\n/* Amalgamated: #include \"mongoose/src/util.h\" */\n\nstatic void mg_tun_reconnect(struct mg_tun_client *client);\n\nstatic void mg_tun_init_client(struct mg_tun_client *client, struct mg_mgr *mgr,\n                               struct mg_iface *iface, const char *dispatcher,\n                               struct mg_tun_ssl_opts ssl)\n{\n  client->mgr = mgr;\n  client->iface = iface;\n  client->disp_url = dispatcher;\n  client->last_stream_id = 0;\n  client->ssl = ssl;\n\n  client->disp = NULL;     /* will be set by mg_tun_reconnect */\n  client->listener = NULL; /* will be set by mg_do_bind */\n}\n\nvoid mg_tun_log_frame(struct mg_tun_frame *frame)\n{\n  LOG(LL_DEBUG, (\"Got TUN frame: type=0x%x, flags=0x%x stream_id=0x%lx, \"\n                 \"len=%zu\",\n                 frame->type, frame->flags, frame->stream_id, frame->body.len));\n#if MG_ENABLE_HEXDUMP\n  {\n    char hex[512];\n    mg_hexdump(frame->body.p, frame->body.len, hex, sizeof(hex) - 1);\n    hex[sizeof(hex) - 1] = '\\0';\n    LOG(LL_DEBUG, (\"body:\\n%s\", hex));\n  }\n#else\n  LOG(LL_DEBUG, (\"body: '%.*s'\", (int)frame->body.len, frame->body.p));\n#endif\n}\n\nstatic void mg_tun_close_all(struct mg_tun_client *client)\n{\n  struct mg_connection *nc;\n  for (nc = client->mgr->active_connections; nc != NULL; nc = nc->next)\n  {\n    if (nc->iface == client->iface && !(nc->flags & MG_F_LISTENING))\n    {\n      LOG(LL_DEBUG, (\"Closing tunneled connection %p\", nc));\n      nc->flags |= MG_F_CLOSE_IMMEDIATELY;\n      /* mg_close_conn(nc); */\n    }\n  }\n}\n\nstatic void mg_tun_client_handler(struct mg_connection *nc, int ev,\n                                  void *ev_data)\n{\n  struct mg_tun_client *client = (struct mg_tun_client *)nc->user_data;\n\n  switch (ev)\n  {\n  case MG_EV_CONNECT:\n  {\n    int err = *(int *)ev_data;\n\n    if (err)\n    {\n      LOG(LL_ERROR, (\"Cannot connect to the tunnel dispatcher: %d\", err));\n    }\n    else\n    {\n      LOG(LL_INFO, (\"Connected to the tunnel dispatcher\"));\n    }\n    break;\n  }\n  case MG_EV_HTTP_REPLY:\n  {\n    struct http_message *hm = (struct http_message *)ev_data;\n\n    if (hm->resp_code != 200)\n    {\n      LOG(LL_ERROR,\n          (\"Tunnel dispatcher reply non-OK status code %d\", hm->resp_code));\n    }\n    break;\n  }\n  case MG_EV_WEBSOCKET_HANDSHAKE_DONE:\n  {\n    LOG(LL_INFO, (\"Tunnel dispatcher handshake done\"));\n    break;\n  }\n  case MG_EV_WEBSOCKET_FRAME:\n  {\n    struct websocket_message *wm = (struct websocket_message *)ev_data;\n    struct mg_connection *tc;\n    struct mg_tun_frame frame;\n\n    if (mg_tun_parse_frame(wm->data, wm->size, &frame) == -1)\n    {\n      LOG(LL_ERROR, (\"Got invalid tun frame dropping\", wm->size));\n      break;\n    }\n\n    mg_tun_log_frame(&frame);\n\n    tc = mg_tun_if_find_conn(client, frame.stream_id);\n    if (tc == NULL)\n    {\n      if (frame.body.len > 0)\n      {\n        LOG(LL_DEBUG, (\"Got frame after receiving end has been closed\"));\n      }\n      break;\n    }\n    if (frame.body.len > 0)\n    {\n      mg_if_recv_tcp_cb(tc, (void *)frame.body.p, frame.body.len,\n                        0 /* own */);\n    }\n    if (frame.flags & MG_TUN_F_END_STREAM)\n    {\n      LOG(LL_DEBUG, (\"Closing tunneled connection because got end of stream \"\n                     \"from other end\"));\n      tc->flags |= MG_F_CLOSE_IMMEDIATELY;\n      mg_close_conn(tc);\n    }\n    break;\n  }\n  case MG_EV_CLOSE:\n  {\n    LOG(LL_DEBUG, (\"Closing all tunneled connections\"));\n    /*\n       * The client might have been already freed when the listening socket is\n       * closed.\n       */\n    if (client != NULL)\n    {\n      mg_tun_close_all(client);\n      client->disp = NULL;\n      LOG(LL_INFO, (\"Dispatcher connection is no more, reconnecting\"));\n      mg_tun_reconnect(client);\n    }\n    break;\n  }\n  default:\n    break;\n  }\n}\n\nstatic void mg_tun_do_reconnect(struct mg_tun_client *client)\n{\n  struct mg_connection *dc;\n  struct mg_connect_opts opts;\n  memset(&opts, 0, sizeof(opts));\n#if MG_ENABLE_SSL\n  opts.ssl_cert = client->ssl.ssl_cert;\n  opts.ssl_key = client->ssl.ssl_key;\n  opts.ssl_ca_cert = client->ssl.ssl_ca_cert;\n#endif\n  /* HTTP/Websocket listener */\n  if ((dc = mg_connect_ws_opt(client->mgr, mg_tun_client_handler, opts,\n                              client->disp_url, MG_TUN_PROTO_NAME, NULL)) ==\n      NULL)\n  {\n    LOG(LL_ERROR,\n        (\"Cannot connect to WS server on addr [%s]\\n\", client->disp_url));\n    return;\n  }\n\n  client->disp = dc;\n  dc->user_data = client;\n}\n\nvoid mg_tun_reconnect_ev_handler(struct mg_connection *nc, int ev,\n                                 void *ev_data)\n{\n  struct mg_tun_client *client = (struct mg_tun_client *)nc->user_data;\n  (void)ev_data;\n\n  switch (ev)\n  {\n  case MG_EV_TIMER:\n    mg_tun_do_reconnect(client);\n    break;\n  }\n}\n\nstatic void mg_tun_reconnect(struct mg_tun_client *client)\n{\n  struct mg_connection *nc;\n  nc = mg_add_sock(client->mgr, INVALID_SOCKET, mg_tun_reconnect_ev_handler);\n  nc->user_data = client;\n  /* TODO(mkm): implement exp back off */\n  nc->ev_timer_time = mg_time() + MG_TUN_RECONNECT_INTERVAL;\n}\n\nstatic struct mg_tun_client *mg_tun_create_client(struct mg_mgr *mgr,\n                                                  const char *dispatcher,\n                                                  struct mg_tun_ssl_opts ssl)\n{\n  struct mg_tun_client *client = NULL;\n  struct mg_iface *iface = mg_find_iface(mgr, &mg_tun_iface_vtable, NULL);\n  if (iface == NULL)\n  {\n    LOG(LL_ERROR, (\"The tun feature requires the manager to have a tun \"\n                   \"interface enabled\"));\n    return NULL;\n  }\n\n  client = (struct mg_tun_client *)MG_MALLOC(sizeof(*client));\n  mg_tun_init_client(client, mgr, iface, dispatcher, ssl);\n  iface->data = client;\n\n  mg_tun_do_reconnect(client);\n  return client;\n}\n\nvoid mg_tun_destroy_client(struct mg_tun_client *client)\n{\n  /*\n   *  NOTE:\n   * `client` is NULL in case of OOM\n   * `client->disp` is NULL if connection failed\n   * `client->iface is NULL is `mg_find_iface` failed\n   */\n\n  if (client != NULL && client->disp != NULL)\n  {\n    /* the dispatcher connection handler will in turn close all tunnels */\n    client->disp->flags |= MG_F_CLOSE_IMMEDIATELY;\n    /* this is used as a signal to other tun handlers that the party is over */\n    client->disp->user_data = NULL;\n  }\n\n  if (client != NULL && client->iface != NULL)\n  {\n    client->iface->data = NULL;\n  }\n\n  MG_FREE(client);\n}\n\nstatic struct mg_connection *mg_tun_do_bind(struct mg_tun_client *client,\n                                            mg_event_handler_t handler,\n                                            struct mg_bind_opts opts)\n{\n  struct mg_connection *lc;\n  opts.iface = client->iface;\n  lc = mg_bind_opt(client->mgr, \":1234\" /* dummy port */, handler, opts);\n  client->listener = lc;\n  return lc;\n}\n\nstruct mg_connection *mg_tun_bind_opt(struct mg_mgr *mgr,\n                                      const char *dispatcher,\n                                      mg_event_handler_t handler,\n                                      struct mg_bind_opts opts)\n{\n#if MG_ENABLE_SSL\n  struct mg_tun_ssl_opts ssl = {opts.ssl_cert, opts.ssl_key, opts.ssl_ca_cert};\n#else\n  struct mg_tun_ssl_opts ssl = {0};\n#endif\n  struct mg_tun_client *client = mg_tun_create_client(mgr, dispatcher, ssl);\n  if (client == NULL)\n  {\n    return NULL;\n  }\n#if MG_ENABLE_SSL\n  /* these options don't make sense in the local mouth of the tunnel */\n  opts.ssl_cert = NULL;\n  opts.ssl_key = NULL;\n  opts.ssl_ca_cert = NULL;\n#endif\n  return mg_tun_do_bind(client, handler, opts);\n}\n\nint mg_tun_parse_frame(void *data, size_t len, struct mg_tun_frame *frame)\n{\n  const size_t header_size = sizeof(uint32_t) + sizeof(uint8_t) * 2;\n  if (len < header_size)\n  {\n    return -1;\n  }\n\n  frame->type = *(uint8_t *)(data);\n  frame->flags = *(uint8_t *)((char *)data + 1);\n  memcpy(&frame->stream_id, (char *)data + 2, sizeof(uint32_t));\n  frame->stream_id = ntohl(frame->stream_id);\n  frame->body.p = (char *)data + header_size;\n  frame->body.len = len - header_size;\n  return 0;\n}\n\nvoid mg_tun_send_frame(struct mg_connection *ws, uint32_t stream_id,\n                       uint8_t type, uint8_t flags, struct mg_str msg)\n{\n  stream_id = htonl(stream_id);\n  {\n    struct mg_str parts[] = {\n        {(char *)&type, sizeof(type)},\n        {(char *)&flags, sizeof(flags)},\n        {(char *)&stream_id, sizeof(stream_id)},\n        {msg.p, msg.len} /* vc6 doesn't like just `msg` here */};\n    mg_send_websocket_framev(ws, WEBSOCKET_OP_BINARY, parts,\n                             sizeof(parts) / sizeof(parts[0]));\n  }\n}\n\n#endif /* MG_ENABLE_TUN */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/sntp.c\"\n#endif\n/*\n * Copyright (c) 2016 Cesanta Software Limited\n * All rights reserved\n */\n\n/* Amalgamated: #include \"mongoose/src/internal.h\" */\n/* Amalgamated: #include \"mongoose/src/sntp.h\" */\n/* Amalgamated: #include \"mongoose/src/util.h\" */\n\n#if MG_ENABLE_SNTP\n\n#define SNTP_TIME_OFFSET 2208988800\n\n#ifndef SNTP_TIMEOUT\n#define SNTP_TIMEOUT 10\n#endif\n\n#ifndef SNTP_ATTEMPTS\n#define SNTP_ATTEMPTS 3\n#endif\n\nstatic uint64_t mg_get_sec(uint64_t val)\n{\n  return (val & 0xFFFFFFFF00000000) >> 32;\n}\n\nstatic uint64_t mg_get_usec(uint64_t val)\n{\n  uint64_t tmp = (val & 0x00000000FFFFFFFF);\n  tmp *= 1000000;\n  tmp >>= 32;\n  return tmp;\n}\n\nstatic void mg_ntp_to_tv(uint64_t val, struct timeval *tv)\n{\n  uint64_t tmp;\n  tmp = mg_get_sec(val);\n  tmp -= SNTP_TIME_OFFSET;\n  tv->tv_sec = tmp;\n  tv->tv_usec = mg_get_usec(val);\n}\n\nstatic void mg_get_ntp_ts(const char *ntp, uint64_t *val)\n{\n  uint32_t tmp;\n  memcpy(&tmp, ntp, sizeof(tmp));\n  tmp = ntohl(tmp);\n  *val = (uint64_t)tmp << 32;\n  memcpy(&tmp, ntp + 4, sizeof(tmp));\n  tmp = ntohl(tmp);\n  *val |= tmp;\n}\n\nvoid mg_sntp_send_request(struct mg_connection *c)\n{\n  char buf[48] = {0};\n  /*\n   * header - 8 bit:\n   * LI (2 bit) - 3 (not in sync), VN (3 bit) - 4 (version),\n   * mode (3 bit) - 3 (client)\n   */\n  buf[0] = (3 << 6) | (4 << 3) | 3;\n\n/*\n * Next fields should be empty in client request\n * stratum, 8 bit\n * poll interval, 8 bit\n * rrecision, 8 bit\n * root delay, 32 bit\n * root dispersion, 32 bit\n * ref id, 32 bit\n * ref timestamp, 64 bit\n * originate Timestamp, 64 bit\n * receive Timestamp, 64 bit\n*/\n\n/*\n * convert time to sntp format (sntp starts from 00:00:00 01.01.1900)\n * according to rfc868 it is 2208988800L sec\n * this information is used to correct roundtrip delay\n * but if local clock is absolutely broken (and doesn't work even\n * as simple timer), it is better to disable it\n*/\n#ifndef MG_SNMP_NO_DELAY_CORRECTION\n  uint32_t sec;\n  sec = htonl(mg_time() + SNTP_TIME_OFFSET);\n  memcpy(&buf[40], &sec, sizeof(sec));\n#endif\n\n  mg_send(c, buf, sizeof(buf));\n}\n\n#ifndef MG_SNMP_NO_DELAY_CORRECTION\nstatic uint64_t mg_calculate_delay(uint64_t t1, uint64_t t2, uint64_t t3)\n{\n  /* roundloop delay = (T4 - T1) - (T3 - T2) */\n  uint64_t d1 = ((mg_time() + SNTP_TIME_OFFSET) * 1000000) -\n                (mg_get_sec(t1) * 1000000 + mg_get_usec(t1));\n  uint64_t d2 = (mg_get_sec(t3) * 1000000 + mg_get_usec(t3)) -\n                (mg_get_sec(t2) * 1000000 + mg_get_usec(t2));\n\n  return (d1 > d2) ? d1 - d2 : 0;\n}\n#endif\n\nMG_INTERNAL int mg_sntp_parse_reply(const char *buf, int len,\n                                    struct mg_sntp_message *msg)\n{\n  uint8_t hdr;\n  uint64_t orig_ts_T1, recv_ts_T2, trsm_ts_T3, delay = 0;\n  int mode;\n  struct timeval tv;\n\n  (void)orig_ts_T1;\n  (void)recv_ts_T2;\n  if (len < 48)\n  {\n    return -1;\n  }\n\n  hdr = buf[0];\n\n  if ((hdr & 0x38) >> 3 != 4)\n  {\n    /* Wrong version */\n    return -1;\n  }\n\n  mode = hdr & 0x7;\n  if (mode != 4 && mode != 5)\n  {\n    /* Not a server reply */\n    return -1;\n  }\n\n  memset(msg, 0, sizeof(*msg));\n\n  msg->kiss_of_death = (buf[1] == 0); /* Server asks to not send requests */\n\n  mg_get_ntp_ts(&buf[40], &trsm_ts_T3);\n\n#ifndef MG_SNMP_NO_DELAY_CORRECTION\n  mg_get_ntp_ts(&buf[24], &orig_ts_T1);\n  mg_get_ntp_ts(&buf[32], &recv_ts_T2);\n  delay = mg_calculate_delay(orig_ts_T1, recv_ts_T2, trsm_ts_T3);\n#endif\n\n  mg_ntp_to_tv(trsm_ts_T3, &tv);\n\n  msg->time = (double)tv.tv_sec + (((double)tv.tv_usec + delay) / 1000000.0);\n\n  return 0;\n}\n\nstatic void mg_sntp_handler(struct mg_connection *c, int ev, void *ev_data)\n{\n  struct mbuf *io = &c->recv_mbuf;\n  struct mg_sntp_message msg;\n\n  c->handler(c, ev, ev_data);\n\n  switch (ev)\n  {\n  case MG_EV_RECV:\n  {\n    if (mg_sntp_parse_reply(io->buf, io->len, &msg) < 0)\n    {\n      DBG((\"Invalid SNTP packet received (%d)\", (int)io->len));\n      c->handler(c, MG_SNTP_MALFORMED_REPLY, NULL);\n    }\n    else\n    {\n      c->handler(c, MG_SNTP_REPLY, (void *)&msg);\n    }\n\n    mbuf_remove(io, io->len);\n    break;\n  }\n  }\n}\n\nint mg_set_protocol_sntp(struct mg_connection *c)\n{\n  if ((c->flags & MG_F_UDP) == 0)\n  {\n    return -1;\n  }\n\n  c->proto_handler = mg_sntp_handler;\n\n  return 0;\n}\n\nstruct mg_connection *mg_sntp_connect(struct mg_mgr *mgr,\n                                      mg_event_handler_t event_handler,\n                                      const char *sntp_server_name)\n{\n  struct mg_connection *c = NULL;\n  char url[100], *p_url = url;\n  const char *proto = \"\", *port = \"\", *tmp;\n\n  /* If port is not specified, use default (123) */\n  tmp = strchr(sntp_server_name, ':');\n  if (tmp != NULL && *(tmp + 1) == '/')\n  {\n    tmp = strchr(tmp + 1, ':');\n  }\n\n  if (tmp == NULL)\n  {\n    port = \":123\";\n  }\n\n  /* Add udp:// if needed */\n  if (strncmp(sntp_server_name, \"udp://\", 6) != 0)\n  {\n    proto = \"udp://\";\n  }\n\n  mg_asprintf(&p_url, sizeof(url), \"%s%s%s\", proto, sntp_server_name, port);\n\n  c = mg_connect(mgr, p_url, event_handler);\n\n  if (c == NULL)\n  {\n    goto cleanup;\n  }\n\n  mg_set_protocol_sntp(c);\n\ncleanup:\n  if (p_url != url)\n  {\n    MG_FREE(p_url);\n  }\n\n  return c;\n}\n\nstruct sntp_data\n{\n  mg_event_handler_t hander;\n  int count;\n};\n\nstatic void mg_sntp_util_ev_handler(struct mg_connection *c, int ev,\n                                    void *ev_data)\n{\n  struct sntp_data *sd = (struct sntp_data *)c->user_data;\n\n  switch (ev)\n  {\n  case MG_EV_CONNECT:\n    if (*(int *)ev_data != 0)\n    {\n      mg_call(c, sd->hander, MG_SNTP_FAILED, NULL);\n      break;\n    }\n  /* fallthrough */\n  case MG_EV_TIMER:\n    if (sd->count <= SNTP_ATTEMPTS)\n    {\n      mg_sntp_send_request(c);\n      mg_set_timer(c, mg_time() + 10);\n      sd->count++;\n    }\n    else\n    {\n      mg_call(c, sd->hander, MG_SNTP_FAILED, NULL);\n      c->flags |= MG_F_CLOSE_IMMEDIATELY;\n    }\n    break;\n  case MG_SNTP_MALFORMED_REPLY:\n    mg_call(c, sd->hander, MG_SNTP_FAILED, NULL);\n    c->flags |= MG_F_CLOSE_IMMEDIATELY;\n    break;\n  case MG_SNTP_REPLY:\n    mg_call(c, sd->hander, MG_SNTP_REPLY, ev_data);\n    c->flags |= MG_F_CLOSE_IMMEDIATELY;\n    break;\n  case MG_EV_CLOSE:\n    MG_FREE(c->user_data);\n    c->user_data = NULL;\n    break;\n  }\n}\n\nstruct mg_connection *mg_sntp_get_time(struct mg_mgr *mgr,\n                                       mg_event_handler_t event_handler,\n                                       const char *sntp_server_name)\n{\n  struct mg_connection *c;\n  struct sntp_data *sd = (struct sntp_data *)MG_CALLOC(1, sizeof(*sd));\n  if (sd == NULL)\n  {\n    return NULL;\n  }\n\n  c = mg_sntp_connect(mgr, mg_sntp_util_ev_handler, sntp_server_name);\n  if (c == NULL)\n  {\n    MG_FREE(sd);\n    return NULL;\n  }\n\n  sd->hander = event_handler;\n  c->user_data = sd;\n\n  return c;\n}\n\n#endif /* MG_ENABLE_SNTP */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/cc3200/cc3200_libc.c\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#if CS_PLATFORM == CS_P_CC3200\n\n#include <stdio.h>\n#include <string.h>\n\n#ifndef __TI_COMPILER_VERSION__\n#include <reent.h>\n#include <sys/stat.h>\n#include <sys/time.h>\n#include <unistd.h>\n#endif\n\n#include <inc/hw_types.h>\n#include <inc/hw_memmap.h>\n#include <driverlib/prcm.h>\n#include <driverlib/rom.h>\n#include <driverlib/rom_map.h>\n#include <driverlib/uart.h>\n#include <driverlib/utils.h>\n\n#define CONSOLE_UART UARTA0_BASE\n\n#ifdef __TI_COMPILER_VERSION__\nint asprintf(char **strp, const char *fmt, ...)\n{\n  va_list ap;\n  int len;\n\n  *strp = malloc(BUFSIZ);\n  if (*strp == NULL)\n    return -1;\n\n  va_start(ap, fmt);\n  len = vsnprintf(*strp, BUFSIZ, fmt, ap);\n  va_end(ap);\n\n  if (len > 0)\n  {\n    *strp = realloc(*strp, len + 1);\n    if (*strp == NULL)\n      return -1;\n  }\n\n  if (len >= BUFSIZ)\n  {\n    va_start(ap, fmt);\n    len = vsnprintf(*strp, len + 1, fmt, ap);\n    va_end(ap);\n  }\n\n  return len;\n}\n\n#if MG_TI_NO_HOST_INTERFACE\ntime_t HOSTtime()\n{\n  struct timeval tp;\n  gettimeofday(&tp, NULL);\n  return tp.tv_sec;\n}\n#endif\n\n#endif /* __TI_COMPILER_VERSION__ */\n\n#ifndef __TI_COMPILER_VERSION__\nint _gettimeofday_r(struct _reent *r, struct timeval *tp, void *tzp)\n{\n#else\nint gettimeofday(struct timeval *tp, void *tzp)\n{\n#endif\n  unsigned long long r1 = 0, r2;\n  /* Achieve two consecutive reads of the same value. */\n  do\n  {\n    r2 = r1;\n    r1 = PRCMSlowClkCtrFastGet();\n  } while (r1 != r2);\n  /* This is a 32768 Hz counter. */\n  tp->tv_sec = (r1 >> 15);\n  /* 1/32768-th of a second is 30.517578125 microseconds, approx. 31,\n   * but we round down so it doesn't overflow at 32767 */\n  tp->tv_usec = (r1 & 0x7FFF) * 30;\n  return 0;\n}\n\nvoid fprint_str(FILE *fp, const char *str)\n{\n  while (*str != '\\0')\n  {\n    if (*str == '\\n')\n      MAP_UARTCharPut(CONSOLE_UART, '\\r');\n    MAP_UARTCharPut(CONSOLE_UART, *str++);\n  }\n}\n\nvoid _exit(int status)\n{\n  fprint_str(stderr, \"_exit\\n\");\n  /* cause an unaligned access exception, that will drop you into gdb */\n  *(int *)1 = status;\n  while (1)\n    ; /* avoid gcc warning because stdlib abort() has noreturn attribute */\n}\n\nvoid _not_implemented(const char *what)\n{\n  fprint_str(stderr, what);\n  fprint_str(stderr, \" is not implemented\\n\");\n  _exit(42);\n}\n\nint _kill(int pid, int sig)\n{\n  (void)pid;\n  (void)sig;\n  _not_implemented(\"_kill\");\n  return -1;\n}\n\nint _getpid()\n{\n  fprint_str(stderr, \"_getpid is not implemented\\n\");\n  return 42;\n}\n\nint _isatty(int fd)\n{\n  /* 0, 1 and 2 are TTYs. */\n  return fd < 2;\n}\n\n#endif /* CS_PLATFORM == CS_P_CC3200 */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/msp432/msp432_libc.c\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#if CS_PLATFORM == CS_P_MSP432\n\n#include <ti/sysbios/BIOS.h>\n#include <ti/sysbios/knl/Clock.h>\n\nint gettimeofday(struct timeval *tp, void *tzp)\n{\n  uint32_t ticks = Clock_getTicks();\n  tp->tv_sec = ticks / 1000;\n  tp->tv_usec = (ticks % 1000) * 1000;\n  return 0;\n}\n\n#endif /* CS_PLATFORM == CS_P_MSP432 */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/nrf5/nrf5_libc.c\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#if (CS_PLATFORM == CS_P_NRF51 || CS_PLATFORM == CS_P_NRF52) && \\\n    defined(__ARMCC_VERSION)\nint gettimeofday(struct timeval *tp, void *tzp)\n{\n  /* TODO */\n  tp->tv_sec = 0;\n  tp->tv_usec = 0;\n  return 0;\n}\n#endif\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/simplelink/sl_fs_slfs.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_COMMON_PLATFORMS_SIMPLELINK_SL_FS_SLFS_H_\n#define CS_COMMON_PLATFORMS_SIMPLELINK_SL_FS_SLFS_H_\n\n#if defined(MG_FS_SLFS)\n\n#include <stdio.h>\n#ifndef __TI_COMPILER_VERSION__\n#include <unistd.h>\n#include <sys/stat.h>\n#endif\n\n#define MAX_OPEN_SLFS_FILES 8\n\n/* Indirect libc interface - same functions, different names. */\nint fs_slfs_open(const char *pathname, int flags, mode_t mode);\nint fs_slfs_close(int fd);\nssize_t fs_slfs_read(int fd, void *buf, size_t count);\nssize_t fs_slfs_write(int fd, const void *buf, size_t count);\nint fs_slfs_stat(const char *pathname, struct stat *s);\nint fs_slfs_fstat(int fd, struct stat *s);\noff_t fs_slfs_lseek(int fd, off_t offset, int whence);\nint fs_slfs_unlink(const char *filename);\nint fs_slfs_rename(const char *from, const char *to);\n\nvoid fs_slfs_set_new_file_size(const char *name, size_t size);\n\n#endif /* defined(MG_FS_SLFS) */\n\n#endif /* CS_COMMON_PLATFORMS_SIMPLELINK_SL_FS_SLFS_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/simplelink/sl_fs_slfs.c\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n/* Standard libc interface to TI SimpleLink FS. */\n\n#if defined(MG_FS_SLFS) || defined(CC3200_FS_SLFS)\n\n/* Amalgamated: #include \"common/platforms/simplelink/sl_fs_slfs.h\" */\n\n#include <errno.h>\n\n#if CS_PLATFORM == CS_P_CC3200\n#include <inc/hw_types.h>\n#endif\n#include <simplelink/include/simplelink.h>\n#include <simplelink/include/fs.h>\n\n/* Amalgamated: #include \"common/cs_dbg.h\" */\n\nextern int set_errno(int e); /* From sl_fs.c */\n\n/*\n * With SLFS, you have to pre-declare max file size. Yes. Really.\n * 64K should be enough for everyone. Right?\n */\n#ifndef FS_SLFS_MAX_FILE_SIZE\n#define FS_SLFS_MAX_FILE_SIZE (64 * 1024)\n#endif\n\nstruct sl_file_size_hint\n{\n  char *name;\n  size_t size;\n};\n\nstruct sl_fd_info\n{\n  _i32 fh;\n  _off_t pos;\n  size_t size;\n};\n\nstatic struct sl_fd_info s_sl_fds[MAX_OPEN_SLFS_FILES];\nstatic struct sl_file_size_hint s_sl_file_size_hints[MAX_OPEN_SLFS_FILES];\n\nstatic int sl_fs_to_errno(_i32 r)\n{\n  DBG((\"SL error: %d\", (int)r));\n  switch (r)\n  {\n  case SL_FS_OK:\n    return 0;\n  case SL_FS_FILE_NAME_EXIST:\n    return EEXIST;\n  case SL_FS_WRONG_FILE_NAME:\n    return EINVAL;\n  case SL_FS_ERR_NO_AVAILABLE_NV_INDEX:\n  case SL_FS_ERR_NO_AVAILABLE_BLOCKS:\n    return ENOSPC;\n  case SL_FS_ERR_FAILED_TO_ALLOCATE_MEM:\n    return ENOMEM;\n  case SL_FS_ERR_FILE_NOT_EXISTS:\n    return ENOENT;\n  case SL_FS_ERR_NOT_SUPPORTED:\n    return ENOTSUP;\n  }\n  return ENXIO;\n}\n\nint fs_slfs_open(const char *pathname, int flags, mode_t mode)\n{\n  int fd;\n  for (fd = 0; fd < MAX_OPEN_SLFS_FILES; fd++)\n  {\n    if (s_sl_fds[fd].fh <= 0)\n      break;\n  }\n  if (fd >= MAX_OPEN_SLFS_FILES)\n    return set_errno(ENOMEM);\n  struct sl_fd_info *fi = &s_sl_fds[fd];\n\n  _u32 am = 0;\n  fi->size = (size_t)-1;\n  int rw = (flags & 3);\n  if (rw == O_RDONLY)\n  {\n    SlFsFileInfo_t sl_fi;\n    _i32 r = sl_FsGetInfo((const _u8 *)pathname, 0, &sl_fi);\n    if (r == SL_FS_OK)\n    {\n      fi->size = sl_fi.FileLen;\n    }\n    am = FS_MODE_OPEN_READ;\n  }\n  else\n  {\n    if (!(flags & O_TRUNC) || (flags & O_APPEND))\n    {\n      // FailFS files cannot be opened for append and will be truncated\n      // when opened for write.\n      return set_errno(ENOTSUP);\n    }\n    if (flags & O_CREAT)\n    {\n      size_t i, size = FS_SLFS_MAX_FILE_SIZE;\n      for (i = 0; i < MAX_OPEN_SLFS_FILES; i++)\n      {\n        if (s_sl_file_size_hints[i].name != NULL &&\n            strcmp(s_sl_file_size_hints[i].name, pathname) == 0)\n        {\n          size = s_sl_file_size_hints[i].size;\n          free(s_sl_file_size_hints[i].name);\n          s_sl_file_size_hints[i].name = NULL;\n          break;\n        }\n      }\n      DBG((\"creating %s with max size %d\", pathname, (int)size));\n      am = FS_MODE_OPEN_CREATE(size, 0);\n    }\n    else\n    {\n      am = FS_MODE_OPEN_WRITE;\n    }\n  }\n  _i32 r = sl_FsOpen((_u8 *)pathname, am, NULL, &fi->fh);\n  DBG((\"sl_FsOpen(%s, 0x%x) = %d, %d\", pathname, (int)am, (int)r,\n       (int)fi->fh));\n  if (r == SL_FS_OK)\n  {\n    fi->pos = 0;\n    r = fd;\n  }\n  else\n  {\n    fi->fh = -1;\n    r = set_errno(sl_fs_to_errno(r));\n  }\n  return r;\n}\n\nint fs_slfs_close(int fd)\n{\n  struct sl_fd_info *fi = &s_sl_fds[fd];\n  if (fi->fh <= 0)\n    return set_errno(EBADF);\n  _i32 r = sl_FsClose(fi->fh, NULL, NULL, 0);\n  DBG((\"sl_FsClose(%d) = %d\", (int)fi->fh, (int)r));\n  s_sl_fds[fd].fh = -1;\n  return set_errno(sl_fs_to_errno(r));\n}\n\nssize_t fs_slfs_read(int fd, void *buf, size_t count)\n{\n  struct sl_fd_info *fi = &s_sl_fds[fd];\n  if (fi->fh <= 0)\n    return set_errno(EBADF);\n  /* Simulate EOF. sl_FsRead @ file_size return SL_FS_ERR_OFFSET_OUT_OF_RANGE.\n   */\n  if (fi->pos == fi->size)\n    return 0;\n  _i32 r = sl_FsRead(fi->fh, fi->pos, buf, count);\n  DBG((\"sl_FsRead(%d, %d, %d) = %d\", (int)fi->fh, (int)fi->pos, (int)count,\n       (int)r));\n  if (r >= 0)\n  {\n    fi->pos += r;\n    return r;\n  }\n  return set_errno(sl_fs_to_errno(r));\n}\n\nssize_t fs_slfs_write(int fd, const void *buf, size_t count)\n{\n  struct sl_fd_info *fi = &s_sl_fds[fd];\n  if (fi->fh <= 0)\n    return set_errno(EBADF);\n  _i32 r = sl_FsWrite(fi->fh, fi->pos, (_u8 *)buf, count);\n  DBG((\"sl_FsWrite(%d, %d, %d) = %d\", (int)fi->fh, (int)fi->pos, (int)count,\n       (int)r));\n  if (r >= 0)\n  {\n    fi->pos += r;\n    return r;\n  }\n  return set_errno(sl_fs_to_errno(r));\n}\n\nint fs_slfs_stat(const char *pathname, struct stat *s)\n{\n  SlFsFileInfo_t sl_fi;\n  _i32 r = sl_FsGetInfo((const _u8 *)pathname, 0, &sl_fi);\n  if (r == SL_FS_OK)\n  {\n    s->st_mode = S_IFREG | 0666;\n    s->st_nlink = 1;\n    s->st_size = sl_fi.FileLen;\n    return 0;\n  }\n  return set_errno(sl_fs_to_errno(r));\n}\n\nint fs_slfs_fstat(int fd, struct stat *s)\n{\n  struct sl_fd_info *fi = &s_sl_fds[fd];\n  if (fi->fh <= 0)\n    return set_errno(EBADF);\n  s->st_mode = 0666;\n  s->st_mode = S_IFREG | 0666;\n  s->st_nlink = 1;\n  s->st_size = fi->size;\n  return 0;\n}\n\noff_t fs_slfs_lseek(int fd, off_t offset, int whence)\n{\n  if (s_sl_fds[fd].fh <= 0)\n    return set_errno(EBADF);\n  switch (whence)\n  {\n  case SEEK_SET:\n    s_sl_fds[fd].pos = offset;\n    break;\n  case SEEK_CUR:\n    s_sl_fds[fd].pos += offset;\n    break;\n  case SEEK_END:\n    return set_errno(ENOTSUP);\n  }\n  return 0;\n}\n\nint fs_slfs_unlink(const char *filename)\n{\n  return set_errno(sl_fs_to_errno(sl_FsDel((const _u8 *)filename, 0)));\n}\n\nint fs_slfs_rename(const char *from, const char *to)\n{\n  return set_errno(ENOTSUP);\n}\n\nvoid fs_slfs_set_new_file_size(const char *name, size_t size)\n{\n  int i;\n  for (i = 0; i < MAX_OPEN_SLFS_FILES; i++)\n  {\n    if (s_sl_file_size_hints[i].name == NULL)\n    {\n      DBG((\"File size hint: %s %d\", name, (int)size));\n      s_sl_file_size_hints[i].name = strdup(name);\n      s_sl_file_size_hints[i].size = size;\n      break;\n    }\n  }\n}\n\n#endif /* defined(MG_FS_SLFS) || defined(CC3200_FS_SLFS) */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/simplelink/sl_fs.c\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#if MG_NET_IF == MG_NET_IF_SIMPLELINK && \\\n    (defined(MG_FS_SLFS) || defined(MG_FS_SPIFFS))\n\n#include <errno.h>\n#include <stdbool.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#ifdef __TI_COMPILER_VERSION__\n#include <file.h>\n#endif\n\n/* Amalgamated: #include \"common/cs_dbg.h\" */\n/* Amalgamated: #include \"common/platform.h\" */\n\n#ifdef CC3200_FS_SPIFFS\n/* Amalgamated: #include \"cc3200_fs_spiffs.h\" */\n#endif\n\n#ifdef MG_FS_SLFS\n/* Amalgamated: #include \"sl_fs_slfs.h\" */\n#endif\n\n#define NUM_SYS_FDS 3\n#define SPIFFS_FD_BASE 10\n#define SLFS_FD_BASE 100\n\n#ifndef MG_UART_CHAR_PUT\n#if CS_PLATFORM == CS_P_CC3200\n#include <inc/hw_types.h>\n#include <inc/hw_memmap.h>\n#include <driverlib/rom.h>\n#include <driverlib/rom_map.h>\n#include <driverlib/uart.h>\n#define MG_UART_CHAR_PUT(fd, c) MAP_UARTCharPut(UARTA0_BASE, c);\n#else\n#define MG_UART_CHAR_PUT(fd, c)\n#endif /* CS_PLATFORM == CS_P_CC3200 */\n#endif /* !MG_UART_CHAR_PUT */\n\nint set_errno(int e)\n{\n  errno = e;\n  return (e == 0 ? 0 : -1);\n}\n\nstatic const char *drop_dir(const char *fname, bool *is_slfs)\n{\n  *is_slfs = (strncmp(fname, \"SL:\", 3) == 0);\n  if (*is_slfs)\n    fname += 3;\n  /* Drop \"./\", if any */\n  if (fname[0] == '.' && fname[1] == '/')\n  {\n    fname += 2;\n  }\n  /*\n   * Drop / if it is the only one in the path.\n   * This allows use of /pretend/directories but serves /file.txt as normal.\n   */\n  if (fname[0] == '/' && strchr(fname + 1, '/') == NULL)\n  {\n    fname++;\n  }\n  return fname;\n}\n\nenum fd_type\n{\n  FD_INVALID,\n  FD_SYS,\n#ifdef CC3200_FS_SPIFFS\n  FD_SPIFFS,\n#endif\n#ifdef MG_FS_SLFS\n  FD_SLFS\n#endif\n};\nstatic int fd_type(int fd)\n{\n  if (fd >= 0 && fd < NUM_SYS_FDS)\n    return FD_SYS;\n#ifdef CC3200_FS_SPIFFS\n  if (fd >= SPIFFS_FD_BASE && fd < SPIFFS_FD_BASE + MAX_OPEN_SPIFFS_FILES)\n  {\n    return FD_SPIFFS;\n  }\n#endif\n#ifdef MG_FS_SLFS\n  if (fd >= SLFS_FD_BASE && fd < SLFS_FD_BASE + MAX_OPEN_SLFS_FILES)\n  {\n    return FD_SLFS;\n  }\n#endif\n  return FD_INVALID;\n}\n\n#if MG_TI_NO_HOST_INTERFACE\nint open(const char *pathname, unsigned flags, int mode)\n{\n#else\nint _open(const char *pathname, int flags, mode_t mode)\n{\n#endif\n  int fd = -1;\n  bool is_sl;\n  const char *fname = drop_dir(pathname, &is_sl);\n  if (is_sl)\n  {\n#ifdef MG_FS_SLFS\n    fd = fs_slfs_open(fname, flags, mode);\n    if (fd >= 0)\n      fd += SLFS_FD_BASE;\n#endif\n  }\n  else\n  {\n#ifdef CC3200_FS_SPIFFS\n    fd = fs_spiffs_open(fname, flags, mode);\n    if (fd >= 0)\n      fd += SPIFFS_FD_BASE;\n#endif\n  }\n  LOG(LL_DEBUG,\n      (\"open(%s, 0x%x) = %d, fname = %s\", pathname, flags, fd, fname));\n  return fd;\n}\n\nint _stat(const char *pathname, struct stat *st)\n{\n  int res = -1;\n  bool is_sl;\n  const char *fname = drop_dir(pathname, &is_sl);\n  memset(st, 0, sizeof(*st));\n  /* Simulate statting the root directory. */\n  if (fname[0] == '\\0' || strcmp(fname, \".\") == 0)\n  {\n    st->st_ino = 0;\n    st->st_mode = S_IFDIR | 0777;\n    st->st_nlink = 1;\n    st->st_size = 0;\n    return 0;\n  }\n  if (is_sl)\n  {\n#ifdef MG_FS_SLFS\n    res = fs_slfs_stat(fname, st);\n#endif\n  }\n  else\n  {\n#ifdef CC3200_FS_SPIFFS\n    res = fs_spiffs_stat(fname, st);\n#endif\n  }\n  LOG(LL_DEBUG, (\"stat(%s) = %d; fname = %s\", pathname, res, fname));\n  return res;\n}\n\n#if MG_TI_NO_HOST_INTERFACE\nint close(int fd)\n{\n#else\nint _close(int fd)\n{\n#endif\n  int r = -1;\n  switch (fd_type(fd))\n  {\n  case FD_INVALID:\n    r = set_errno(EBADF);\n    break;\n  case FD_SYS:\n    r = set_errno(EACCES);\n    break;\n#ifdef CC3200_FS_SPIFFS\n  case FD_SPIFFS:\n    r = fs_spiffs_close(fd - SPIFFS_FD_BASE);\n    break;\n#endif\n#ifdef MG_FS_SLFS\n  case FD_SLFS:\n    r = fs_slfs_close(fd - SLFS_FD_BASE);\n    break;\n#endif\n  }\n  DBG((\"close(%d) = %d\", fd, r));\n  return r;\n}\n\n#if MG_TI_NO_HOST_INTERFACE\noff_t lseek(int fd, off_t offset, int whence)\n{\n#else\noff_t _lseek(int fd, off_t offset, int whence)\n{\n#endif\n  int r = -1;\n  switch (fd_type(fd))\n  {\n  case FD_INVALID:\n    r = set_errno(EBADF);\n    break;\n  case FD_SYS:\n    r = set_errno(ESPIPE);\n    break;\n#ifdef CC3200_FS_SPIFFS\n  case FD_SPIFFS:\n    r = fs_spiffs_lseek(fd - SPIFFS_FD_BASE, offset, whence);\n    break;\n#endif\n#ifdef MG_FS_SLFS\n  case FD_SLFS:\n    r = fs_slfs_lseek(fd - SLFS_FD_BASE, offset, whence);\n    break;\n#endif\n  }\n  DBG((\"lseek(%d, %d, %d) = %d\", fd, (int)offset, whence, r));\n  return r;\n}\n\nint _fstat(int fd, struct stat *s)\n{\n  int r = -1;\n  memset(s, 0, sizeof(*s));\n  switch (fd_type(fd))\n  {\n  case FD_INVALID:\n    r = set_errno(EBADF);\n    break;\n  case FD_SYS:\n  {\n    /* Create barely passable stats for STD{IN,OUT,ERR}. */\n    memset(s, 0, sizeof(*s));\n    s->st_ino = fd;\n    s->st_mode = S_IFCHR | 0666;\n    r = 0;\n    break;\n  }\n#ifdef CC3200_FS_SPIFFS\n  case FD_SPIFFS:\n    r = fs_spiffs_fstat(fd - SPIFFS_FD_BASE, s);\n    break;\n#endif\n#ifdef MG_FS_SLFS\n  case FD_SLFS:\n    r = fs_slfs_fstat(fd - SLFS_FD_BASE, s);\n    break;\n#endif\n  }\n  DBG((\"fstat(%d) = %d\", fd, r));\n  return r;\n}\n\n#if MG_TI_NO_HOST_INTERFACE\nint read(int fd, char *buf, unsigned count)\n{\n#else\nssize_t _read(int fd, void *buf, size_t count)\n{\n#endif\n  int r = -1;\n  switch (fd_type(fd))\n  {\n  case FD_INVALID:\n    r = set_errno(EBADF);\n    break;\n  case FD_SYS:\n  {\n    if (fd != 0)\n    {\n      r = set_errno(EACCES);\n      break;\n    }\n    /* Should we allow reading from stdin = uart? */\n    r = set_errno(ENOTSUP);\n    break;\n  }\n#ifdef CC3200_FS_SPIFFS\n  case FD_SPIFFS:\n    r = fs_spiffs_read(fd - SPIFFS_FD_BASE, buf, count);\n    break;\n#endif\n#ifdef MG_FS_SLFS\n  case FD_SLFS:\n    r = fs_slfs_read(fd - SLFS_FD_BASE, buf, count);\n    break;\n#endif\n  }\n  DBG((\"read(%d, %u) = %d\", fd, count, r));\n  return r;\n}\n\n#if MG_TI_NO_HOST_INTERFACE\nint write(int fd, const char *buf, unsigned count)\n{\n#else\nssize_t _write(int fd, const void *buf, size_t count)\n{\n#endif\n  int r = -1;\n  size_t i = 0;\n  switch (fd_type(fd))\n  {\n  case FD_INVALID:\n    r = set_errno(EBADF);\n    break;\n  case FD_SYS:\n  {\n    if (fd == 0)\n    {\n      r = set_errno(EACCES);\n      break;\n    }\n    for (i = 0; i < count; i++)\n    {\n      const char c = ((const char *)buf)[i];\n      if (c == '\\n')\n        MG_UART_CHAR_PUT(fd, '\\r');\n      MG_UART_CHAR_PUT(fd, c);\n    }\n    r = count;\n    break;\n  }\n#ifdef CC3200_FS_SPIFFS\n  case FD_SPIFFS:\n    r = fs_spiffs_write(fd - SPIFFS_FD_BASE, buf, count);\n    break;\n#endif\n#ifdef MG_FS_SLFS\n  case FD_SLFS:\n    r = fs_slfs_write(fd - SLFS_FD_BASE, buf, count);\n    break;\n#endif\n  }\n  return r;\n}\n\n/*\n * On Newlib we override rename directly too, because the default\n * implementation using _link and _unlink doesn't work for us.\n */\n#if MG_TI_NO_HOST_INTERFACE || defined(_NEWLIB_VERSION)\nint rename(const char *frompath, const char *topath)\n{\n  int r = -1;\n  bool is_sl_from, is_sl_to;\n  const char *from = drop_dir(frompath, &is_sl_from);\n  const char *to = drop_dir(topath, &is_sl_to);\n  if (is_sl_from || is_sl_to)\n  {\n    set_errno(ENOTSUP);\n  }\n  else\n  {\n#ifdef CC3200_FS_SPIFFS\n    r = fs_spiffs_rename(from, to);\n#endif\n  }\n  DBG((\"rename(%s, %s) = %d\", from, to, r));\n  return r;\n}\n#endif /* MG_TI_NO_HOST_INTERFACE || defined(_NEWLIB_VERSION) */\n\n#if MG_TI_NO_HOST_INTERFACE\nint unlink(const char *pathname)\n{\n#else\nint _unlink(const char *pathname)\n{\n#endif\n  int r = -1;\n  bool is_sl;\n  const char *fname = drop_dir(pathname, &is_sl);\n  if (is_sl)\n  {\n#ifdef MG_FS_SLFS\n    r = fs_slfs_unlink(fname);\n#endif\n  }\n  else\n  {\n#ifdef CC3200_FS_SPIFFS\n    r = fs_spiffs_unlink(fname);\n#endif\n  }\n  DBG((\"unlink(%s) = %d, fname = %s\", pathname, r, fname));\n  return r;\n}\n\n#ifdef CC3200_FS_SPIFFS /* FailFS does not support listing files. */\nDIR *opendir(const char *dir_name)\n{\n  DIR *r = NULL;\n  bool is_sl;\n  drop_dir(dir_name, &is_sl);\n  if (is_sl)\n  {\n    r = NULL;\n    set_errno(ENOTSUP);\n  }\n  else\n  {\n    r = fs_spiffs_opendir(dir_name);\n  }\n  DBG((\"opendir(%s) = %p\", dir_name, r));\n  return r;\n}\n\nstruct dirent *readdir(DIR *dir)\n{\n  struct dirent *res = fs_spiffs_readdir(dir);\n  DBG((\"readdir(%p) = %p\", dir, res));\n  return res;\n}\n\nint closedir(DIR *dir)\n{\n  int res = fs_spiffs_closedir(dir);\n  DBG((\"closedir(%p) = %d\", dir, res));\n  return res;\n}\n\nint rmdir(const char *path)\n{\n  return fs_spiffs_rmdir(path);\n}\n\nint mkdir(const char *path, mode_t mode)\n{\n  (void)path;\n  (void)mode;\n  /* for spiffs supports only root dir, which comes from mongoose as '.' */\n  return (strlen(path) == 1 && *path == '.') ? 0 : ENOTDIR;\n}\n#endif\n\nint sl_fs_init(void)\n{\n  int ret = 1;\n#ifdef __TI_COMPILER_VERSION__\n#ifdef MG_FS_SLFS\n#pragma diag_push\n#pragma diag_suppress 169 /* Nothing we can do about the prototype mismatch. \\\n                           */\n  ret = (add_device(\"SL\", _MSA, fs_slfs_open, fs_slfs_close, fs_slfs_read,\n                    fs_slfs_write, fs_slfs_lseek, fs_slfs_unlink,\n                    fs_slfs_rename) == 0);\n#pragma diag_pop\n#endif\n#endif\n  return ret;\n}\n\n#endif /* MG_NET_IF == MG_NET_IF_SIMPLELINK && (defined(MG_FS_SLFS) || \\\n          defined(MG_FS_SPIFFS)) */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/simplelink/sl_socket.c\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#if MG_NET_IF == MG_NET_IF_SIMPLELINK\n\n#include <errno.h>\n#include <stdio.h>\n\n/* Amalgamated: #include \"common/platform.h\" */\n\nconst char *inet_ntop(int af, const void *src, char *dst, socklen_t size)\n{\n  int res;\n  struct in_addr *in = (struct in_addr *)src;\n  if (af != AF_INET)\n  {\n    errno = EAFNOSUPPORT;\n    return NULL;\n  }\n  res = snprintf(dst, size, \"%lu.%lu.%lu.%lu\", SL_IPV4_BYTE(in->s_addr, 0),\n                 SL_IPV4_BYTE(in->s_addr, 1), SL_IPV4_BYTE(in->s_addr, 2),\n                 SL_IPV4_BYTE(in->s_addr, 3));\n  return res > 0 ? dst : NULL;\n}\n\nchar *inet_ntoa(struct in_addr n)\n{\n  static char a[16];\n  return (char *)inet_ntop(AF_INET, &n, a, sizeof(a));\n}\n\nint inet_pton(int af, const char *src, void *dst)\n{\n  uint32_t a0, a1, a2, a3;\n  uint8_t *db = (uint8_t *)dst;\n  if (af != AF_INET)\n  {\n    errno = EAFNOSUPPORT;\n    return 0;\n  }\n  if (sscanf(src, \"%lu.%lu.%lu.%lu\", &a0, &a1, &a2, &a3) != 4)\n  {\n    return 0;\n  }\n  *db = a3;\n  *(db + 1) = a2;\n  *(db + 2) = a1;\n  *(db + 3) = a0;\n  return 1;\n}\n\n#endif /* MG_NET_IF == MG_NET_IF_SIMPLELINK */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/simplelink/sl_mg_task.c\"\n#endif\n#if MG_NET_IF == MG_NET_IF_SIMPLELINK && !defined(MG_SIMPLELINK_NO_OSI)\n\n/* Amalgamated: #include \"mg_task.h\" */\n\n#include <oslib/osi.h>\n\nenum mg_q_msg_type\n{\n  MG_Q_MSG_CB,\n};\nstruct mg_q_msg\n{\n  enum mg_q_msg_type type;\n  void (*cb)(struct mg_mgr *mgr, void *arg);\n  void *arg;\n};\nstatic OsiMsgQ_t s_mg_q;\nstatic void mg_task(void *arg);\n\nbool mg_start_task(int priority, int stack_size, mg_init_cb mg_init)\n{\n  if (osi_MsgQCreate(&s_mg_q, \"MG\", sizeof(struct mg_q_msg), 16) != OSI_OK)\n  {\n    return false;\n  }\n  if (osi_TaskCreate(mg_task, (const signed char *)\"MG\", stack_size,\n                     (void *)mg_init, priority, NULL) != OSI_OK)\n  {\n    return false;\n  }\n  return true;\n}\n\nstatic void mg_task(void *arg)\n{\n  struct mg_mgr mgr;\n  mg_init_cb mg_init = (mg_init_cb)arg;\n  mg_mgr_init(&mgr, NULL);\n  mg_init(&mgr);\n  while (1)\n  {\n    struct mg_q_msg msg;\n    mg_mgr_poll(&mgr, 1);\n    if (osi_MsgQRead(&s_mg_q, &msg, 1) != OSI_OK)\n      continue;\n    switch (msg.type)\n    {\n    case MG_Q_MSG_CB:\n    {\n      msg.cb(&mgr, msg.arg);\n    }\n    }\n  }\n}\n\nvoid mg_run_in_task(void (*cb)(struct mg_mgr *mgr, void *arg), void *cb_arg)\n{\n  struct mg_q_msg msg = {MG_Q_MSG_CB, cb, cb_arg};\n  osi_MsgQWrite(&s_mg_q, &msg, OSI_NO_WAIT);\n}\n\n#endif /* MG_NET_IF == MG_NET_IF_SIMPLELINK && !defined(MG_SIMPLELINK_NO_OSI) \\\n        */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/simplelink/sl_net_if.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_COMMON_PLATFORMS_SIMPLELINK_SL_NET_IF_H_\n#define CS_COMMON_PLATFORMS_SIMPLELINK_SL_NET_IF_H_\n\n/* Amalgamated: #include \"mongoose/src/net_if.h\" */\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif /* __cplusplus */\n\n#ifndef MG_ENABLE_NET_IF_SIMPLELINK\n#define MG_ENABLE_NET_IF_SIMPLELINK MG_NET_IF == MG_NET_IF_SIMPLELINK\n#endif\n\n  extern struct mg_iface_vtable mg_simplelink_iface_vtable;\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif /* CS_COMMON_PLATFORMS_SIMPLELINK_SL_NET_IF_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/simplelink/sl_net_if.c\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n/* Amalgamated: #include \"common/platforms/simplelink/sl_net_if.h\" */\n\n#if MG_ENABLE_NET_IF_SIMPLELINK\n\n/* Amalgamated: #include \"mongoose/src/internal.h\" */\n/* Amalgamated: #include \"mongoose/src/util.h\" */\n\n#define MG_TCP_RECV_BUFFER_SIZE 1024\n#define MG_UDP_RECV_BUFFER_SIZE 1500\n\nstatic sock_t mg_open_listening_socket(union socket_address *sa, int type,\n                                       int proto);\n\nint sl_set_ssl_opts(struct mg_connection *nc);\n\nvoid mg_set_non_blocking_mode(sock_t sock)\n{\n  SlSockNonblocking_t opt;\n  opt.NonblockingEnabled = 1;\n  sl_SetSockOpt(sock, SL_SOL_SOCKET, SL_SO_NONBLOCKING, &opt, sizeof(opt));\n}\n\nstatic int mg_is_error(int n)\n{\n  return (n < 0 && n != SL_EALREADY && n != SL_EAGAIN);\n}\n\nvoid mg_sl_if_connect_tcp(struct mg_connection *nc,\n                          const union socket_address *sa)\n{\n  int proto = 0;\n  if (nc->flags & MG_F_SSL)\n    proto = SL_SEC_SOCKET;\n  sock_t sock = sl_Socket(AF_INET, SOCK_STREAM, proto);\n  if (sock < 0)\n  {\n    nc->err = sock;\n    goto out;\n  }\n  mg_sock_set(nc, sock);\n#if MG_ENABLE_SSL\n  nc->err = sl_set_ssl_opts(nc);\n  if (nc->err != 0)\n    goto out;\n#endif\n  nc->err = sl_Connect(sock, &sa->sa, sizeof(sa->sin));\nout:\n  DBG((\"%p to %s:%d sock %d %d err %d\", nc, inet_ntoa(sa->sin.sin_addr),\n       ntohs(sa->sin.sin_port), nc->sock, proto, nc->err));\n}\n\nvoid mg_sl_if_connect_udp(struct mg_connection *nc)\n{\n  sock_t sock = sl_Socket(AF_INET, SOCK_DGRAM, 0);\n  if (sock < 0)\n  {\n    nc->err = sock;\n    return;\n  }\n  mg_sock_set(nc, sock);\n  nc->err = 0;\n}\n\nint mg_sl_if_listen_tcp(struct mg_connection *nc, union socket_address *sa)\n{\n  int proto = 0;\n  if (nc->flags & MG_F_SSL)\n    proto = SL_SEC_SOCKET;\n  sock_t sock = mg_open_listening_socket(sa, SOCK_STREAM, proto);\n  if (sock < 0)\n    return sock;\n  mg_sock_set(nc, sock);\n#if MG_ENABLE_SSL\n  return sl_set_ssl_opts(nc);\n#else\n  return 0;\n#endif\n}\n\nint mg_sl_if_listen_udp(struct mg_connection *nc, union socket_address *sa)\n{\n  sock_t sock = mg_open_listening_socket(sa, SOCK_DGRAM, 0);\n  if (sock == INVALID_SOCKET)\n    return (errno ? errno : 1);\n  mg_sock_set(nc, sock);\n  return 0;\n}\n\nvoid mg_sl_if_tcp_send(struct mg_connection *nc, const void *buf, size_t len)\n{\n  mbuf_append(&nc->send_mbuf, buf, len);\n}\n\nvoid mg_sl_if_udp_send(struct mg_connection *nc, const void *buf, size_t len)\n{\n  mbuf_append(&nc->send_mbuf, buf, len);\n}\n\nvoid mg_sl_if_recved(struct mg_connection *nc, size_t len)\n{\n  (void)nc;\n  (void)len;\n}\n\nint mg_sl_if_create_conn(struct mg_connection *nc)\n{\n  (void)nc;\n  return 1;\n}\n\nvoid mg_sl_if_destroy_conn(struct mg_connection *nc)\n{\n  if (nc->sock == INVALID_SOCKET)\n    return;\n  /* For UDP, only close outgoing sockets or listeners. */\n  if (!(nc->flags & MG_F_UDP) || nc->listener == NULL)\n  {\n    sl_Close(nc->sock);\n  }\n  nc->sock = INVALID_SOCKET;\n}\n\nstatic int mg_accept_conn(struct mg_connection *lc)\n{\n  struct mg_connection *nc;\n  union socket_address sa;\n  socklen_t sa_len = sizeof(sa);\n  sock_t sock = sl_Accept(lc->sock, &sa.sa, &sa_len);\n  if (sock < 0)\n  {\n    DBG((\"%p: failed to accept: %d\", lc, sock));\n    return 0;\n  }\n  nc = mg_if_accept_new_conn(lc);\n  if (nc == NULL)\n  {\n    sl_Close(sock);\n    return 0;\n  }\n  DBG((\"%p conn from %s:%d\", nc, inet_ntoa(sa.sin.sin_addr),\n       ntohs(sa.sin.sin_port)));\n  mg_sock_set(nc, sock);\n  if (nc->flags & MG_F_SSL)\n    nc->flags |= MG_F_SSL_HANDSHAKE_DONE;\n  mg_if_accept_tcp_cb(nc, &sa, sa_len);\n  return 1;\n}\n\n/* 'sa' must be an initialized address to bind to */\nstatic sock_t mg_open_listening_socket(union socket_address *sa, int type,\n                                       int proto)\n{\n  int r;\n  socklen_t sa_len =\n      (sa->sa.sa_family == AF_INET) ? sizeof(sa->sin) : sizeof(sa->sin6);\n  sock_t sock = sl_Socket(sa->sa.sa_family, type, proto);\n  if (sock < 0)\n    return sock;\n  if ((r = sl_Bind(sock, &sa->sa, sa_len)) < 0)\n  {\n    sl_Close(sock);\n    return r;\n  }\n  if (type != SOCK_DGRAM && (r = sl_Listen(sock, SOMAXCONN)) < 0)\n  {\n    sl_Close(sock);\n    return r;\n  }\n  mg_set_non_blocking_mode(sock);\n  return sock;\n}\n\nstatic void mg_write_to_socket(struct mg_connection *nc)\n{\n  struct mbuf *io = &nc->send_mbuf;\n  int n = 0;\n\n  if (nc->flags & MG_F_UDP)\n  {\n    n = sl_SendTo(nc->sock, io->buf, io->len, 0, &nc->sa.sa,\n                  sizeof(nc->sa.sin));\n    DBG((\"%p %d %d %d %s:%hu\", nc, nc->sock, n, errno,\n         inet_ntoa(nc->sa.sin.sin_addr), ntohs(nc->sa.sin.sin_port)));\n  }\n  else\n  {\n    n = (int)sl_Send(nc->sock, io->buf, io->len, 0);\n    DBG((\"%p %d bytes -> %d\", nc, n, nc->sock));\n  }\n\n  if (n > 0)\n  {\n    mbuf_remove(io, n);\n    mg_if_sent_cb(nc, n);\n  }\n  else if (n < 0 && mg_is_error(n))\n  {\n    /* Something went wrong, drop the connection. */\n    nc->flags |= MG_F_CLOSE_IMMEDIATELY;\n  }\n}\n\nMG_INTERNAL size_t recv_avail_size(struct mg_connection *conn, size_t max)\n{\n  size_t avail;\n  if (conn->recv_mbuf_limit < conn->recv_mbuf.len)\n    return 0;\n  avail = conn->recv_mbuf_limit - conn->recv_mbuf.len;\n  return avail > max ? max : avail;\n}\n\nstatic void mg_handle_tcp_read(struct mg_connection *conn)\n{\n  int n = 0;\n  char *buf = (char *)MG_MALLOC(MG_TCP_RECV_BUFFER_SIZE);\n\n  if (buf == NULL)\n  {\n    DBG((\"OOM\"));\n    return;\n  }\n\n  n = (int)sl_Recv(conn->sock, buf,\n                   recv_avail_size(conn, MG_TCP_RECV_BUFFER_SIZE), 0);\n  DBG((\"%p %d bytes <- %d\", conn, n, conn->sock));\n  if (n > 0)\n  {\n    mg_if_recv_tcp_cb(conn, buf, n, 1 /* own */);\n  }\n  else\n  {\n    MG_FREE(buf);\n  }\n  if (n == 0)\n  {\n    /* Orderly shutdown of the socket, try flushing output. */\n    conn->flags |= MG_F_SEND_AND_CLOSE;\n  }\n  else if (mg_is_error(n))\n  {\n    conn->flags |= MG_F_CLOSE_IMMEDIATELY;\n  }\n}\n\nstatic void mg_handle_udp_read(struct mg_connection *nc)\n{\n  char *buf = (char *)MG_MALLOC(MG_UDP_RECV_BUFFER_SIZE);\n  if (buf == NULL)\n    return;\n  union socket_address sa;\n  socklen_t sa_len = sizeof(sa);\n  int n = sl_RecvFrom(nc->sock, buf, MG_UDP_RECV_BUFFER_SIZE, 0,\n                      (SlSockAddr_t *)&sa, &sa_len);\n  DBG((\"%p %d bytes from %s:%d\", nc, n, inet_ntoa(nc->sa.sin.sin_addr),\n       ntohs(nc->sa.sin.sin_port)));\n  if (n > 0)\n  {\n    mg_if_recv_udp_cb(nc, buf, n, &sa, sa_len);\n  }\n  else\n  {\n    MG_FREE(buf);\n  }\n}\n\n#define _MG_F_FD_CAN_READ 1\n#define _MG_F_FD_CAN_WRITE 1 << 1\n#define _MG_F_FD_ERROR 1 << 2\n\nvoid mg_mgr_handle_conn(struct mg_connection *nc, int fd_flags, double now)\n{\n  DBG((\"%p fd=%d fd_flags=%d nc_flags=%lu rmbl=%d smbl=%d\", nc, nc->sock,\n       fd_flags, nc->flags, (int)nc->recv_mbuf.len, (int)nc->send_mbuf.len));\n\n  if (nc->flags & MG_F_CONNECTING)\n  {\n    if (nc->flags & MG_F_UDP || nc->err != SL_EALREADY)\n    {\n      mg_if_connect_cb(nc, nc->err);\n    }\n    else\n    {\n      /* In SimpleLink, to get status of non-blocking connect() we need to wait\n       * until socket is writable and repeat the call to sl_Connect again,\n       * which will now return the real status. */\n      if (fd_flags & _MG_F_FD_CAN_WRITE)\n      {\n        nc->err = sl_Connect(nc->sock, &nc->sa.sa, sizeof(nc->sa.sin));\n        DBG((\"%p conn res=%d\", nc, nc->err));\n        if (nc->err == SL_ESECSNOVERIFY ||\n            /* TODO(rojer): Provide API to set the date for verification. */\n            nc->err == SL_ESECDATEERROR)\n        {\n          nc->err = 0;\n        }\n        if (nc->flags & MG_F_SSL && nc->err == 0)\n        {\n          nc->flags |= MG_F_SSL_HANDSHAKE_DONE;\n        }\n        mg_if_connect_cb(nc, nc->err);\n      }\n    }\n    /* Ignore read/write in further processing, we've handled it. */\n    fd_flags &= ~(_MG_F_FD_CAN_READ | _MG_F_FD_CAN_WRITE);\n  }\n\n  if (fd_flags & _MG_F_FD_CAN_READ)\n  {\n    if (nc->flags & MG_F_UDP)\n    {\n      mg_handle_udp_read(nc);\n    }\n    else\n    {\n      if (nc->flags & MG_F_LISTENING)\n      {\n        mg_accept_conn(nc);\n      }\n      else\n      {\n        mg_handle_tcp_read(nc);\n      }\n    }\n  }\n\n  if (!(nc->flags & MG_F_CLOSE_IMMEDIATELY))\n  {\n    if ((fd_flags & _MG_F_FD_CAN_WRITE) && nc->send_mbuf.len > 0)\n    {\n      mg_write_to_socket(nc);\n    }\n\n    if (!(fd_flags & (_MG_F_FD_CAN_READ | _MG_F_FD_CAN_WRITE)))\n    {\n      mg_if_poll(nc, now);\n    }\n    mg_if_timer(nc, now);\n  }\n\n  DBG((\"%p after fd=%d nc_flags=%lu rmbl=%d smbl=%d\", nc, nc->sock, nc->flags,\n       (int)nc->recv_mbuf.len, (int)nc->send_mbuf.len));\n}\n\n/* Associate a socket to a connection. */\nvoid mg_sl_if_sock_set(struct mg_connection *nc, sock_t sock)\n{\n  mg_set_non_blocking_mode(sock);\n  nc->sock = sock;\n  DBG((\"%p %d\", nc, sock));\n}\n\nvoid mg_sl_if_init(struct mg_iface *iface)\n{\n  (void)iface;\n  DBG((\"%p using sl_Select()\", iface->mgr));\n}\n\nvoid mg_sl_if_free(struct mg_iface *iface)\n{\n  (void)iface;\n}\n\nvoid mg_sl_if_add_conn(struct mg_connection *nc)\n{\n  (void)nc;\n}\n\nvoid mg_sl_if_remove_conn(struct mg_connection *nc)\n{\n  (void)nc;\n}\n\ntime_t mg_sl_if_poll(struct mg_iface *iface, int timeout_ms)\n{\n  struct mg_mgr *mgr = iface->mgr;\n  double now = mg_time();\n  double min_timer;\n  struct mg_connection *nc, *tmp;\n  struct SlTimeval_t tv;\n  SlFdSet_t read_set, write_set, err_set;\n  sock_t max_fd = INVALID_SOCKET;\n  int num_fds, num_ev, num_timers = 0;\n\n  SL_FD_ZERO(&read_set);\n  SL_FD_ZERO(&write_set);\n  SL_FD_ZERO(&err_set);\n\n  /*\n   * Note: it is ok to have connections with sock == INVALID_SOCKET in the list,\n   * e.g. timer-only \"connections\".\n   */\n  min_timer = 0;\n  for (nc = mgr->active_connections, num_fds = 0; nc != NULL; nc = tmp)\n  {\n    tmp = nc->next;\n\n    if (nc->sock != INVALID_SOCKET)\n    {\n      num_fds++;\n\n      if (!(nc->flags & MG_F_WANT_WRITE) &&\n          nc->recv_mbuf.len < nc->recv_mbuf_limit &&\n          (!(nc->flags & MG_F_UDP) || nc->listener == NULL))\n      {\n        SL_FD_SET(nc->sock, &read_set);\n        if (max_fd == INVALID_SOCKET || nc->sock > max_fd)\n          max_fd = nc->sock;\n      }\n\n      if (((nc->flags & MG_F_CONNECTING) && !(nc->flags & MG_F_WANT_READ)) ||\n          (nc->send_mbuf.len > 0 && !(nc->flags & MG_F_CONNECTING)))\n      {\n        SL_FD_SET(nc->sock, &write_set);\n        SL_FD_SET(nc->sock, &err_set);\n        if (max_fd == INVALID_SOCKET || nc->sock > max_fd)\n          max_fd = nc->sock;\n      }\n    }\n\n    if (nc->ev_timer_time > 0)\n    {\n      if (num_timers == 0 || nc->ev_timer_time < min_timer)\n      {\n        min_timer = nc->ev_timer_time;\n      }\n      num_timers++;\n    }\n  }\n\n  /*\n   * If there is a timer to be fired earlier than the requested timeout,\n   * adjust the timeout.\n   */\n  if (num_timers > 0)\n  {\n    double timer_timeout_ms = (min_timer - mg_time()) * 1000 + 1 /* rounding */;\n    if (timer_timeout_ms < timeout_ms)\n    {\n      timeout_ms = timer_timeout_ms;\n    }\n  }\n  if (timeout_ms < 0)\n    timeout_ms = 0;\n\n  tv.tv_sec = timeout_ms / 1000;\n  tv.tv_usec = (timeout_ms % 1000) * 1000;\n\n  num_ev = sl_Select((int)max_fd + 1, &read_set, &write_set, &err_set, &tv);\n  now = mg_time();\n  DBG((\"sl_Select @ %ld num_ev=%d of %d, timeout=%d\", (long)now, num_ev,\n       num_fds, timeout_ms));\n\n  for (nc = mgr->active_connections; nc != NULL; nc = tmp)\n  {\n    int fd_flags = 0;\n    if (nc->sock != INVALID_SOCKET)\n    {\n      if (num_ev > 0)\n      {\n        fd_flags =\n            (SL_FD_ISSET(nc->sock, &read_set) &&\n                     (!(nc->flags & MG_F_UDP) || nc->listener == NULL)\n                 ? _MG_F_FD_CAN_READ\n                 : 0) |\n            (SL_FD_ISSET(nc->sock, &write_set) ? _MG_F_FD_CAN_WRITE : 0) |\n            (SL_FD_ISSET(nc->sock, &err_set) ? _MG_F_FD_ERROR : 0);\n      }\n      /* SimpleLink does not report UDP sockets as writeable. */\n      if (nc->flags & MG_F_UDP && nc->send_mbuf.len > 0)\n      {\n        fd_flags |= _MG_F_FD_CAN_WRITE;\n      }\n    }\n    tmp = nc->next;\n    mg_mgr_handle_conn(nc, fd_flags, now);\n  }\n\n  for (nc = mgr->active_connections; nc != NULL; nc = tmp)\n  {\n    tmp = nc->next;\n    if ((nc->flags & MG_F_CLOSE_IMMEDIATELY) ||\n        (nc->send_mbuf.len == 0 && (nc->flags & MG_F_SEND_AND_CLOSE)))\n    {\n      mg_close_conn(nc);\n    }\n  }\n\n  return now;\n}\n\nvoid mg_sl_if_get_conn_addr(struct mg_connection *nc, int remote,\n                            union socket_address *sa)\n{\n  /* SimpleLink does not provide a way to get socket's peer address after\n   * accept or connect. Address hould have been preserved in the connection,\n   * so we do our best here by using it. */\n  if (remote)\n    memcpy(sa, &nc->sa, sizeof(*sa));\n}\n\nvoid sl_restart_cb(struct mg_mgr *mgr)\n{\n  /*\n   * SimpleLink has been restarted, meaning all sockets have been invalidated.\n   * We try our best - we'll restart the listeners, but for outgoing\n   * connections we have no option but to terminate.\n   */\n  struct mg_connection *nc;\n  for (nc = mg_next(mgr, NULL); nc != NULL; nc = mg_next(mgr, nc))\n  {\n    if (nc->sock == INVALID_SOCKET)\n      continue; /* Could be a timer */\n    if (nc->flags & MG_F_LISTENING)\n    {\n      DBG((\"restarting %p %s:%d\", nc, inet_ntoa(nc->sa.sin.sin_addr),\n           ntohs(nc->sa.sin.sin_port)));\n      int res = (nc->flags & MG_F_UDP ? mg_sl_if_listen_udp(nc, &nc->sa)\n                                      : mg_sl_if_listen_tcp(nc, &nc->sa));\n      if (res == 0)\n        continue;\n      /* Well, we tried and failed. Fall through to closing. */\n    }\n    nc->sock = INVALID_SOCKET;\n    DBG((\"terminating %p %s:%d\", nc, inet_ntoa(nc->sa.sin.sin_addr),\n         ntohs(nc->sa.sin.sin_port)));\n    /* TODO(rojer): Outgoing UDP? */\n    nc->flags |= MG_F_CLOSE_IMMEDIATELY;\n  }\n}\n\n/* clang-format off */\n#define MG_SL_IFACE_VTABLE                                              \\\n  {                                                                     \\\n    mg_sl_if_init,                                                      \\\n    mg_sl_if_free,                                                      \\\n    mg_sl_if_add_conn,                                                  \\\n    mg_sl_if_remove_conn,                                               \\\n    mg_sl_if_poll,                                                      \\\n    mg_sl_if_listen_tcp,                                                \\\n    mg_sl_if_listen_udp,                                                \\\n    mg_sl_if_connect_tcp,                                               \\\n    mg_sl_if_connect_udp,                                               \\\n    mg_sl_if_tcp_send,                                                  \\\n    mg_sl_if_udp_send,                                                  \\\n    mg_sl_if_recved,                                                    \\\n    mg_sl_if_create_conn,                                               \\\n    mg_sl_if_destroy_conn,                                              \\\n    mg_sl_if_sock_set,                                                  \\\n    mg_sl_if_get_conn_addr,                                             \\\n  }\n/* clang-format on */\n\nstruct mg_iface_vtable mg_simplelink_iface_vtable = MG_SL_IFACE_VTABLE;\n#if MG_NET_IF == MG_NET_IF_SIMPLELINK\nstruct mg_iface_vtable mg_default_iface_vtable = MG_SL_IFACE_VTABLE;\n#endif\n\n#endif /* MG_ENABLE_NET_IF_SIMPLELINK */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/simplelink/sl_ssl_if.c\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#if MG_ENABLE_SSL && MG_SSL_IF == MG_SSL_IF_SIMPLELINK\n\nstruct mg_ssl_if_ctx\n{\n  char *ssl_cert;\n  char *ssl_key;\n  char *ssl_ca_cert;\n  char *ssl_server_name;\n};\n\nvoid mg_ssl_if_init()\n{\n}\n\nenum mg_ssl_if_result mg_ssl_if_conn_init(\n    struct mg_connection *nc, const struct mg_ssl_if_conn_params *params,\n    const char **err_msg)\n{\n  struct mg_ssl_if_ctx *ctx =\n      (struct mg_ssl_if_ctx *)MG_CALLOC(1, sizeof(*ctx));\n  if (ctx == NULL)\n  {\n    MG_SET_PTRPTR(err_msg, \"Out of memory\");\n    return MG_SSL_ERROR;\n  }\n  nc->ssl_if_data = ctx;\n\n  if (params->cert != NULL || params->key != NULL)\n  {\n    if (params->cert != NULL && params->key != NULL)\n    {\n      ctx->ssl_cert = strdup(params->cert);\n      ctx->ssl_key = strdup(params->key);\n    }\n    else\n    {\n      MG_SET_PTRPTR(err_msg, \"Both cert and key are required.\");\n      return MG_SSL_ERROR;\n    }\n  }\n  if (params->ca_cert != NULL && strcmp(params->ca_cert, \"*\") != 0)\n  {\n    ctx->ssl_ca_cert = strdup(params->ca_cert);\n  }\n  if (params->server_name != NULL)\n  {\n    ctx->ssl_server_name = strdup(params->server_name);\n  }\n  return MG_SSL_OK;\n}\n\nvoid mg_ssl_if_conn_free(struct mg_connection *nc)\n{\n  struct mg_ssl_if_ctx *ctx = (struct mg_ssl_if_ctx *)nc->ssl_if_data;\n  if (ctx == NULL)\n    return;\n  nc->ssl_if_data = NULL;\n  MG_FREE(ctx->ssl_cert);\n  MG_FREE(ctx->ssl_key);\n  MG_FREE(ctx->ssl_ca_cert);\n  MG_FREE(ctx->ssl_server_name);\n  memset(ctx, 0, sizeof(*ctx));\n  MG_FREE(ctx);\n}\n\nint sl_set_ssl_opts(struct mg_connection *nc)\n{\n  int err;\n  struct mg_ssl_if_ctx *ctx = (struct mg_ssl_if_ctx *)nc->ssl_if_data;\n  DBG((\"%p ssl ctx: %p\", nc, ctx));\n\n  if (ctx != NULL)\n  {\n    DBG((\"%p %s,%s,%s,%s\", nc, (ctx->ssl_cert ? ctx->ssl_cert : \"-\"),\n         (ctx->ssl_key ? ctx->ssl_cert : \"-\"),\n         (ctx->ssl_ca_cert ? ctx->ssl_ca_cert : \"-\"),\n         (ctx->ssl_server_name ? ctx->ssl_server_name : \"-\")));\n    if (ctx->ssl_cert != NULL && ctx->ssl_key != NULL)\n    {\n      err = sl_SetSockOpt(nc->sock, SL_SOL_SOCKET,\n                          SL_SO_SECURE_FILES_CERTIFICATE_FILE_NAME,\n                          ctx->ssl_cert, strlen(ctx->ssl_cert));\n      DBG((\"CERTIFICATE_FILE_NAME %s -> %d\", ctx->ssl_cert, err));\n      if (err != 0)\n        return err;\n      err = sl_SetSockOpt(nc->sock, SL_SOL_SOCKET,\n                          SL_SO_SECURE_FILES_PRIVATE_KEY_FILE_NAME,\n                          ctx->ssl_key, strlen(ctx->ssl_key));\n      DBG((\"PRIVATE_KEY_FILE_NAME %s -> %d\", ctx->ssl_key, nc->err));\n      if (err != 0)\n        return err;\n    }\n    if (ctx->ssl_ca_cert != NULL)\n    {\n      if (ctx->ssl_ca_cert[0] != '\\0')\n      {\n        err = sl_SetSockOpt(nc->sock, SL_SOL_SOCKET,\n                            SL_SO_SECURE_FILES_CA_FILE_NAME, ctx->ssl_ca_cert,\n                            strlen(ctx->ssl_ca_cert));\n        DBG((\"CA_FILE_NAME %s -> %d\", ctx->ssl_ca_cert, err));\n        if (err != 0)\n          return err;\n      }\n    }\n    if (ctx->ssl_server_name != NULL)\n    {\n      err = sl_SetSockOpt(nc->sock, SL_SOL_SOCKET,\n                          SO_SECURE_DOMAIN_NAME_VERIFICATION,\n                          ctx->ssl_server_name, strlen(ctx->ssl_server_name));\n      DBG((\"DOMAIN_NAME_VERIFICATION %s -> %d\", ctx->ssl_server_name, err));\n      /* Domain name verificationw as added in a NWP service pack, older\n       * versions return SL_ENOPROTOOPT. There isn't much we can do about it,\n       * so we ignore the error. */\n      if (err != 0 && err != SL_ENOPROTOOPT)\n        return err;\n    }\n  }\n  return 0;\n}\n\n#endif /* MG_ENABLE_SSL && MG_SSL_IF == MG_SSL_IF_SIMPLELINK */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/lwip/mg_lwip_net_if.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_COMMON_PLATFORMS_LWIP_MG_NET_IF_LWIP_H_\n#define CS_COMMON_PLATFORMS_LWIP_MG_NET_IF_LWIP_H_\n\n#ifndef MG_ENABLE_NET_IF_LWIP_LOW_LEVEL\n#define MG_ENABLE_NET_IF_LWIP_LOW_LEVEL MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL\n#endif\n\n#if MG_ENABLE_NET_IF_LWIP_LOW_LEVEL\n\n#include <stdint.h>\n\nextern struct mg_iface_vtable mg_lwip_iface_vtable;\n\nstruct mg_lwip_conn_state\n{\n  struct mg_connection *nc;\n  union {\n    struct tcp_pcb *tcp;\n    struct udp_pcb *udp;\n  } pcb;\n  err_t err;\n  size_t num_sent;       /* Number of acknowledged bytes to be reported to the core */\n  struct pbuf *rx_chain; /* Chain of incoming data segments. */\n  size_t rx_offset;      /* Offset within the first pbuf (if partially consumed) */\n  /* Last SSL write size, for retries. */\n  int last_ssl_write_size;\n};\n\nenum mg_sig_type\n{\n  MG_SIG_CONNECT_RESULT = 1,\n  MG_SIG_RECV = 2,\n  MG_SIG_SENT_CB = 3,\n  MG_SIG_CLOSE_CONN = 4,\n  MG_SIG_TOMBSTONE = 5,\n};\n\nvoid mg_lwip_post_signal(enum mg_sig_type sig, struct mg_connection *nc);\n\n/* To be implemented by the platform. */\nvoid mg_lwip_mgr_schedule_poll(struct mg_mgr *mgr);\n\n#endif /* MG_ENABLE_NET_IF_LWIP_LOW_LEVEL */\n\n#endif /* CS_COMMON_PLATFORMS_LWIP_MG_NET_IF_LWIP_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/lwip/mg_lwip_net_if.c\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#if MG_ENABLE_NET_IF_LWIP_LOW_LEVEL\n\n#include <lwip/pbuf.h>\n#include <lwip/tcp.h>\n#include <lwip/tcp_impl.h>\n#include <lwip/udp.h>\n\n/* Amalgamated: #include \"common/cs_dbg.h\" */\n\n/*\n * Depending on whether Mongoose is compiled with ipv6 support, use right\n * lwip functions\n */\n#if MG_ENABLE_IPV6\n#define TCP_NEW tcp_new_ip6\n#define TCP_BIND tcp_bind_ip6\n#define UDP_BIND udp_bind_ip6\n#define IPADDR_NTOA(x) ip6addr_ntoa((const ip6_addr_t *)(x))\n#define SET_ADDR(dst, src)                               \\\n  memcpy((dst)->sin6.sin6_addr.s6_addr, (src)->ip6.addr, \\\n         sizeof((dst)->sin6.sin6_addr.s6_addr))\n#else\n#define TCP_NEW tcp_new\n#define TCP_BIND tcp_bind\n#define UDP_BIND udp_bind\n#define IPADDR_NTOA ipaddr_ntoa\n#define SET_ADDR(dst, src) (dst)->sin.sin_addr.s_addr = GET_IPV4(src)\n#endif\n\n/*\n * If lwip is compiled with ipv6 support, then API changes even for ipv4\n */\n#if !defined(LWIP_IPV6) || !LWIP_IPV6\n#define GET_IPV4(ipX_addr) ((ipX_addr)->addr)\n#else\n#define GET_IPV4(ipX_addr) ((ipX_addr)->ip4.addr)\n#endif\n\nvoid mg_lwip_ssl_do_hs(struct mg_connection *nc);\nvoid mg_lwip_ssl_send(struct mg_connection *nc);\nvoid mg_lwip_ssl_recv(struct mg_connection *nc);\n\nvoid mg_lwip_if_init(struct mg_iface *iface);\nvoid mg_lwip_if_free(struct mg_iface *iface);\nvoid mg_lwip_if_add_conn(struct mg_connection *nc);\nvoid mg_lwip_if_remove_conn(struct mg_connection *nc);\ntime_t mg_lwip_if_poll(struct mg_iface *iface, int timeout_ms);\n\n#if LWIP_TCP_KEEPALIVE\nvoid mg_lwip_set_keepalive_params(struct mg_connection *nc, int idle,\n                                  int interval, int count)\n{\n  if (nc->sock == INVALID_SOCKET || nc->flags & MG_F_UDP)\n  {\n    return;\n  }\n  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)nc->sock;\n  struct tcp_pcb *tpcb = cs->pcb.tcp;\n  if (idle > 0 && interval > 0 && count > 0)\n  {\n    tpcb->keep_idle = idle * 1000;\n    tpcb->keep_intvl = interval * 1000;\n    tpcb->keep_cnt = count;\n    tpcb->so_options |= SOF_KEEPALIVE;\n  }\n  else\n  {\n    tpcb->so_options &= ~SOF_KEEPALIVE;\n  }\n}\n#elif !defined(MG_NO_LWIP_TCP_KEEPALIVE)\n#warning LWIP TCP keepalive is disabled. Please consider enabling it.\n#endif /* LWIP_TCP_KEEPALIVE */\n\nstatic err_t mg_lwip_tcp_conn_cb(void *arg, struct tcp_pcb *tpcb, err_t err)\n{\n  struct mg_connection *nc = (struct mg_connection *)arg;\n  DBG((\"%p connect to %s:%u = %d\", nc, IPADDR_NTOA(&tpcb->remote_ip),\n       tpcb->remote_port, err));\n  if (nc == NULL)\n  {\n    tcp_abort(tpcb);\n    return ERR_ARG;\n  }\n  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)nc->sock;\n  cs->err = err;\n#if LWIP_TCP_KEEPALIVE\n  if (err == 0)\n    mg_lwip_set_keepalive_params(nc, 60, 10, 6);\n#endif\n  mg_lwip_post_signal(MG_SIG_CONNECT_RESULT, nc);\n  return ERR_OK;\n}\n\nstatic void mg_lwip_tcp_error_cb(void *arg, err_t err)\n{\n  struct mg_connection *nc = (struct mg_connection *)arg;\n  DBG((\"%p conn error %d\", nc, err));\n  if (nc == NULL)\n    return;\n  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)nc->sock;\n  cs->pcb.tcp = NULL; /* Has already been deallocated */\n  if (nc->flags & MG_F_CONNECTING)\n  {\n    cs->err = err;\n    mg_lwip_post_signal(MG_SIG_CONNECT_RESULT, nc);\n  }\n  else\n  {\n    mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);\n  }\n}\n\nstatic err_t mg_lwip_tcp_recv_cb(void *arg, struct tcp_pcb *tpcb,\n                                 struct pbuf *p, err_t err)\n{\n  struct mg_connection *nc = (struct mg_connection *)arg;\n  DBG((\"%p %p %u %d\", nc, tpcb, (p != NULL ? p->tot_len : 0), err));\n  if (p == NULL)\n  {\n    if (nc != NULL)\n    {\n      mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);\n    }\n    else\n    {\n      /* Tombstoned connection, do nothing. */\n    }\n    return ERR_OK;\n  }\n  else if (nc == NULL)\n  {\n    tcp_abort(tpcb);\n    return ERR_ARG;\n  }\n  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)nc->sock;\n  /*\n   * If we get a chain of more than one segment at once, we need to bump\n   * refcount on the subsequent bufs to make them independent.\n   */\n  if (p->next != NULL)\n  {\n    struct pbuf *q = p->next;\n    for (; q != NULL; q = q->next)\n      pbuf_ref(q);\n  }\n  if (cs->rx_chain == NULL)\n  {\n    cs->rx_chain = p;\n    cs->rx_offset = 0;\n  }\n  else\n  {\n    if (pbuf_clen(cs->rx_chain) >= 4)\n    {\n      /* ESP SDK has a limited pool of 5 pbufs. We must not hog them all or RX\n       * will be completely blocked. We already have at least 4 in the chain,\n       * this one is, so we have to make a copy and release this one. */\n      struct pbuf *np = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM);\n      if (np != NULL)\n      {\n        pbuf_copy(np, p);\n        pbuf_free(p);\n        p = np;\n      }\n    }\n    pbuf_chain(cs->rx_chain, p);\n  }\n  mg_lwip_post_signal(MG_SIG_RECV, nc);\n  return ERR_OK;\n}\n\nstatic void mg_lwip_handle_recv(struct mg_connection *nc)\n{\n  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)nc->sock;\n\n#if MG_ENABLE_SSL\n  if (nc->flags & MG_F_SSL)\n  {\n    if (nc->flags & MG_F_SSL_HANDSHAKE_DONE)\n    {\n      mg_lwip_ssl_recv(nc);\n    }\n    else\n    {\n      mg_lwip_ssl_do_hs(nc);\n    }\n    return;\n  }\n#endif\n\n  while (cs->rx_chain != NULL)\n  {\n    struct pbuf *seg = cs->rx_chain;\n    size_t len = (seg->len - cs->rx_offset);\n    char *data = (char *)malloc(len);\n    if (data == NULL)\n    {\n      DBG((\"OOM\"));\n      return;\n    }\n    pbuf_copy_partial(seg, data, len, cs->rx_offset);\n    mg_if_recv_tcp_cb(nc, data, len, 1 /* own */);\n    cs->rx_offset += len;\n    if (cs->rx_offset == cs->rx_chain->len)\n    {\n      cs->rx_chain = pbuf_dechain(cs->rx_chain);\n      pbuf_free(seg);\n      cs->rx_offset = 0;\n    }\n  }\n\n  if (nc->send_mbuf.len > 0)\n  {\n    mg_lwip_mgr_schedule_poll(nc->mgr);\n  }\n}\n\nstatic err_t mg_lwip_tcp_sent_cb(void *arg, struct tcp_pcb *tpcb,\n                                 u16_t num_sent)\n{\n  struct mg_connection *nc = (struct mg_connection *)arg;\n  DBG((\"%p %p %u\", nc, tpcb, num_sent));\n  if (nc == NULL)\n  {\n    tcp_abort(tpcb);\n    return ERR_ABRT;\n  }\n  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)nc->sock;\n  cs->num_sent += num_sent;\n\n  mg_lwip_post_signal(MG_SIG_SENT_CB, nc);\n  return ERR_OK;\n}\n\nvoid mg_lwip_if_connect_tcp(struct mg_connection *nc,\n                            const union socket_address *sa)\n{\n  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)nc->sock;\n  struct tcp_pcb *tpcb = TCP_NEW();\n  cs->pcb.tcp = tpcb;\n  ip_addr_t *ip = (ip_addr_t *)&sa->sin.sin_addr.s_addr;\n  u16_t port = ntohs(sa->sin.sin_port);\n  tcp_arg(tpcb, nc);\n  tcp_err(tpcb, mg_lwip_tcp_error_cb);\n  tcp_sent(tpcb, mg_lwip_tcp_sent_cb);\n  tcp_recv(tpcb, mg_lwip_tcp_recv_cb);\n  cs->err = TCP_BIND(tpcb, IP_ADDR_ANY, 0 /* any port */);\n  DBG((\"%p tcp_bind = %d\", nc, cs->err));\n  if (cs->err != ERR_OK)\n  {\n    mg_lwip_post_signal(MG_SIG_CONNECT_RESULT, nc);\n    return;\n  }\n  cs->err = tcp_connect(tpcb, ip, port, mg_lwip_tcp_conn_cb);\n  DBG((\"%p tcp_connect %p = %d\", nc, tpcb, cs->err));\n  if (cs->err != ERR_OK)\n  {\n    mg_lwip_post_signal(MG_SIG_CONNECT_RESULT, nc);\n    return;\n  }\n}\n\n/*\n * Lwip included in the SDKs for nRF5x chips has different type for the\n * callback of `udp_recv()`\n */\n#if CS_PLATFORM == CS_P_NRF51 || CS_PLATFORM == CS_P_NRF52\nstatic void mg_lwip_udp_recv_cb(void *arg, struct udp_pcb *pcb, struct pbuf *p,\n                                const ip_addr_t *addr, u16_t port)\n#else\nstatic void mg_lwip_udp_recv_cb(void *arg, struct udp_pcb *pcb, struct pbuf *p,\n                                ip_addr_t *addr, u16_t port)\n#endif\n{\n  struct mg_connection *nc = (struct mg_connection *)arg;\n  size_t len = p->len;\n  char *data = (char *)malloc(len);\n  union socket_address sa;\n  (void)pcb;\n  DBG((\"%p %s:%u %u\", nc, IPADDR_NTOA(addr), port, p->len));\n  if (data == NULL)\n  {\n    DBG((\"OOM\"));\n    pbuf_free(p);\n    return;\n  }\n  sa.sin.sin_addr.s_addr = addr->addr;\n  sa.sin.sin_port = htons(port);\n  pbuf_copy_partial(p, data, len, 0);\n  pbuf_free(p);\n  mg_if_recv_udp_cb(nc, data, len, &sa, sizeof(sa.sin));\n}\n\nvoid mg_lwip_if_connect_udp(struct mg_connection *nc)\n{\n  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)nc->sock;\n  struct udp_pcb *upcb = udp_new();\n  cs->err = UDP_BIND(upcb, IP_ADDR_ANY, 0 /* any port */);\n  DBG((\"%p udp_bind %p = %d\", nc, upcb, cs->err));\n  if (cs->err == ERR_OK)\n  {\n    udp_recv(upcb, mg_lwip_udp_recv_cb, nc);\n    cs->pcb.udp = upcb;\n  }\n  else\n  {\n    udp_remove(upcb);\n  }\n  mg_lwip_post_signal(MG_SIG_CONNECT_RESULT, nc);\n}\n\nvoid mg_lwip_accept_conn(struct mg_connection *nc, struct tcp_pcb *tpcb)\n{\n  union socket_address sa;\n  SET_ADDR(&sa, &tpcb->remote_ip);\n  sa.sin.sin_port = htons(tpcb->remote_port);\n  mg_if_accept_tcp_cb(nc, &sa, sizeof(sa.sin));\n}\n\nstatic err_t mg_lwip_accept_cb(void *arg, struct tcp_pcb *newtpcb, err_t err)\n{\n  struct mg_connection *lc = (struct mg_connection *)arg;\n  (void)err;\n  DBG((\"%p conn %p from %s:%u\", lc, newtpcb, IPADDR_NTOA(&newtpcb->remote_ip),\n       newtpcb->remote_port));\n  struct mg_connection *nc = mg_if_accept_new_conn(lc);\n  if (nc == NULL)\n  {\n    tcp_abort(newtpcb);\n    return ERR_ABRT;\n  }\n  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)nc->sock;\n  cs->pcb.tcp = newtpcb;\n  tcp_arg(newtpcb, nc);\n  tcp_err(newtpcb, mg_lwip_tcp_error_cb);\n  tcp_sent(newtpcb, mg_lwip_tcp_sent_cb);\n  tcp_recv(newtpcb, mg_lwip_tcp_recv_cb);\n#if LWIP_TCP_KEEPALIVE\n  mg_lwip_set_keepalive_params(nc, 60, 10, 6);\n#endif\n#if MG_ENABLE_SSL\n  if (lc->flags & MG_F_SSL)\n  {\n    if (mg_ssl_if_conn_accept(nc, lc) != MG_SSL_OK)\n    {\n      LOG(LL_ERROR, (\"SSL error\"));\n      tcp_close(newtpcb);\n    }\n  }\n  else\n#endif\n  {\n    mg_lwip_accept_conn(nc, newtpcb);\n  }\n  return ERR_OK;\n}\n\nint mg_lwip_if_listen_tcp(struct mg_connection *nc, union socket_address *sa)\n{\n  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)nc->sock;\n  struct tcp_pcb *tpcb = TCP_NEW();\n  ip_addr_t *ip = (ip_addr_t *)&sa->sin.sin_addr.s_addr;\n  u16_t port = ntohs(sa->sin.sin_port);\n  cs->err = TCP_BIND(tpcb, ip, port);\n  DBG((\"%p tcp_bind(%s:%u) = %d\", nc, IPADDR_NTOA(ip), port, cs->err));\n  if (cs->err != ERR_OK)\n  {\n    tcp_close(tpcb);\n    return -1;\n  }\n  tcp_arg(tpcb, nc);\n  tpcb = tcp_listen(tpcb);\n  cs->pcb.tcp = tpcb;\n  tcp_accept(tpcb, mg_lwip_accept_cb);\n  return 0;\n}\n\nint mg_lwip_if_listen_udp(struct mg_connection *nc, union socket_address *sa)\n{\n  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)nc->sock;\n  struct udp_pcb *upcb = udp_new();\n  ip_addr_t *ip = (ip_addr_t *)&sa->sin.sin_addr.s_addr;\n  u16_t port = ntohs(sa->sin.sin_port);\n  cs->err = UDP_BIND(upcb, ip, port);\n  DBG((\"%p udb_bind(%s:%u) = %d\", nc, IPADDR_NTOA(ip), port, cs->err));\n  if (cs->err != ERR_OK)\n  {\n    udp_remove(upcb);\n    return -1;\n  }\n  udp_recv(upcb, mg_lwip_udp_recv_cb, nc);\n  cs->pcb.udp = upcb;\n  return 0;\n}\n\nint mg_lwip_tcp_write(struct mg_connection *nc, const void *data,\n                      uint16_t len)\n{\n  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)nc->sock;\n  struct tcp_pcb *tpcb = cs->pcb.tcp;\n  len = MIN(tpcb->mss, MIN(len, tpcb->snd_buf));\n  if (len == 0)\n  {\n    DBG((\"%p no buf avail %u %u %u %p %p\", tpcb, tpcb->acked, tpcb->snd_buf,\n         tpcb->snd_queuelen, tpcb->unsent, tpcb->unacked));\n    tcp_output(tpcb);\n    return 0;\n  }\n  err_t err = tcp_write(tpcb, data, len, TCP_WRITE_FLAG_COPY);\n  tcp_output(tpcb);\n  DBG((\"%p tcp_write %u = %d\", tpcb, len, err));\n  if (err != ERR_OK)\n  {\n    /*\n     * We ignore ERR_MEM because memory will be freed up when the data is sent\n     * and we'll retry.\n     */\n    return (err == ERR_MEM ? 0 : -1);\n  }\n  return len;\n}\n\nstatic void mg_lwip_send_more(struct mg_connection *nc)\n{\n  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)nc->sock;\n  if (nc->sock == INVALID_SOCKET || cs->pcb.tcp == NULL)\n  {\n    DBG((\"%p invalid socket\", nc));\n    return;\n  }\n  int num_written = mg_lwip_tcp_write(nc, nc->send_mbuf.buf, nc->send_mbuf.len);\n  DBG((\"%p mg_lwip_tcp_write %u = %d\", nc, nc->send_mbuf.len, num_written));\n  if (num_written == 0)\n    return;\n  if (num_written < 0)\n  {\n    mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);\n  }\n  mbuf_remove(&nc->send_mbuf, num_written);\n  mbuf_trim(&nc->send_mbuf);\n}\n\nvoid mg_lwip_if_tcp_send(struct mg_connection *nc, const void *buf,\n                         size_t len)\n{\n  mbuf_append(&nc->send_mbuf, buf, len);\n  mg_lwip_mgr_schedule_poll(nc->mgr);\n}\n\nvoid mg_lwip_if_udp_send(struct mg_connection *nc, const void *buf,\n                         size_t len)\n{\n  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)nc->sock;\n  if (nc->sock == INVALID_SOCKET || cs->pcb.udp == NULL)\n  {\n    /*\n     * In case of UDP, this usually means, what\n     * async DNS resolve is still in progress and connection\n     * is not ready yet\n     */\n    DBG((\"%p socket is not connected\", nc));\n    return;\n  }\n  struct udp_pcb *upcb = cs->pcb.udp;\n  struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);\n  ip_addr_t *ip = (ip_addr_t *)&nc->sa.sin.sin_addr.s_addr;\n  u16_t port = ntohs(nc->sa.sin.sin_port);\n  memcpy(p->payload, buf, len);\n  cs->err = udp_sendto(upcb, p, (ip_addr_t *)ip, port);\n  DBG((\"%p udp_sendto = %d\", nc, cs->err));\n  pbuf_free(p);\n  if (cs->err != ERR_OK)\n  {\n    mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);\n  }\n  else\n  {\n    cs->num_sent += len;\n    mg_lwip_post_signal(MG_SIG_SENT_CB, nc);\n  }\n}\n\nvoid mg_lwip_if_recved(struct mg_connection *nc, size_t len)\n{\n  if (nc->flags & MG_F_UDP)\n    return;\n  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)nc->sock;\n  if (nc->sock == INVALID_SOCKET || cs->pcb.tcp == NULL)\n  {\n    DBG((\"%p invalid socket\", nc));\n    return;\n  }\n  DBG((\"%p %p %u\", nc, cs->pcb.tcp, len));\n/* Currently SSL acknowledges data immediately.\n * TODO(rojer): Find a way to propagate mg_lwip_if_recved. */\n#if MG_ENABLE_SSL\n  if (!(nc->flags & MG_F_SSL))\n  {\n    tcp_recved(cs->pcb.tcp, len);\n  }\n#else\n  tcp_recved(cs->pcb.tcp, len);\n#endif\n  mbuf_trim(&nc->recv_mbuf);\n}\n\nint mg_lwip_if_create_conn(struct mg_connection *nc)\n{\n  struct mg_lwip_conn_state *cs =\n      (struct mg_lwip_conn_state *)calloc(1, sizeof(*cs));\n  if (cs == NULL)\n    return 0;\n  cs->nc = nc;\n  nc->sock = (intptr_t)cs;\n  return 1;\n}\n\nvoid mg_lwip_if_destroy_conn(struct mg_connection *nc)\n{\n  if (nc->sock == INVALID_SOCKET)\n    return;\n  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)nc->sock;\n  if (!(nc->flags & MG_F_UDP))\n  {\n    struct tcp_pcb *tpcb = cs->pcb.tcp;\n    if (tpcb != NULL)\n    {\n      tcp_arg(tpcb, NULL);\n      DBG((\"%p tcp_close %p\", nc, tpcb));\n      tcp_arg(tpcb, NULL);\n      tcp_close(tpcb);\n    }\n    while (cs->rx_chain != NULL)\n    {\n      struct pbuf *seg = cs->rx_chain;\n      cs->rx_chain = pbuf_dechain(cs->rx_chain);\n      pbuf_free(seg);\n    }\n    memset(cs, 0, sizeof(*cs));\n    free(cs);\n  }\n  else if (nc->listener == NULL)\n  {\n    /* Only close outgoing UDP pcb or listeners. */\n    struct udp_pcb *upcb = cs->pcb.udp;\n    if (upcb != NULL)\n    {\n      DBG((\"%p udp_remove %p\", nc, upcb));\n      udp_remove(upcb);\n    }\n    memset(cs, 0, sizeof(*cs));\n    free(cs);\n  }\n  nc->sock = INVALID_SOCKET;\n}\n\nvoid mg_lwip_if_get_conn_addr(struct mg_connection *nc, int remote,\n                              union socket_address *sa)\n{\n  memset(sa, 0, sizeof(*sa));\n  if (nc->sock == INVALID_SOCKET)\n    return;\n  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)nc->sock;\n  if (nc->flags & MG_F_UDP)\n  {\n    struct udp_pcb *upcb = cs->pcb.udp;\n    if (remote)\n    {\n      memcpy(sa, &nc->sa, sizeof(*sa));\n    }\n    else\n    {\n      sa->sin.sin_port = htons(upcb->local_port);\n      SET_ADDR(sa, &upcb->local_ip);\n    }\n  }\n  else\n  {\n    struct tcp_pcb *tpcb = cs->pcb.tcp;\n    if (remote)\n    {\n      sa->sin.sin_port = htons(tpcb->remote_port);\n      SET_ADDR(sa, &tpcb->remote_ip);\n    }\n    else\n    {\n      sa->sin.sin_port = htons(tpcb->local_port);\n      SET_ADDR(sa, &tpcb->local_ip);\n    }\n  }\n}\n\nvoid mg_lwip_if_sock_set(struct mg_connection *nc, sock_t sock)\n{\n  nc->sock = sock;\n}\n\n/* clang-format off */\n#define MG_LWIP_IFACE_VTABLE                                          \\\n  {                                                                   \\\n    mg_lwip_if_init,                                                  \\\n    mg_lwip_if_free,                                                  \\\n    mg_lwip_if_add_conn,                                              \\\n    mg_lwip_if_remove_conn,                                           \\\n    mg_lwip_if_poll,                                                  \\\n    mg_lwip_if_listen_tcp,                                            \\\n    mg_lwip_if_listen_udp,                                            \\\n    mg_lwip_if_connect_tcp,                                           \\\n    mg_lwip_if_connect_udp,                                           \\\n    mg_lwip_if_tcp_send,                                              \\\n    mg_lwip_if_udp_send,                                              \\\n    mg_lwip_if_recved,                                                \\\n    mg_lwip_if_create_conn,                                           \\\n    mg_lwip_if_destroy_conn,                                          \\\n    mg_lwip_if_sock_set,                                              \\\n    mg_lwip_if_get_conn_addr,                                         \\\n  }\n/* clang-format on */\n\nstruct mg_iface_vtable mg_lwip_iface_vtable = MG_LWIP_IFACE_VTABLE;\n#if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL\nstruct mg_iface_vtable mg_default_iface_vtable = MG_LWIP_IFACE_VTABLE;\n#endif\n\n#endif /* MG_ENABLE_NET_IF_LWIP_LOW_LEVEL */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/lwip/mg_lwip_ev_mgr.c\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL\n\n#ifndef MG_SIG_QUEUE_LEN\n#define MG_SIG_QUEUE_LEN 16\n#endif\n\nstruct mg_ev_mgr_lwip_signal\n{\n  int sig;\n  struct mg_connection *nc;\n};\n\nstruct mg_ev_mgr_lwip_data\n{\n  struct mg_ev_mgr_lwip_signal sig_queue[MG_SIG_QUEUE_LEN];\n  int sig_queue_len;\n  int start_index;\n};\n\nvoid mg_lwip_post_signal(enum mg_sig_type sig, struct mg_connection *nc)\n{\n  struct mg_ev_mgr_lwip_data *md =\n      (struct mg_ev_mgr_lwip_data *)nc->iface->data;\n  if (md->sig_queue_len >= MG_SIG_QUEUE_LEN)\n    return;\n  int end_index = (md->start_index + md->sig_queue_len) % MG_SIG_QUEUE_LEN;\n  md->sig_queue[end_index].sig = sig;\n  md->sig_queue[end_index].nc = nc;\n  md->sig_queue_len++;\n}\n\nvoid mg_ev_mgr_lwip_process_signals(struct mg_mgr *mgr)\n{\n  struct mg_ev_mgr_lwip_data *md =\n      (struct mg_ev_mgr_lwip_data *)mgr->ifaces[MG_MAIN_IFACE]->data;\n  while (md->sig_queue_len > 0)\n  {\n    struct mg_connection *nc = md->sig_queue[md->start_index].nc;\n    struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)nc->sock;\n    switch (md->sig_queue[md->start_index].sig)\n    {\n    case MG_SIG_CONNECT_RESULT:\n    {\n#if MG_ENABLE_SSL\n      if (cs->err == 0 && (nc->flags & MG_F_SSL) &&\n          !(nc->flags & MG_F_SSL_HANDSHAKE_DONE))\n      {\n        mg_lwip_ssl_do_hs(nc);\n      }\n      else\n#endif\n      {\n        mg_if_connect_cb(nc, cs->err);\n      }\n      break;\n    }\n    case MG_SIG_CLOSE_CONN:\n    {\n      nc->flags |= MG_F_CLOSE_IMMEDIATELY;\n      mg_close_conn(nc);\n      break;\n    }\n    case MG_SIG_RECV:\n    {\n      mg_lwip_handle_recv(nc);\n      break;\n    }\n    case MG_SIG_SENT_CB:\n    {\n      if (cs->num_sent > 0)\n        mg_if_sent_cb(nc, cs->num_sent);\n      cs->num_sent = 0;\n      break;\n    }\n    case MG_SIG_TOMBSTONE:\n    {\n      break;\n    }\n    }\n    md->start_index = (md->start_index + 1) % MG_SIG_QUEUE_LEN;\n    md->sig_queue_len--;\n  }\n}\n\nvoid mg_lwip_if_init(struct mg_iface *iface)\n{\n  LOG(LL_INFO, (\"%p Mongoose init\"));\n  iface->data = MG_CALLOC(1, sizeof(struct mg_ev_mgr_lwip_data));\n}\n\nvoid mg_lwip_if_free(struct mg_iface *iface)\n{\n  MG_FREE(iface->data);\n  iface->data = NULL;\n}\n\nvoid mg_lwip_if_add_conn(struct mg_connection *nc)\n{\n  (void)nc;\n}\n\nvoid mg_lwip_if_remove_conn(struct mg_connection *nc)\n{\n  struct mg_ev_mgr_lwip_data *md =\n      (struct mg_ev_mgr_lwip_data *)nc->iface->data;\n  /* Walk the queue and null-out further signals for this conn. */\n  for (int i = 0; i < MG_SIG_QUEUE_LEN; i++)\n  {\n    if (md->sig_queue[i].nc == nc)\n    {\n      md->sig_queue[i].sig = MG_SIG_TOMBSTONE;\n    }\n  }\n}\n\ntime_t mg_lwip_if_poll(struct mg_iface *iface, int timeout_ms)\n{\n  struct mg_mgr *mgr = iface->mgr;\n  int n = 0;\n  double now = mg_time();\n  struct mg_connection *nc, *tmp;\n  double min_timer = 0;\n  int num_timers = 0;\n#if 0\n  DBG((\"begin poll @%u\", (unsigned int) (now * 1000)));\n#endif\n  mg_ev_mgr_lwip_process_signals(mgr);\n  for (nc = mgr->active_connections; nc != NULL; nc = tmp)\n  {\n    struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)nc->sock;\n    (void)cs;\n    tmp = nc->next;\n    n++;\n    if (nc->flags & MG_F_CLOSE_IMMEDIATELY)\n    {\n      mg_close_conn(nc);\n      continue;\n    }\n    mg_if_poll(nc, now);\n    mg_if_timer(nc, now);\n    if (nc->send_mbuf.len == 0 && (nc->flags & MG_F_SEND_AND_CLOSE) &&\n        !(nc->flags & MG_F_WANT_WRITE))\n    {\n      mg_close_conn(nc);\n      continue;\n    }\n#if MG_ENABLE_SSL\n    if ((nc->flags & MG_F_SSL) && cs != NULL && cs->pcb.tcp != NULL &&\n        cs->pcb.tcp->state == ESTABLISHED)\n    {\n      if (((nc->flags & MG_F_WANT_WRITE) ||\n           (nc->send_mbuf.len > 0) && (nc->flags & MG_F_SSL_HANDSHAKE_DONE)) &&\n          cs->pcb.tcp->snd_buf > 0)\n      {\n        /* Can write more. */\n        if (nc->flags & MG_F_SSL_HANDSHAKE_DONE)\n        {\n          if (!(nc->flags & MG_F_CONNECTING))\n            mg_lwip_ssl_send(nc);\n        }\n        else\n        {\n          mg_lwip_ssl_do_hs(nc);\n        }\n      }\n      if (cs->rx_chain != NULL || (nc->flags & MG_F_WANT_READ))\n      {\n        if (nc->flags & MG_F_SSL_HANDSHAKE_DONE)\n        {\n          if (!(nc->flags & MG_F_CONNECTING))\n            mg_lwip_ssl_recv(nc);\n        }\n        else\n        {\n          mg_lwip_ssl_do_hs(nc);\n        }\n      }\n    }\n    else\n#endif /* KR_VERSION */\n    {\n      if (!(nc->flags & (MG_F_CONNECTING | MG_F_UDP)))\n      {\n        if (nc->send_mbuf.len > 0)\n          mg_lwip_send_more(nc);\n      }\n    }\n    if (nc->ev_timer_time > 0)\n    {\n      if (num_timers == 0 || nc->ev_timer_time < min_timer)\n      {\n        min_timer = nc->ev_timer_time;\n      }\n      num_timers++;\n    }\n  }\n#if 0\n  DBG((\"end poll @%u, %d conns, %d timers (min %u), next in %d ms\",\n       (unsigned int) (now * 1000), n, num_timers,\n       (unsigned int) (min_timer * 1000), timeout_ms));\n#endif\n  (void)timeout_ms;\n  return now;\n}\n\nuint32_t mg_lwip_get_poll_delay_ms(struct mg_mgr *mgr)\n{\n  struct mg_connection *nc;\n  double now = mg_time();\n  double min_timer = 0;\n  int num_timers = 0;\n  mg_ev_mgr_lwip_process_signals(mgr);\n  for (nc = mg_next(mgr, NULL); nc != NULL; nc = mg_next(mgr, nc))\n  {\n    if (nc->ev_timer_time > 0)\n    {\n      if (num_timers == 0 || nc->ev_timer_time < min_timer)\n      {\n        min_timer = nc->ev_timer_time;\n      }\n      num_timers++;\n    }\n  }\n  uint32_t timeout_ms = ~0;\n  if (num_timers > 0)\n  {\n    double timer_timeout_ms = (min_timer - now) * 1000 + 1 /* rounding */;\n    if (timer_timeout_ms < timeout_ms)\n    {\n      timeout_ms = timer_timeout_ms;\n    }\n  }\n  return timeout_ms;\n}\n\n#endif /* MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/lwip/mg_lwip_ssl_if.c\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#if MG_ENABLE_SSL && MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL\n\n/* Amalgamated: #include \"common/cs_dbg.h\" */\n\n#include <lwip/pbuf.h>\n#include <lwip/tcp.h>\n\n#ifndef MG_LWIP_SSL_IO_SIZE\n#define MG_LWIP_SSL_IO_SIZE 1024\n#endif\n\n/*\n * Stop processing incoming SSL traffic when recv_mbuf.size is this big.\n * It'a a uick solution for SSL recv pushback.\n */\n#ifndef MG_LWIP_SSL_RECV_MBUF_LIMIT\n#define MG_LWIP_SSL_RECV_MBUF_LIMIT 3072\n#endif\n\n#ifndef MIN\n#define MIN(a, b) ((a) < (b) ? (a) : (b))\n#endif\n\nvoid mg_lwip_ssl_do_hs(struct mg_connection *nc)\n{\n  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)nc->sock;\n  int server_side = (nc->listener != NULL);\n  enum mg_ssl_if_result res;\n  if (nc->flags & MG_F_CLOSE_IMMEDIATELY)\n    return;\n  res = mg_ssl_if_handshake(nc);\n  DBG((\"%p %d %d %d\", nc, nc->flags, server_side, res));\n  if (res != MG_SSL_OK)\n  {\n    if (res == MG_SSL_WANT_WRITE)\n    {\n      nc->flags |= MG_F_WANT_WRITE;\n      cs->err = 0;\n    }\n    else if (res == MG_SSL_WANT_READ)\n    {\n      /*\n       * Nothing to do in particular, we are callback-driven.\n       * What we definitely do not need anymore is SSL reading (nothing left).\n       */\n      nc->flags &= ~MG_F_WANT_READ;\n      cs->err = 0;\n    }\n    else\n    {\n      cs->err = res;\n      if (server_side)\n      {\n        mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);\n      }\n      else\n      {\n        mg_lwip_post_signal(MG_SIG_CONNECT_RESULT, nc);\n      }\n    }\n  }\n  else\n  {\n    cs->err = 0;\n    nc->flags &= ~MG_F_WANT_WRITE;\n    /*\n     * Handshake is done. Schedule a read immediately to consume app data\n     * which may already be waiting.\n     */\n    nc->flags |= (MG_F_SSL_HANDSHAKE_DONE | MG_F_WANT_READ);\n    if (server_side)\n    {\n      mg_lwip_accept_conn(nc, cs->pcb.tcp);\n    }\n    else\n    {\n      mg_lwip_post_signal(MG_SIG_CONNECT_RESULT, nc);\n    }\n  }\n}\n\nvoid mg_lwip_ssl_send(struct mg_connection *nc)\n{\n  if (nc->sock == INVALID_SOCKET)\n  {\n    DBG((\"%p invalid socket\", nc));\n    return;\n  }\n  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)nc->sock;\n  /* It's ok if the buffer is empty. Return value of 0 may also be valid. */\n  int len = cs->last_ssl_write_size;\n  if (len == 0)\n  {\n    len = MIN(MG_LWIP_SSL_IO_SIZE, nc->send_mbuf.len);\n  }\n  int ret = mg_ssl_if_write(nc, nc->send_mbuf.buf, len);\n  DBG((\"%p SSL_write %u = %d, %d\", nc, len, ret));\n  if (ret > 0)\n  {\n    mbuf_remove(&nc->send_mbuf, ret);\n    mbuf_trim(&nc->send_mbuf);\n    cs->last_ssl_write_size = 0;\n  }\n  else if (ret < 0)\n  {\n    /* This is tricky. We must remember the exact data we were sending to retry\n     * exactly the same send next time. */\n    cs->last_ssl_write_size = len;\n  }\n  if (ret == len)\n  {\n    nc->flags &= ~MG_F_WANT_WRITE;\n  }\n  else if (ret == MG_SSL_WANT_WRITE)\n  {\n    nc->flags |= MG_F_WANT_WRITE;\n  }\n  else\n  {\n    mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);\n  }\n}\n\nvoid mg_lwip_ssl_recv(struct mg_connection *nc)\n{\n  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)nc->sock;\n  /* Don't deliver data before connect callback */\n  if (nc->flags & MG_F_CONNECTING)\n    return;\n  while (nc->recv_mbuf.len < MG_LWIP_SSL_RECV_MBUF_LIMIT)\n  {\n    char *buf = (char *)malloc(MG_LWIP_SSL_IO_SIZE);\n    if (buf == NULL)\n      return;\n    int ret = mg_ssl_if_read(nc, buf, MG_LWIP_SSL_IO_SIZE);\n    DBG((\"%p %p SSL_read %u = %d\", nc, cs->rx_chain, MG_LWIP_SSL_IO_SIZE, ret));\n    if (ret <= 0)\n    {\n      free(buf);\n      if (ret == MG_SSL_WANT_WRITE)\n      {\n        nc->flags |= MG_F_WANT_WRITE;\n        return;\n      }\n      else if (ret == MG_SSL_WANT_READ)\n      {\n        /*\n         * Nothing to do in particular, we are callback-driven.\n         * What we definitely do not need anymore is SSL reading (nothing left).\n         */\n        nc->flags &= ~MG_F_WANT_READ;\n        cs->err = 0;\n        return;\n      }\n      else\n      {\n        mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);\n        return;\n      }\n    }\n    else\n    {\n      mg_if_recv_tcp_cb(nc, buf, ret, 1 /* own */);\n    }\n  }\n}\n\n#ifdef KR_VERSION\n\nssize_t kr_send(int fd, const void *buf, size_t len)\n{\n  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)fd;\n  int ret = mg_lwip_tcp_write(cs->nc, buf, len);\n  DBG((\"%p mg_lwip_tcp_write %u = %d\", cs->nc, len, ret));\n  if (ret == 0)\n    ret = KR_IO_WOULDBLOCK;\n  return ret;\n}\n\nssize_t kr_recv(int fd, void *buf, size_t len)\n{\n  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)fd;\n  struct pbuf *seg = cs->rx_chain;\n  if (seg == NULL)\n  {\n    DBG((\"%u - nothing to read\", len));\n    return KR_IO_WOULDBLOCK;\n  }\n  size_t seg_len = (seg->len - cs->rx_offset);\n  DBG((\"%u %u %u %u\", len, cs->rx_chain->len, seg_len, cs->rx_chain->tot_len));\n  len = MIN(len, seg_len);\n  pbuf_copy_partial(seg, buf, len, cs->rx_offset);\n  cs->rx_offset += len;\n  tcp_recved(cs->pcb.tcp, len);\n  if (cs->rx_offset == cs->rx_chain->len)\n  {\n    cs->rx_chain = pbuf_dechain(cs->rx_chain);\n    pbuf_free(seg);\n    cs->rx_offset = 0;\n  }\n  return len;\n}\n\n#elif MG_SSL_IF == MG_SSL_IF_MBEDTLS\n\nint ssl_socket_send(void *ctx, const unsigned char *buf, size_t len)\n{\n  struct mg_connection *nc = (struct mg_connection *)ctx;\n  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)nc->sock;\n  int ret = mg_lwip_tcp_write(cs->nc, buf, len);\n  DBG((\"%p mg_lwip_tcp_write %u = %d\", cs->nc, len, ret));\n  if (ret == 0)\n    ret = MBEDTLS_ERR_SSL_WANT_WRITE;\n  return ret;\n}\n\nint ssl_socket_recv(void *ctx, unsigned char *buf, size_t len)\n{\n  struct mg_connection *nc = (struct mg_connection *)ctx;\n  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *)nc->sock;\n  struct pbuf *seg = cs->rx_chain;\n  if (seg == NULL)\n  {\n    DBG((\"%u - nothing to read\", len));\n    return MBEDTLS_ERR_SSL_WANT_READ;\n  }\n  size_t seg_len = (seg->len - cs->rx_offset);\n  DBG((\"%u %u %u %u\", len, cs->rx_chain->len, seg_len, cs->rx_chain->tot_len));\n  len = MIN(len, seg_len);\n  pbuf_copy_partial(seg, buf, len, cs->rx_offset);\n  cs->rx_offset += len;\n  /* TCP PCB may be NULL if connection has already been closed\n   * but we still have data to deliver to SSL. */\n  if (cs->pcb.tcp != NULL)\n    tcp_recved(cs->pcb.tcp, len);\n  if (cs->rx_offset == cs->rx_chain->len)\n  {\n    cs->rx_chain = pbuf_dechain(cs->rx_chain);\n    pbuf_free(seg);\n    cs->rx_offset = 0;\n  }\n  return len;\n}\n\n#endif\n\n#endif /* MG_ENABLE_SSL && MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/wince/wince_libc.c\"\n#endif\n/*\n * Copyright (c) 2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifdef WINCE\n\nconst char *strerror(int err)\n{\n  /*\n   * TODO(alashkin): there is no strerror on WinCE;\n   * look for similar wce_xxxx function\n   */\n  static char buf[10];\n  snprintf(buf, sizeof(buf), \"%d\", err);\n  return buf;\n}\n\nint open(const char *filename, int oflag, int pmode)\n{\n  /*\n   * TODO(alashkin): mg_open function is not used in mongoose\n   * but exists in documentation as utility function\n   * Shall we delete it at all or implement for WinCE as well?\n   */\n  DebugBreak();\n  return 0; /* for compiler */\n}\n\nint _wstati64(const wchar_t *path, cs_stat_t *st)\n{\n  DWORD fa = GetFileAttributesW(path);\n  if (fa == INVALID_FILE_ATTRIBUTES)\n  {\n    return -1;\n  }\n  memset(st, 0, sizeof(*st));\n  if ((fa & FILE_ATTRIBUTE_DIRECTORY) == 0)\n  {\n    HANDLE h;\n    FILETIME ftime;\n    st->st_mode |= _S_IFREG;\n    h = CreateFileW(path, GENERIC_READ, 0, NULL, OPEN_EXISTING,\n                    FILE_ATTRIBUTE_NORMAL, NULL);\n    if (h == INVALID_HANDLE_VALUE)\n    {\n      return -1;\n    }\n    st->st_size = GetFileSize(h, NULL);\n    GetFileTime(h, NULL, NULL, &ftime);\n    st->st_mtime = (uint32_t)((((uint64_t)ftime.dwLowDateTime +\n                                ((uint64_t)ftime.dwHighDateTime << 32)) /\n                               10000000.0) -\n                              11644473600);\n    CloseHandle(h);\n  }\n  else\n  {\n    st->st_mode |= _S_IFDIR;\n  }\n  return 0;\n}\n\n/* Windows CE doesn't have neither gmtime nor strftime */\nstatic void mg_gmt_time_string(char *buf, size_t buf_len, time_t *t)\n{\n  FILETIME ft;\n  SYSTEMTIME systime;\n  if (t != NULL)\n  {\n    uint64_t filetime = (*t + 11644473600) * 10000000;\n    ft.dwLowDateTime = filetime & 0xFFFFFFFF;\n    ft.dwHighDateTime = (filetime & 0xFFFFFFFF00000000) >> 32;\n    FileTimeToSystemTime(&ft, &systime);\n  }\n  else\n  {\n    GetSystemTime(&systime);\n  }\n  /* There is no PRIu16 in WinCE SDK */\n  snprintf(buf, buf_len, \"%d.%d.%d %d:%d:%d GMT\", (int)systime.wYear,\n           (int)systime.wMonth, (int)systime.wDay, (int)systime.wHour,\n           (int)systime.wMinute, (int)systime.wSecond);\n}\n\n#endif\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/pic32_harmony/pic32_harmony_net_if.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_COMMON_PLATFORMS_PIC32_HARMONY_NET_IF_H_\n#define CS_COMMON_PLATFORMS_PIC32_HARMONY_NET_IF_H_\n\n/* Amalgamated: #include \"mongoose/src/net_if.h\" */\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif /* __cplusplus */\n\n#ifndef MG_ENABLE_NET_IF_PIC32_HARMONY\n#define MG_ENABLE_NET_IF_PIC32_HARMONY MG_NET_IF == MG_NET_IF_PIC32_HARMONY\n#endif\n\n  extern struct mg_iface_vtable mg_pic32_harmony_iface_vtable;\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif /* CS_COMMON_PLATFORMS_PIC32_HARMONY_NET_IF_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/pic32_harmony/pic32_harmony_net_if.c\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#if MG_ENABLE_NET_IF_PIC32_HARMONY\n\nint mg_pic32_harmony_if_create_conn(struct mg_connection *nc)\n{\n  (void)nc;\n  return 1;\n}\n\nvoid mg_pic32_harmony_if_recved(struct mg_connection *nc, size_t len)\n{\n  (void)nc;\n  (void)len;\n}\n\nvoid mg_pic32_harmony_if_add_conn(struct mg_connection *nc)\n{\n  (void)nc;\n}\n\nvoid mg_pic32_harmony_if_init(struct mg_iface *iface)\n{\n  (void)iface;\n  (void)mg_get_errno(); /* Shutup compiler */\n}\n\nvoid mg_pic32_harmony_if_free(struct mg_iface *iface)\n{\n  (void)iface;\n}\n\nvoid mg_pic32_harmony_if_remove_conn(struct mg_connection *nc)\n{\n  (void)nc;\n}\n\nvoid mg_pic32_harmony_if_destroy_conn(struct mg_connection *nc)\n{\n  if (nc->sock == INVALID_SOCKET)\n    return;\n  /* For UDP, only close outgoing sockets or listeners. */\n  if (!(nc->flags & MG_F_UDP))\n  {\n    /* Close TCP */\n    TCPIP_TCP_Close((TCP_SOCKET)nc->sock);\n  }\n  else if (nc->listener == NULL)\n  {\n    /* Only close outgoing UDP or listeners. */\n    TCPIP_UDP_Close((UDP_SOCKET)nc->sock);\n  }\n\n  nc->sock = INVALID_SOCKET;\n}\n\nint mg_pic32_harmony_if_listen_udp(struct mg_connection *nc,\n                                   union socket_address *sa)\n{\n  nc->sock = TCPIP_UDP_ServerOpen(\n      sa->sin.sin_family == AF_INET ? IP_ADDRESS_TYPE_IPV4\n                                    : IP_ADDRESS_TYPE_IPV6,\n      ntohs(sa->sin.sin_port),\n      sa->sin.sin_addr.s_addr == 0 ? 0 : (IP_MULTI_ADDRESS *)&sa->sin);\n  if (nc->sock == INVALID_SOCKET)\n  {\n    return -1;\n  }\n  return 0;\n}\n\nvoid mg_pic32_harmony_if_udp_send(struct mg_connection *nc, const void *buf,\n                                  size_t len)\n{\n  mbuf_append(&nc->send_mbuf, buf, len);\n}\n\nvoid mg_pic32_harmony_if_tcp_send(struct mg_connection *nc, const void *buf,\n                                  size_t len)\n{\n  mbuf_append(&nc->send_mbuf, buf, len);\n}\n\nint mg_pic32_harmony_if_listen_tcp(struct mg_connection *nc,\n                                   union socket_address *sa)\n{\n  nc->sock = TCPIP_TCP_ServerOpen(\n      sa->sin.sin_family == AF_INET ? IP_ADDRESS_TYPE_IPV4\n                                    : IP_ADDRESS_TYPE_IPV6,\n      ntohs(sa->sin.sin_port),\n      sa->sin.sin_addr.s_addr == 0 ? 0 : (IP_MULTI_ADDRESS *)&sa->sin);\n  memcpy(&nc->sa, sa, sizeof(*sa));\n  if (nc->sock == INVALID_SOCKET)\n  {\n    return -1;\n  }\n  return 0;\n}\n\nstatic int mg_accept_conn(struct mg_connection *lc)\n{\n  struct mg_connection *nc;\n  TCP_SOCKET_INFO si;\n  union socket_address sa;\n\n  nc = mg_if_accept_new_conn(lc);\n\n  if (nc == NULL)\n  {\n    return 0;\n  }\n\n  nc->sock = lc->sock;\n  nc->flags &= ~MG_F_LISTENING;\n\n  if (!TCPIP_TCP_SocketInfoGet((TCP_SOCKET)nc->sock, &si))\n  {\n    return 0;\n  }\n\n  if (si.addressType == IP_ADDRESS_TYPE_IPV4)\n  {\n    sa.sin.sin_family = AF_INET;\n    sa.sin.sin_port = htons(si.remotePort);\n    sa.sin.sin_addr.s_addr = si.remoteIPaddress.v4Add.Val;\n  }\n  else\n  {\n    /* TODO(alashkin): do something with _potential_ IPv6 */\n    memset(&sa, 0, sizeof(sa));\n  }\n\n  mg_if_accept_tcp_cb(nc, (union socket_address *)&sa, sizeof(sa));\n\n  return mg_pic32_harmony_if_listen_tcp(lc, &lc->sa) >= 0;\n}\n\nchar *inet_ntoa(struct in_addr in)\n{\n  static char addr[17];\n  snprintf(addr, sizeof(addr), \"%d.%d.%d.%d\", (int)in.S_un.S_un_b.s_b1,\n           (int)in.S_un.S_un_b.s_b2, (int)in.S_un.S_un_b.s_b3,\n           (int)in.S_un.S_un_b.s_b4);\n  return addr;\n}\n\nstatic void mg_handle_send(struct mg_connection *nc)\n{\n  uint16_t bytes_written = 0;\n  if (nc->flags & MG_F_UDP)\n  {\n    if (!TCPIP_UDP_RemoteBind(\n            (UDP_SOCKET)nc->sock,\n            nc->sa.sin.sin_family == AF_INET ? IP_ADDRESS_TYPE_IPV4\n                                             : IP_ADDRESS_TYPE_IPV6,\n            ntohs(nc->sa.sin.sin_port), (IP_MULTI_ADDRESS *)&nc->sa.sin))\n    {\n      nc->flags |= MG_F_CLOSE_IMMEDIATELY;\n      return;\n    }\n    bytes_written = TCPIP_UDP_TxPutIsReady((UDP_SOCKET)nc->sock, 0);\n    if (bytes_written >= nc->send_mbuf.len)\n    {\n      if (TCPIP_UDP_ArrayPut((UDP_SOCKET)nc->sock,\n                             (uint8_t *)nc->send_mbuf.buf,\n                             nc->send_mbuf.len) != nc->send_mbuf.len)\n      {\n        nc->flags |= MG_F_CLOSE_IMMEDIATELY;\n        bytes_written = 0;\n      }\n    }\n  }\n  else\n  {\n    bytes_written = TCPIP_TCP_FifoTxFreeGet((TCP_SOCKET)nc->sock);\n    if (bytes_written != 0)\n    {\n      if (bytes_written > nc->send_mbuf.len)\n      {\n        bytes_written = nc->send_mbuf.len;\n      }\n      if (TCPIP_TCP_ArrayPut((TCP_SOCKET)nc->sock,\n                             (uint8_t *)nc->send_mbuf.buf,\n                             bytes_written) != bytes_written)\n      {\n        nc->flags |= MG_F_CLOSE_IMMEDIATELY;\n        bytes_written = 0;\n      }\n    }\n  }\n\n  if (bytes_written != 0)\n  {\n    mbuf_remove(&nc->send_mbuf, bytes_written);\n    mg_if_sent_cb(nc, bytes_written);\n  }\n}\n\nstatic void mg_handle_recv(struct mg_connection *nc)\n{\n  uint16_t bytes_read = 0;\n  uint8_t *buf = NULL;\n  if (nc->flags & MG_F_UDP)\n  {\n    bytes_read = TCPIP_UDP_GetIsReady((UDP_SOCKET)nc->sock);\n    if (bytes_read != 0 &&\n        (nc->recv_mbuf_limit == -1 ||\n         nc->recv_mbuf.len + bytes_read < nc->recv_mbuf_limit))\n    {\n      buf = (uint8_t *)MG_MALLOC(bytes_read);\n      if (TCPIP_UDP_ArrayGet((UDP_SOCKET)nc->sock, buf, bytes_read) !=\n          bytes_read)\n      {\n        nc->flags |= MG_F_CLOSE_IMMEDIATELY;\n        bytes_read = 0;\n        MG_FREE(buf);\n      }\n    }\n  }\n  else\n  {\n    bytes_read = TCPIP_TCP_GetIsReady((TCP_SOCKET)nc->sock);\n    if (bytes_read != 0)\n    {\n      if (nc->recv_mbuf_limit != -1 &&\n          nc->recv_mbuf_limit - nc->recv_mbuf.len > bytes_read)\n      {\n        bytes_read = nc->recv_mbuf_limit - nc->recv_mbuf.len;\n      }\n      buf = (uint8_t *)MG_MALLOC(bytes_read);\n      if (TCPIP_TCP_ArrayGet((TCP_SOCKET)nc->sock, buf, bytes_read) !=\n          bytes_read)\n      {\n        nc->flags |= MG_F_CLOSE_IMMEDIATELY;\n        MG_FREE(buf);\n        bytes_read = 0;\n      }\n    }\n  }\n\n  if (bytes_read != 0)\n  {\n    mg_if_recv_tcp_cb(nc, buf, bytes_read, 1 /* own */);\n  }\n}\n\ntime_t mg_pic32_harmony_if_poll(struct mg_iface *iface, int timeout_ms)\n{\n  struct mg_mgr *mgr = iface->mgr;\n  double now = mg_time();\n  struct mg_connection *nc, *tmp;\n\n  for (nc = mgr->active_connections; nc != NULL; nc = tmp)\n  {\n    tmp = nc->next;\n\n    if (nc->flags & MG_F_CONNECTING)\n    {\n      /* processing connections */\n      if (nc->flags & MG_F_UDP ||\n          TCPIP_TCP_IsConnected((TCP_SOCKET)nc->sock))\n      {\n        mg_if_connect_cb(nc, 0);\n      }\n    }\n    else if (nc->flags & MG_F_LISTENING)\n    {\n      if (TCPIP_TCP_IsConnected((TCP_SOCKET)nc->sock))\n      {\n        /* accept new connections */\n        mg_accept_conn(nc);\n      }\n    }\n    else\n    {\n      if (nc->send_mbuf.len != 0)\n      {\n        mg_handle_send(nc);\n      }\n\n      if (nc->recv_mbuf_limit == -1 ||\n          nc->recv_mbuf.len < nc->recv_mbuf_limit)\n      {\n        mg_handle_recv(nc);\n      }\n    }\n  }\n\n  for (nc = mgr->active_connections; nc != NULL; nc = tmp)\n  {\n    tmp = nc->next;\n    if ((nc->flags & MG_F_CLOSE_IMMEDIATELY) ||\n        (nc->send_mbuf.len == 0 && (nc->flags & MG_F_SEND_AND_CLOSE)))\n    {\n      mg_close_conn(nc);\n    }\n  }\n\n  return now;\n}\n\nvoid mg_pic32_harmony_if_sock_set(struct mg_connection *nc, sock_t sock)\n{\n  nc->sock = sock;\n}\n\nvoid mg_pic32_harmony_if_get_conn_addr(struct mg_connection *nc, int remote,\n                                       union socket_address *sa)\n{\n  /* TODO(alaskin): not implemented yet */\n}\n\nvoid mg_pic32_harmony_if_connect_tcp(struct mg_connection *nc,\n                                     const union socket_address *sa)\n{\n  nc->sock = TCPIP_TCP_ClientOpen(\n      sa->sin.sin_family == AF_INET ? IP_ADDRESS_TYPE_IPV4\n                                    : IP_ADDRESS_TYPE_IPV6,\n      ntohs(sa->sin.sin_port), (IP_MULTI_ADDRESS *)&sa->sin);\n  nc->err = (nc->sock == INVALID_SOCKET) ? -1 : 0;\n}\n\nvoid mg_pic32_harmony_if_connect_udp(struct mg_connection *nc)\n{\n  nc->sock = TCPIP_UDP_ClientOpen(IP_ADDRESS_TYPE_ANY, 0, NULL);\n  nc->err = (nc->sock == INVALID_SOCKET) ? -1 : 0;\n}\n\n/* clang-format off */\n#define MG_PIC32_HARMONY_IFACE_VTABLE                                   \\\n  {                                                                     \\\n    mg_pic32_harmony_if_init,                                           \\\n    mg_pic32_harmony_if_free,                                           \\\n    mg_pic32_harmony_if_add_conn,                                       \\\n    mg_pic32_harmony_if_remove_conn,                                    \\\n    mg_pic32_harmony_if_poll,                                           \\\n    mg_pic32_harmony_if_listen_tcp,                                     \\\n    mg_pic32_harmony_if_listen_udp,                                     \\\n    mg_pic32_harmony_if_connect_tcp,                                    \\\n    mg_pic32_harmony_if_connect_udp,                                    \\\n    mg_pic32_harmony_if_tcp_send,                                       \\\n    mg_pic32_harmony_if_udp_send,                                       \\\n    mg_pic32_harmony_if_recved,                                         \\\n    mg_pic32_harmony_if_create_conn,                                    \\\n    mg_pic32_harmony_if_destroy_conn,                                   \\\n    mg_pic32_harmony_if_sock_set,                                       \\\n    mg_pic32_harmony_if_get_conn_addr,                                  \\\n  }\n/* clang-format on */\n\nstruct mg_iface_vtable mg_pic32_harmony_iface_vtable =\n    MG_PIC32_HARMONY_IFACE_VTABLE;\n#if MG_NET_IF == MG_NET_IF_PIC32_HARMONY\nstruct mg_iface_vtable mg_default_iface_vtable = MG_PIC32_HARMONY_IFACE_VTABLE;\n#endif\n\n#endif /* MG_ENABLE_NET_IF_PIC32_HARMONY */\n"
  },
  {
    "path": "thirdparty/mongoose/mongoose.h",
    "content": "#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/common.h\"\n#endif\n/*\n * Copyright (c) 2004-2013 Sergey Lyubka\n * Copyright (c) 2013-2015 Cesanta Software Limited\n * All rights reserved\n *\n * This software is dual-licensed: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation. For the terms of this\n * license, see <http://www.gnu.org/licenses/>.\n *\n * You are free to use this software under the terms of the GNU General\n * Public License, but WITHOUT ANY WARRANTY; without even the implied\n * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n * See the GNU General Public License for more details.\n *\n * Alternatively, you can license this software under a commercial\n * license, as set out in <https://www.cesanta.com/license>.\n */\n\n#ifndef CS_MONGOOSE_SRC_COMMON_H_\n#define CS_MONGOOSE_SRC_COMMON_H_\n\n#define MG_VERSION \"6.6\"\n\n/* Local tweaks, applied before any of Mongoose's own headers. */\n#ifdef MG_LOCALS\n#include <mg_locals.h>\n#endif\n\n#endif /* CS_MONGOOSE_SRC_COMMON_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platform.h\"\n#endif\n#ifndef CS_COMMON_PLATFORM_H_\n#define CS_COMMON_PLATFORM_H_\n\n/*\n * For the \"custom\" platform, includes and dependencies can be\n * provided through mg_locals.h.\n */\n#define CS_P_CUSTOM 0\n#define CS_P_UNIX 1\n#define CS_P_WINDOWS 2\n#define CS_P_ESP8266 3\n#define CS_P_CC3200 4\n#define CS_P_MSP432 5\n#define CS_P_CC3100 6\n#define CS_P_TM4C129 14\n#define CS_P_MBED 7\n#define CS_P_WINCE 8\n#define CS_P_NXP_LPC 13\n#define CS_P_NXP_KINETIS 9\n#define CS_P_NRF51 12\n#define CS_P_NRF52 10\n#define CS_P_PIC32_HARMONY 11\n/* Next id: 15 */\n\n/* If not specified explicitly, we guess platform by defines. */\n#ifndef CS_PLATFORM\n\n#if defined(TARGET_IS_MSP432P4XX) || defined(__MSP432P401R__)\n#define CS_PLATFORM CS_P_MSP432\n#elif defined(cc3200)\n#define CS_PLATFORM CS_P_CC3200\n#elif defined(__unix__) || defined(__APPLE__)\n#define CS_PLATFORM CS_P_UNIX\n#elif defined(WINCE)\n#define CS_PLATFORM CS_P_WINCE\n#elif defined(_WIN32)\n#define CS_PLATFORM CS_P_WINDOWS\n#elif defined(__MBED__)\n#define CS_PLATFORM CS_P_MBED\n#elif defined(__USE_LPCOPEN)\n#define CS_PLATFORM CS_P_NXP_LPC\n#elif defined(FRDM_K64F) || defined(FREEDOM)\n#define CS_PLATFORM CS_P_NXP_KINETIS\n#elif defined(PIC32)\n#define CS_PLATFORM CS_P_PIC32_HARMONY\n#elif defined(ICACHE_FLASH)\n#define CS_PLATFORM CS_P_ESP8266\n#elif defined(TARGET_IS_TM4C129_RA0) || defined(TARGET_IS_TM4C129_RA1) || \\\n    defined(TARGET_IS_TM4C129_RA2)\n#define CS_PLATFORM CS_P_TM4C129\n#endif\n\n#ifndef CS_PLATFORM\n#error \"CS_PLATFORM is not specified and we couldn't guess it.\"\n#endif\n\n#endif /* !defined(CS_PLATFORM) */\n\n#define MG_NET_IF_SOCKET 1\n#define MG_NET_IF_SIMPLELINK 2\n#define MG_NET_IF_LWIP_LOW_LEVEL 3\n#define MG_NET_IF_PIC32_HARMONY 4\n\n#define MG_SSL_IF_OPENSSL 1\n#define MG_SSL_IF_MBEDTLS 2\n#define MG_SSL_IF_SIMPLELINK 3\n\n/* Amalgamated: #include \"common/platforms/platform_unix.h\" */\n/* Amalgamated: #include \"common/platforms/platform_windows.h\" */\n/* Amalgamated: #include \"common/platforms/platform_esp8266.h\" */\n/* Amalgamated: #include \"common/platforms/platform_cc3200.h\" */\n/* Amalgamated: #include \"common/platforms/platform_cc3100.h\" */\n/* Amalgamated: #include \"common/platforms/platform_mbed.h\" */\n/* Amalgamated: #include \"common/platforms/platform_nrf51.h\" */\n/* Amalgamated: #include \"common/platforms/platform_nrf52.h\" */\n/* Amalgamated: #include \"common/platforms/platform_wince.h\" */\n/* Amalgamated: #include \"common/platforms/platform_nxp_lpc.h\" */\n/* Amalgamated: #include \"common/platforms/platform_nxp_kinetis.h\" */\n/* Amalgamated: #include \"common/platforms/platform_pic32_harmony.h\" */\n\n/* Common stuff */\n\n#ifdef __GNUC__\n#define NORETURN __attribute__((noreturn))\n#define NOINLINE __attribute__((noinline))\n#define WARN_UNUSED_RESULT __attribute__((warn_unused_result))\n#define NOINSTR __attribute__((no_instrument_function))\n#else\n#define NORETURN\n#define NOINLINE\n#define WARN_UNUSED_RESULT\n#define NOINSTR\n#endif /* __GNUC__ */\n\n#ifndef ARRAY_SIZE\n#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))\n#endif\n\n#endif /* CS_COMMON_PLATFORM_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/platform_windows.h\"\n#endif\n#ifndef CS_COMMON_PLATFORMS_PLATFORM_WINDOWS_H_\n#define CS_COMMON_PLATFORMS_PLATFORM_WINDOWS_H_\n#if CS_PLATFORM == CS_P_WINDOWS\n\n/*\n * MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)\n * MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)\n * MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)\n * MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)\n * MSVC++ 9.0  _MSC_VER == 1500 (Visual Studio 2008)\n * MSVC++ 8.0  _MSC_VER == 1400 (Visual Studio 2005)\n * MSVC++ 7.1  _MSC_VER == 1310 (Visual Studio 2003)\n * MSVC++ 7.0  _MSC_VER == 1300\n * MSVC++ 6.0  _MSC_VER == 1200\n * MSVC++ 5.0  _MSC_VER == 1100\n */\n#ifdef _MSC_VER\n#pragma warning(disable : 4127) /* FD_SET() emits warning, disable it */\n#pragma warning(disable : 4204) /* missing c99 support */\n#endif\n\n#ifndef _WINSOCK_DEPRECATED_NO_WARNINGS\n#define _WINSOCK_DEPRECATED_NO_WARNINGS 1\n#endif\n\n#ifndef _CRT_SECURE_NO_WARNINGS\n#define _CRT_SECURE_NO_WARNINGS\n#endif\n\n#include <assert.h>\n#include <direct.h>\n#include <errno.h>\n#include <fcntl.h>\n#include <io.h>\n#include <limits.h>\n#include <signal.h>\n#include <stddef.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <sys/stat.h>\n#include <time.h>\n\n#ifdef _MSC_VER\n#pragma comment(lib, \"ws2_32.lib\") /* Linking with winsock library */\n#endif\n\n#include <winsock2.h>\n#include <ws2tcpip.h>\n#include <windows.h>\n#include <process.h>\n\n#if defined(_MSC_VER) && _MSC_VER >= 1800\n#define strdup _strdup\n#endif\n\n#ifndef EINPROGRESS\n#define EINPROGRESS WSAEINPROGRESS\n#endif\n#ifndef EWOULDBLOCK\n#define EWOULDBLOCK WSAEWOULDBLOCK\n#endif\n#ifndef __func__\n#define STRX(x) #x\n#define STR(x) STRX(x)\n#define __func__ __FILE__ \":\" STR(__LINE__)\n#endif\n#define snprintf _snprintf\n#define fileno _fileno\n#define vsnprintf _vsnprintf\n#define sleep(x) Sleep((x)*1000)\n#define to64(x) _atoi64(x)\n#if !defined(__MINGW32__) && !defined(__MINGW64__)\n#define popen(x, y) _popen((x), (y))\n#define pclose(x) _pclose(x)\n#endif\n#define rmdir _rmdir\n#if defined(_MSC_VER) && _MSC_VER >= 1400\n#define fseeko(x, y, z) _fseeki64((x), (y), (z))\n#else\n#define fseeko(x, y, z) fseek((x), (y), (z))\n#endif\n#if defined(_MSC_VER) && _MSC_VER <= 1200\ntypedef unsigned long uintptr_t;\ntypedef long intptr_t;\n#endif\ntypedef int socklen_t;\n#if _MSC_VER >= 1700\n#include <stdint.h>\n#else\ntypedef signed char int8_t;\ntypedef unsigned char uint8_t;\ntypedef int int32_t;\ntypedef unsigned int uint32_t;\ntypedef short int16_t;\ntypedef unsigned short uint16_t;\ntypedef __int64 int64_t;\ntypedef unsigned __int64 uint64_t;\n#endif\ntypedef SOCKET sock_t;\ntypedef uint32_t in_addr_t;\n#ifndef UINT16_MAX\n#define UINT16_MAX 65535\n#endif\n#ifndef UINT32_MAX\n#define UINT32_MAX 4294967295\n#endif\n#ifndef pid_t\n#define pid_t HANDLE\n#endif\n#define INT64_FMT \"I64d\"\n#define INT64_X_FMT \"I64x\"\n#define SIZE_T_FMT \"Iu\"\n#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)\ntypedef struct stat cs_stat_t;\n#else\ntypedef struct _stati64 cs_stat_t;\n#endif\n#ifndef S_ISDIR\n#define S_ISDIR(x) (((x)&_S_IFMT) == _S_IFDIR)\n#endif\n#ifndef S_ISREG\n#define S_ISREG(x) (((x)&_S_IFMT) == _S_IFREG)\n#endif\n#define DIRSEP '\\\\'\n\n#ifndef va_copy\n#ifdef __va_copy\n#define va_copy __va_copy\n#else\n#define va_copy(x, y) (x) = (y)\n#endif\n#endif\n\n#ifndef MG_MAX_HTTP_REQUEST_SIZE\n#define MG_MAX_HTTP_REQUEST_SIZE 8192\n#endif\n\n#ifndef MG_MAX_HTTP_SEND_MBUF\n#define MG_MAX_HTTP_SEND_MBUF 4096\n#endif\n\n#ifndef MG_MAX_HTTP_HEADERS\n#define MG_MAX_HTTP_HEADERS 40\n#endif\n\n#ifndef CS_ENABLE_STDIO\n#define CS_ENABLE_STDIO 1\n#endif\n\n#ifndef MG_ENABLE_BROADCAST\n#define MG_ENABLE_BROADCAST 1\n#endif\n\n#ifndef MG_ENABLE_DIRECTORY_LISTING\n#define MG_ENABLE_DIRECTORY_LISTING 1\n#endif\n\n#ifndef MG_ENABLE_FILESYSTEM\n#define MG_ENABLE_FILESYSTEM 1\n#endif\n\n#ifndef MG_ENABLE_HTTP_CGI\n#define MG_ENABLE_HTTP_CGI 1\n#endif\n\n#ifndef MG_NET_IF\n#define MG_NET_IF MG_NET_IF_SOCKET\n#endif\n\n#endif /* CS_PLATFORM == CS_P_WINDOWS */\n#endif /* CS_COMMON_PLATFORMS_PLATFORM_WINDOWS_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/platform_unix.h\"\n#endif\n#ifndef CS_COMMON_PLATFORMS_PLATFORM_UNIX_H_\n#define CS_COMMON_PLATFORMS_PLATFORM_UNIX_H_\n#if CS_PLATFORM == CS_P_UNIX\n\n#ifndef _XOPEN_SOURCE\n#define _XOPEN_SOURCE 600\n#endif\n\n/* <inttypes.h> wants this for C++ */\n#ifndef __STDC_FORMAT_MACROS\n#define __STDC_FORMAT_MACROS\n#endif\n\n/* C++ wants that for INT64_MAX */\n#ifndef __STDC_LIMIT_MACROS\n#define __STDC_LIMIT_MACROS\n#endif\n\n/* Enable fseeko() and ftello() functions */\n#ifndef _LARGEFILE_SOURCE\n#define _LARGEFILE_SOURCE\n#endif\n\n/* Enable 64-bit file offsets */\n#ifndef _FILE_OFFSET_BITS\n#define _FILE_OFFSET_BITS 64\n#endif\n\n#include <arpa/inet.h>\n#include <assert.h>\n#include <ctype.h>\n#include <dirent.h>\n#include <errno.h>\n#include <fcntl.h>\n#include <inttypes.h>\n#include <stdint.h>\n#include <limits.h>\n#include <math.h>\n#include <netdb.h>\n#include <netinet/in.h>\n#include <pthread.h>\n#include <signal.h>\n#include <stdarg.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <sys/param.h>\n#include <sys/socket.h>\n#include <sys/select.h>\n#include <sys/stat.h>\n#include <sys/time.h>\n#include <sys/types.h>\n#include <unistd.h>\n\n#ifdef __APPLE__\n#include <machine/endian.h>\n#ifndef BYTE_ORDER\n#define LITTLE_ENDIAN __DARWIN_LITTLE_ENDIAN\n#define BIG_ENDIAN __DARWIN_BIG_ENDIAN\n#define PDP_ENDIAN __DARWIN_PDP_ENDIAN\n#define BYTE_ORDER __DARWIN_BYTE_ORDER\n#endif\n#endif\n\n/*\n * osx correctly avoids defining strtoll when compiling in strict ansi mode.\n * c++ 11 standard defines strtoll as well.\n * We require strtoll, and if your embedded pre-c99 compiler lacks one, please\n * implement a shim.\n */\n#if !(defined(__cplusplus) && __cplusplus >= 201103L) && \\\n    !(defined(__DARWIN_C_LEVEL) && __DARWIN_C_LEVEL >= 200809L)\nlong long strtoll(const char *, char **, int);\n#endif\n\ntypedef int sock_t;\n#define INVALID_SOCKET (-1)\n#define SIZE_T_FMT \"zu\"\ntypedef struct stat cs_stat_t;\n#define DIRSEP '/'\n#define to64(x) strtoll(x, NULL, 10)\n#define INT64_FMT PRId64\n#define INT64_X_FMT PRIx64\n\n#ifndef __cdecl\n#define __cdecl\n#endif\n\n#ifndef va_copy\n#ifdef __va_copy\n#define va_copy __va_copy\n#else\n#define va_copy(x, y) (x) = (y)\n#endif\n#endif\n\n#define closesocket(x) close(x)\n\n#ifndef MG_MAX_HTTP_REQUEST_SIZE\n#define MG_MAX_HTTP_REQUEST_SIZE 8192\n#endif\n\n#ifndef MG_MAX_HTTP_SEND_MBUF\n#define MG_MAX_HTTP_SEND_MBUF 4096\n#endif\n\n#ifndef MG_MAX_HTTP_HEADERS\n#define MG_MAX_HTTP_HEADERS 40\n#endif\n\n#ifndef CS_ENABLE_STDIO\n#define CS_ENABLE_STDIO 1\n#endif\n\n#ifndef MG_ENABLE_BROADCAST\n#define MG_ENABLE_BROADCAST 1\n#endif\n\n#ifndef MG_ENABLE_DIRECTORY_LISTING\n#define MG_ENABLE_DIRECTORY_LISTING 1\n#endif\n\n#ifndef MG_ENABLE_FILESYSTEM\n#define MG_ENABLE_FILESYSTEM 1\n#endif\n\n#ifndef MG_ENABLE_HTTP_CGI\n#define MG_ENABLE_HTTP_CGI 1\n#endif\n\n#ifndef MG_NET_IF\n#define MG_NET_IF MG_NET_IF_SOCKET\n#endif\n\n#endif /* CS_PLATFORM == CS_P_UNIX */\n#endif /* CS_COMMON_PLATFORMS_PLATFORM_UNIX_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/platform_esp8266.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_COMMON_PLATFORMS_PLATFORM_ESP8266_H_\n#define CS_COMMON_PLATFORMS_PLATFORM_ESP8266_H_\n#if CS_PLATFORM == CS_P_ESP8266\n\n#include <assert.h>\n#include <ctype.h>\n#include <fcntl.h>\n#include <inttypes.h>\n#include <machine/endian.h>\n#include <string.h>\n#include <sys/stat.h>\n#include <sys/time.h>\n\n#define SIZE_T_FMT \"u\"\ntypedef struct stat cs_stat_t;\n#define DIRSEP '/'\n#define to64(x) strtoll(x, NULL, 10)\n#define INT64_FMT PRId64\n#define INT64_X_FMT PRIx64\n#define __cdecl\n#define _FILE_OFFSET_BITS 32\n#define fineno(x) -1\n\n#define MG_LWIP 1\n\n/* struct timeval is defined in sys/time.h. */\n#define LWIP_TIMEVAL_PRIVATE 0\n\n#ifndef MG_NET_IF\n#include <lwip/opt.h>\n#if LWIP_SOCKET /* RTOS SDK has LWIP sockets */\n#define MG_NET_IF MG_NET_IF_SOCKET\n#else\n#define MG_NET_IF MG_NET_IF_LWIP_LOW_LEVEL\n#endif\n#endif\n\n#ifndef CS_ENABLE_STDIO\n#define CS_ENABLE_STDIO 1\n#endif\n\n#endif /* CS_PLATFORM == CS_P_ESP8266 */\n#endif /* CS_COMMON_PLATFORMS_PLATFORM_ESP8266_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/platform_cc3100.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3100_H_\n#define CS_COMMON_PLATFORMS_PLATFORM_CC3100_H_\n#if CS_PLATFORM == CS_P_CC3100\n\n#include <assert.h>\n#include <ctype.h>\n#include <errno.h>\n#include <inttypes.h>\n#include <stdint.h>\n#include <string.h>\n#include <time.h>\n\n#define MG_NET_IF MG_NET_IF_SIMPLELINK\n#define MG_SSL_IF MG_SSL_IF_SIMPLELINK\n\n/*\n * CC3100 SDK and STM32 SDK include headers w/out path, just like\n * #include \"simplelink.h\". As result, we have to add all required directories\n * into Makefile IPATH and do the same thing (include w/out path)\n */\n\n#include <simplelink.h>\n#include <netapp.h>\n#undef timeval\n\ntypedef int sock_t;\n#define INVALID_SOCKET (-1)\n\n#define to64(x) strtoll(x, NULL, 10)\n#define INT64_FMT PRId64\n#define INT64_X_FMT PRIx64\n#define SIZE_T_FMT \"u\"\n\n#define SOMAXCONN 8\n\nconst char *inet_ntop(int af, const void *src, char *dst, socklen_t size);\nchar *inet_ntoa(struct in_addr in);\nint inet_pton(int af, const char *src, void *dst);\n\n#endif /* CS_PLATFORM == CS_P_CC3100 */\n#endif /* CS_COMMON_PLATFORMS_PLATFORM_CC3100_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/platform_cc3200.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_\n#define CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_\n#if CS_PLATFORM == CS_P_CC3200\n\n#include <assert.h>\n#include <ctype.h>\n#include <errno.h>\n#include <inttypes.h>\n#include <stdint.h>\n#include <string.h>\n#include <time.h>\n\n#ifndef __TI_COMPILER_VERSION__\n#include <fcntl.h>\n#include <sys/time.h>\n#endif\n\n#define MG_NET_IF MG_NET_IF_SIMPLELINK\n#define MG_SSL_IF MG_SSL_IF_SIMPLELINK\n\n/* Only SPIFFS supports directories, SLFS does not. */\n#if defined(CC3200_FS_SPIFFS) && !defined(MG_ENABLE_DIRECTORY_LISTING)\n#define MG_ENABLE_DIRECTORY_LISTING 1\n#endif\n\n/* Amalgamated: #include \"common/platforms/simplelink/cs_simplelink.h\" */\n\ntypedef int sock_t;\n#define INVALID_SOCKET (-1)\n#define SIZE_T_FMT \"u\"\ntypedef struct stat cs_stat_t;\n#define DIRSEP '/'\n#define to64(x) strtoll(x, NULL, 10)\n#define INT64_FMT PRId64\n#define INT64_X_FMT PRIx64\n#define __cdecl\n\n#define fileno(x) -1\n\n/* Some functions we implement for Mongoose. */\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n#ifdef __TI_COMPILER_VERSION__\n  struct SlTimeval_t;\n#define timeval SlTimeval_t\n  int gettimeofday(struct timeval *t, void *tz);\n\n  int asprintf(char **strp, const char *fmt, ...);\n\n#endif\n\n/* TI's libc does not have stat & friends, add them. */\n#ifdef __TI_COMPILER_VERSION__\n\n#include <file.h>\n\n  typedef unsigned int mode_t;\n  typedef size_t _off_t;\n  typedef long ssize_t;\n\n  struct stat\n  {\n    int st_ino;\n    mode_t st_mode;\n    int st_nlink;\n    time_t st_mtime;\n    off_t st_size;\n  };\n\n  int _stat(const char *pathname, struct stat *st);\n#define stat(a, b) _stat(a, b)\n\n#define __S_IFMT 0170000\n\n#define __S_IFDIR 0040000\n#define __S_IFCHR 0020000\n#define __S_IFREG 0100000\n\n#define __S_ISTYPE(mode, mask) (((mode)&__S_IFMT) == (mask))\n\n#define S_IFDIR __S_IFDIR\n#define S_IFCHR __S_IFCHR\n#define S_IFREG __S_IFREG\n#define S_ISDIR(mode) __S_ISTYPE((mode), __S_IFDIR)\n#define S_ISREG(mode) __S_ISTYPE((mode), __S_IFREG)\n\n/* As of 5.2.7, TI compiler does not support va_copy() yet. */\n#define va_copy(apc, ap) ((apc) = (ap))\n\n#endif /* __TI_COMPILER_VERSION__ */\n\n#ifdef CC3200_FS_SPIFFS\n#include <common/spiffs/spiffs.h>\n\n  typedef struct\n  {\n    spiffs_DIR dh;\n    struct spiffs_dirent de;\n  } DIR;\n\n#define d_name name\n#define dirent spiffs_dirent\n\n  DIR *opendir(const char *dir_name);\n  int closedir(DIR *dir);\n  struct dirent *readdir(DIR *dir);\n#endif /* CC3200_FS_SPIFFS */\n\n#ifdef CC3200_FS_SLFS\n#define MG_FS_SLFS\n#endif\n\n#if (defined(CC3200_FS_SPIFFS) || defined(CC3200_FS_SLFS)) && !defined(MG_ENABLE_FILESYSTEM)\n#define MG_ENABLE_FILESYSTEM 1\n#endif\n\n#ifndef CS_ENABLE_STDIO\n#define CS_ENABLE_STDIO 1\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* CS_PLATFORM == CS_P_CC3200 */\n#endif /* CS_COMMON_PLATFORMS_PLATFORM_CC3200_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/platform_msp432.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_COMMON_PLATFORMS_PLATFORM_MSP432_H_\n#define CS_COMMON_PLATFORMS_PLATFORM_MSP432_H_\n#if CS_PLATFORM == CS_P_MSP432\n\n#include <assert.h>\n#include <ctype.h>\n#include <errno.h>\n#include <inttypes.h>\n#include <stdint.h>\n#include <string.h>\n#include <time.h>\n\n#ifndef __TI_COMPILER_VERSION__\n#include <fcntl.h>\n#include <sys/time.h>\n#endif\n\n#define MG_NET_IF MG_NET_IF_SIMPLELINK\n#define MG_SSL_IF MG_SSL_IF_SIMPLELINK\n\n/* Amalgamated: #include \"common/platforms/simplelink/cs_simplelink.h\" */\n\ntypedef int sock_t;\n#define INVALID_SOCKET (-1)\n#define SIZE_T_FMT \"u\"\ntypedef struct stat cs_stat_t;\n#define DIRSEP '/'\n#define to64(x) strtoll(x, NULL, 10)\n#define INT64_FMT PRId64\n#define INT64_X_FMT PRIx64\n#define __cdecl\n\n#define fileno(x) -1\n\n/* Some functions we implement for Mongoose. */\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n#ifdef __TI_COMPILER_VERSION__\n  struct SlTimeval_t;\n#define timeval SlTimeval_t\n  int gettimeofday(struct timeval *t, void *tz);\n#endif\n\n/* TI's libc does not have stat & friends, add them. */\n#ifdef __TI_COMPILER_VERSION__\n\n#include <file.h>\n\n  typedef unsigned int mode_t;\n  typedef size_t _off_t;\n  typedef long ssize_t;\n\n  struct stat\n  {\n    int st_ino;\n    mode_t st_mode;\n    int st_nlink;\n    time_t st_mtime;\n    off_t st_size;\n  };\n\n  int _stat(const char *pathname, struct stat *st);\n#define stat(a, b) _stat(a, b)\n\n#define __S_IFMT 0170000\n\n#define __S_IFDIR 0040000\n#define __S_IFCHR 0020000\n#define __S_IFREG 0100000\n\n#define __S_ISTYPE(mode, mask) (((mode)&__S_IFMT) == (mask))\n\n#define S_IFDIR __S_IFDIR\n#define S_IFCHR __S_IFCHR\n#define S_IFREG __S_IFREG\n#define S_ISDIR(mode) __S_ISTYPE((mode), __S_IFDIR)\n#define S_ISREG(mode) __S_ISTYPE((mode), __S_IFREG)\n\n/* As of 5.2.7, TI compiler does not support va_copy() yet. */\n#define va_copy(apc, ap) ((apc) = (ap))\n\n#endif /* __TI_COMPILER_VERSION__ */\n\n#ifndef CS_ENABLE_STDIO\n#define CS_ENABLE_STDIO 1\n#endif\n\n#if (defined(CC3200_FS_SPIFFS) || defined(CC3200_FS_SLFS)) && !defined(MG_ENABLE_FILESYSTEM)\n#define MG_ENABLE_FILESYSTEM 1\n#endif\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* CS_PLATFORM == CS_P_MSP432 */\n#endif /* CS_COMMON_PLATFORMS_PLATFORM_MSP432_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/platform_tm4c129.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_COMMON_PLATFORMS_PLATFORM_TM4C129_H_\n#define CS_COMMON_PLATFORMS_PLATFORM_TM4C129_H_\n#if CS_PLATFORM == CS_P_TM4C129\n\n#include <assert.h>\n#include <ctype.h>\n#include <errno.h>\n#include <inttypes.h>\n#include <stdint.h>\n#include <string.h>\n#include <time.h>\n\n#ifndef __TI_COMPILER_VERSION__\n#include <fcntl.h>\n#include <sys/time.h>\n#endif\n\n#define SIZE_T_FMT \"u\"\ntypedef struct stat cs_stat_t;\n#define DIRSEP '/'\n#define to64(x) strtoll(x, NULL, 10)\n#define INT64_FMT PRId64\n#define INT64_X_FMT PRIx64\n#define __cdecl\n\n#ifndef MG_NET_IF\n#include <lwip/opt.h>\n#if LWIP_SOCKET\n#define MG_NET_IF MG_NET_IF_SOCKET\n#else\n#define MG_NET_IF MG_NET_IF_LWIP_LOW_LEVEL\n#endif\n#define MG_LWIP 1\n#elif MG_NET_IF == MG_NET_IF_SIMPLELINK\n#include \"common/platforms/simplelink/cs_simplelink.h\"\n#endif\n\n#ifndef CS_ENABLE_STDIO\n#define CS_ENABLE_STDIO 1\n#endif\n\n#ifdef __TI_COMPILER_VERSION__\n/* As of 5.2.8, TI compiler does not support va_copy() yet. */\n#define va_copy(apc, ap) ((apc) = (ap))\n#endif /* __TI_COMPILER_VERSION__ */\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* CS_PLATFORM == CS_P_TM4C129 */\n#endif /* CS_COMMON_PLATFORMS_PLATFORM_TM4C129_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/platform_mbed.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_COMMON_PLATFORMS_PLATFORM_MBED_H_\n#define CS_COMMON_PLATFORMS_PLATFORM_MBED_H_\n#if CS_PLATFORM == CS_P_MBED\n\n/* Amalgamated: #include \"mbed.h\" */\n\n#include <assert.h>\n#include <ctype.h>\n#include <errno.h>\n#include <inttypes.h>\n#include <stdint.h>\n#include <string.h>\n#include <time.h>\n\n#ifndef CS_ENABLE_STDIO\n#define CS_ENABLE_STDIO 1\n#endif\n\n/*\n * mbed can be compiled with the ARM compiler which\n * just doesn't come with a gettimeofday shim\n * because it's a BSD API and ARM targets embedded\n * non-unix platforms.\n */\n#if defined(__ARMCC_VERSION) || defined(__ICCARM__)\n#define _TIMEVAL_DEFINED\n#define gettimeofday _gettimeofday\n\n/* copied from GCC on ARM; for some reason useconds are signed */\ntypedef long suseconds_t; /* microseconds (signed) */\nstruct timeval\n{\n  time_t tv_sec;       /* seconds */\n  suseconds_t tv_usec; /* and microseconds */\n};\n\n#endif\n\n#if MG_NET_IF == MG_NET_IF_SIMPLELINK\n\n#define MG_SIMPLELINK_NO_OSI 1\n\n#include <simplelink.h>\n\ntypedef int sock_t;\n#define INVALID_SOCKET (-1)\n\n#define to64(x) strtoll(x, NULL, 10)\n#define INT64_FMT PRId64\n#define INT64_X_FMT PRIx64\n#define SIZE_T_FMT \"u\"\n\n#define SOMAXCONN 8\n\nconst char *inet_ntop(int af, const void *src, char *dst, socklen_t size);\nchar *inet_ntoa(struct in_addr in);\nint inet_pton(int af, const char *src, void *dst);\n\n#endif /* MG_NET_IF == MG_NET_IF_SIMPLELINK */\n\n#endif /* CS_PLATFORM == CS_P_MBED */\n#endif /* CS_COMMON_PLATFORMS_PLATFORM_MBED_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/platform_nrf51.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n#ifndef CS_COMMON_PLATFORMS_PLATFORM_NRF51_H_\n#define CS_COMMON_PLATFORMS_PLATFORM_NRF51_H_\n#if CS_PLATFORM == CS_P_NRF51\n\n#include <assert.h>\n#include <ctype.h>\n#include <inttypes.h>\n#include <stdint.h>\n#include <string.h>\n#include <time.h>\n\n#define to64(x) strtoll(x, NULL, 10)\n\n#define MG_NET_IF MG_NET_IF_LWIP_LOW_LEVEL\n#define MG_LWIP 1\n#define MG_ENABLE_IPV6 1\n\n/*\n * For ARM C Compiler, make lwip to export `struct timeval`; for other\n * compilers, suppress it.\n */\n#if !defined(__ARMCC_VERSION)\n#define LWIP_TIMEVAL_PRIVATE 0\n#else\nstruct timeval;\nint gettimeofday(struct timeval *tp, void *tzp);\n#endif\n\n#define INT64_FMT PRId64\n#define SIZE_T_FMT \"u\"\n\n/*\n * ARM C Compiler doesn't have strdup, so we provide it\n */\n#define CS_ENABLE_STRDUP defined(__ARMCC_VERSION)\n\n#endif /* CS_PLATFORM == CS_P_NRF51 */\n#endif /* CS_COMMON_PLATFORMS_PLATFORM_NRF51_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/platform_nrf52.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n#ifndef CS_COMMON_PLATFORMS_PLATFORM_NRF52_H_\n#define CS_COMMON_PLATFORMS_PLATFORM_NRF52_H_\n#if CS_PLATFORM == CS_P_NRF52\n\n#include <assert.h>\n#include <ctype.h>\n#include <errno.h>\n#include <inttypes.h>\n#include <stdint.h>\n#include <string.h>\n#include <time.h>\n\n#define to64(x) strtoll(x, NULL, 10)\n\n#define MG_NET_IF MG_NET_IF_LWIP_LOW_LEVEL\n#define MG_LWIP 1\n#define MG_ENABLE_IPV6 1\n\n#if !defined(ENOSPC)\n#define ENOSPC 28 /* No space left on device */\n#endif\n\n/*\n * For ARM C Compiler, make lwip to export `struct timeval`; for other\n * compilers, suppress it.\n */\n#if !defined(__ARMCC_VERSION)\n#define LWIP_TIMEVAL_PRIVATE 0\n#endif\n\n#define INT64_FMT PRId64\n#define SIZE_T_FMT \"u\"\n\n/*\n * ARM C Compiler doesn't have strdup, so we provide it\n */\n#define CS_ENABLE_STRDUP defined(__ARMCC_VERSION)\n\n#endif /* CS_PLATFORM == CS_P_NRF52 */\n#endif /* CS_COMMON_PLATFORMS_PLATFORM_NRF52_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/simplelink/cs_simplelink.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_\n#define CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_\n\n/* If simplelink.h is already included, all bets are off. */\n#if MG_NET_IF == MG_NET_IF_SIMPLELINK && !defined(__SIMPLELINK_H__)\n\n#include <stdbool.h>\n\n#ifndef __TI_COMPILER_VERSION__\n#undef __CONCAT\n#undef FD_CLR\n#undef FD_ISSET\n#undef FD_SET\n#undef FD_SETSIZE\n#undef FD_ZERO\n#undef fd_set\n#endif\n\n/* We want to disable SL_INC_STD_BSD_API_NAMING, so we include user.h ourselves\n * and undef it. */\n#define PROVISIONING_API_H_\n#include <simplelink/user.h>\n#undef PROVISIONING_API_H_\n#undef SL_INC_STD_BSD_API_NAMING\n\n#include <simplelink/include/simplelink.h>\n#include <simplelink/include/netapp.h>\n\n/* Now define only the subset of the BSD API that we use.\n * Notably, close(), read() and write() are not defined. */\n#define AF_INET SL_AF_INET\n\n#define socklen_t SlSocklen_t\n#define sockaddr SlSockAddr_t\n#define sockaddr_in SlSockAddrIn_t\n#define in_addr SlInAddr_t\n\n#define SOCK_STREAM SL_SOCK_STREAM\n#define SOCK_DGRAM SL_SOCK_DGRAM\n\n#define htonl sl_Htonl\n#define ntohl sl_Ntohl\n#define htons sl_Htons\n#define ntohs sl_Ntohs\n\n#ifndef EACCES\n#define EACCES SL_EACCES\n#endif\n#ifndef EAFNOSUPPORT\n#define EAFNOSUPPORT SL_EAFNOSUPPORT\n#endif\n#ifndef EAGAIN\n#define EAGAIN SL_EAGAIN\n#endif\n#ifndef EBADF\n#define EBADF SL_EBADF\n#endif\n#ifndef EINVAL\n#define EINVAL SL_EINVAL\n#endif\n#ifndef ENOMEM\n#define ENOMEM SL_ENOMEM\n#endif\n#ifndef EWOULDBLOCK\n#define EWOULDBLOCK SL_EWOULDBLOCK\n#endif\n\n#define SOMAXCONN 8\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n  const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);\n  char *inet_ntoa(struct in_addr in);\n  int inet_pton(int af, const char *src, void *dst);\n\n  struct mg_mgr;\n  struct mg_connection;\n\n  typedef void (*mg_init_cb)(struct mg_mgr *mgr);\n  bool mg_start_task(int priority, int stack_size, mg_init_cb mg_init);\n\n  void mg_run_in_task(void (*cb)(struct mg_mgr *mgr, void *arg), void *cb_arg);\n\n  int sl_fs_init(void);\n\n  void sl_restart_cb(struct mg_mgr *mgr);\n\n  int sl_set_ssl_opts(struct mg_connection *nc);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* MG_NET_IF == MG_NET_IF_SIMPLELINK && !defined(__SIMPLELINK_H__) */\n\n#endif /* CS_COMMON_PLATFORMS_SIMPLELINK_CS_SIMPLELINK_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/platform_wince.h\"\n#endif\n#ifndef CS_COMMON_PLATFORMS_PLATFORM_WINCE_H_\n#define CS_COMMON_PLATFORMS_PLATFORM_WINCE_H_\n\n#if CS_PLATFORM == CS_P_WINCE\n\n/*\n * MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)\n * MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)\n * MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)\n * MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)\n * MSVC++ 9.0  _MSC_VER == 1500 (Visual Studio 2008)\n * MSVC++ 8.0  _MSC_VER == 1400 (Visual Studio 2005)\n * MSVC++ 7.1  _MSC_VER == 1310 (Visual Studio 2003)\n * MSVC++ 7.0  _MSC_VER == 1300\n * MSVC++ 6.0  _MSC_VER == 1200\n * MSVC++ 5.0  _MSC_VER == 1100\n */\n#pragma warning(disable : 4127) /* FD_SET() emits warning, disable it */\n#pragma warning(disable : 4204) /* missing c99 support */\n\n#ifndef _WINSOCK_DEPRECATED_NO_WARNINGS\n#define _WINSOCK_DEPRECATED_NO_WARNINGS 1\n#endif\n\n#ifndef _CRT_SECURE_NO_WARNINGS\n#define _CRT_SECURE_NO_WARNINGS\n#endif\n\n#include <assert.h>\n#include <limits.h>\n#include <stddef.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <time.h>\n\n#pragma comment(lib, \"ws2.lib\") /* Linking with WinCE winsock library */\n\n#include <winsock2.h>\n#include <ws2tcpip.h>\n#include <windows.h>\n\n#define strdup _strdup\n\n#ifndef EINPROGRESS\n#define EINPROGRESS WSAEINPROGRESS\n#endif\n\n#ifndef EWOULDBLOCK\n#define EWOULDBLOCK WSAEWOULDBLOCK\n#endif\n\n#ifndef __func__\n#define STRX(x) #x\n#define STR(x) STRX(x)\n#define __func__ __FILE__ \":\" STR(__LINE__)\n#endif\n\n#define snprintf _snprintf\n#define fileno _fileno\n#define vsnprintf _vsnprintf\n#define sleep(x) Sleep((x)*1000)\n#define to64(x) _atoi64(x)\n#define rmdir _rmdir\n\n#if defined(_MSC_VER) && _MSC_VER >= 1400\n#define fseeko(x, y, z) _fseeki64((x), (y), (z))\n#else\n#define fseeko(x, y, z) fseek((x), (y), (z))\n#endif\n\ntypedef int socklen_t;\n\n#if _MSC_VER >= 1700\n#include <stdint.h>\n#else\ntypedef signed char int8_t;\ntypedef unsigned char uint8_t;\ntypedef int int32_t;\ntypedef unsigned int uint32_t;\ntypedef short int16_t;\ntypedef unsigned short uint16_t;\ntypedef __int64 int64_t;\ntypedef unsigned __int64 uint64_t;\n#endif\n\ntypedef SOCKET sock_t;\ntypedef uint32_t in_addr_t;\n\n#ifndef UINT16_MAX\n#define UINT16_MAX 65535\n#endif\n\n#ifndef UINT32_MAX\n#define UINT32_MAX 4294967295\n#endif\n\n#ifndef pid_t\n#define pid_t HANDLE\n#endif\n\n#define INT64_FMT \"I64d\"\n#define INT64_X_FMT \"I64x\"\n/* TODO(alashkin): check if this is correct */\n#define SIZE_T_FMT \"u\"\n\n#define DIRSEP '\\\\'\n\n#ifndef va_copy\n#ifdef __va_copy\n#define va_copy __va_copy\n#else\n#define va_copy(x, y) (x) = (y)\n#endif\n#endif\n\n#ifndef MG_MAX_HTTP_REQUEST_SIZE\n#define MG_MAX_HTTP_REQUEST_SIZE 8192\n#endif\n\n#ifndef MG_MAX_HTTP_SEND_MBUF\n#define MG_MAX_HTTP_SEND_MBUF 4096\n#endif\n\n#ifndef MG_MAX_HTTP_HEADERS\n#define MG_MAX_HTTP_HEADERS 40\n#endif\n\n#ifndef CS_ENABLE_STDIO\n#define CS_ENABLE_STDIO 1\n#endif\n\n#define abort() DebugBreak();\n\n#ifndef BUFSIZ\n#define BUFSIZ 4096\n#endif\n/*\n * Explicitly disabling MG_ENABLE_THREADS for WinCE\n * because they are enabled for _WIN32 by default\n */\n#ifndef MG_ENABLE_THREADS\n#define MG_ENABLE_THREADS 0\n#endif\n\n#ifndef MG_ENABLE_FILESYSTEM\n#define MG_ENABLE_FILESYSTEM 1\n#endif\n\n#ifndef MG_NET_IF\n#define MG_NET_IF MG_NET_IF_SOCKET\n#endif\n\ntypedef struct _stati64\n{\n  uint32_t st_mtime;\n  uint32_t st_size;\n  uint32_t st_mode;\n} cs_stat_t;\n\n/*\n * WinCE 6.0 has a lot of useful definitions in ATL (not windows.h) headers\n * use #ifdefs to avoid conflicts\n */\n\n#ifndef ENOENT\n#define ENOENT ERROR_PATH_NOT_FOUND\n#endif\n\n#ifndef EACCES\n#define EACCES ERROR_ACCESS_DENIED\n#endif\n\n#ifndef ENOMEM\n#define ENOMEM ERROR_NOT_ENOUGH_MEMORY\n#endif\n\n#ifndef _UINTPTR_T_DEFINED\ntypedef unsigned int *uintptr_t;\n#endif\n\n#define _S_IFREG 2\n#define _S_IFDIR 4\n\n#ifndef S_ISDIR\n#define S_ISDIR(x) (((x)&_S_IFDIR) != 0)\n#endif\n\n#ifndef S_ISREG\n#define S_ISREG(x) (((x)&_S_IFREG) != 0)\n#endif\n\nint open(const char *filename, int oflag, int pmode);\nint _wstati64(const wchar_t *path, cs_stat_t *st);\nconst char *strerror();\n\n#endif /* CS_PLATFORM == CS_P_WINCE */\n#endif /* CS_COMMON_PLATFORMS_PLATFORM_WINCE_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/platform_nxp_lpc.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_COMMON_PLATFORMS_PLATFORM_NXP_LPC_H_\n#define CS_COMMON_PLATFORMS_PLATFORM_NXP_LPC_H_\n\n#if CS_PLATFORM == CS_P_NXP_LPC\n\n#include <ctype.h>\n#include <stdint.h>\n#include <string.h>\n\n#define SIZE_T_FMT \"u\"\ntypedef struct stat cs_stat_t;\n#define INT64_FMT \"lld\"\n#define INT64_X_FMT \"llx\"\n#define __cdecl\n\n#define MG_LWIP 1\n\n#define MG_NET_IF MG_NET_IF_LWIP_LOW_LEVEL\n\n/*\n * LPCXpress comes with 3 C library implementations: Newlib, NewlibNano and Redlib.\n * See https://community.nxp.com/message/630860 for more details.\n *\n * Redlib is the default and lacks certain things, so we provide them.\n */\n#ifdef __REDLIB_INTERFACE_VERSION__\n\n/* Let LWIP define timeval for us. */\n#define LWIP_TIMEVAL_PRIVATE 1\n\n#define va_copy(d, s) __builtin_va_copy(d, s)\n\n#define CS_ENABLE_TO64 1\n#define to64(x) cs_to64(x)\n\n#define CS_ENABLE_STRDUP 1\n\n#else\n\n#include <sys/time.h>\n#define LWIP_TIMEVAL_PRIVATE 0\n#define to64(x) strtoll(x, NULL, 10)\n\n#endif\n\n#endif /* CS_PLATFORM == CS_P_NXP_LPC */\n#endif /* CS_COMMON_PLATFORMS_PLATFORM_NXP_LPC_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/platform_nxp_kinetis.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_COMMON_PLATFORMS_PLATFORM_NXP_KINETIS_H_\n#define CS_COMMON_PLATFORMS_PLATFORM_NXP_KINETIS_H_\n\n#if CS_PLATFORM == CS_P_NXP_KINETIS\n\n#include <ctype.h>\n#include <inttypes.h>\n#include <string.h>\n#include <sys/time.h>\n\n#define SIZE_T_FMT \"u\"\ntypedef struct stat cs_stat_t;\n#define to64(x) strtoll(x, NULL, 10)\n#define INT64_FMT \"lld\"\n#define INT64_X_FMT \"llx\"\n#define __cdecl\n\n#define MG_LWIP 1\n\n#define MG_NET_IF MG_NET_IF_LWIP_LOW_LEVEL\n\n/* struct timeval is defined in sys/time.h. */\n#define LWIP_TIMEVAL_PRIVATE 0\n\n#endif /* CS_PLATFORM == CS_P_NXP_KINETIS */\n#endif /* CS_COMMON_PLATFORMS_PLATFORM_NXP_KINETIS_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/platform_pic32_harmony.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_COMMON_PLATFORMS_PLATFORM_PIC32_HARMONY_H_\n#define CS_COMMON_PLATFORMS_PLATFORM_PIC32_HARMONY_H_\n\n#if CS_PLATFORM == CS_P_PIC32_HARMONY\n\n#define MG_NET_IF MG_NET_IF_PIC32_HARMONY\n\n#include <stdint.h>\n#include <time.h>\n#include <ctype.h>\n#include <stdlib.h>\n\n#include <system_config.h>\n#include <system_definitions.h>\n\ntypedef TCP_SOCKET sock_t;\n#define to64(x) strtoll(x, NULL, 10)\n\n#define SIZE_T_FMT \"lu\"\n#define INT64_FMT \"lld\"\n\nchar *inet_ntoa(struct in_addr in);\n\n#endif /* CS_PLATFORM == CS_P_PIC32_HARMONY */\n\n#endif /* CS_COMMON_PLATFORMS_PLATFORM_PIC32_HARMONY_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/platforms/lwip/mg_lwip.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_COMMON_PLATFORMS_LWIP_MG_LWIP_H_\n#define CS_COMMON_PLATFORMS_LWIP_MG_LWIP_H_\n\n#ifndef MG_LWIP\n#define MG_LWIP 0\n#endif\n\n#if MG_LWIP\n\n/*\n * When compiling for nRF5x chips with arm-none-eabi-gcc, it has BYTE_ORDER\n * already defined, so in order to avoid warnings in lwip, we have to undefine\n * it.\n *\n * TODO: Check if in the future versions of nRF5 SDK that changes.\n *       Current version of nRF51 SDK: 0.8.0\n *                          nRF5 SDK:  0.9.0\n */\n#if CS_PLATFORM == CS_P_NRF51 || CS_PLATFORM == CS_P_NRF52\n#undef BYTE_ORDER\n#endif\n\n#include <lwip/opt.h>\n#include <lwip/err.h>\n#include <lwip/ip_addr.h>\n#include <lwip/inet.h>\n#include <lwip/netdb.h>\n#include <lwip/dns.h>\n\n#ifndef LWIP_PROVIDE_ERRNO\n#include <errno.h>\n#endif\n\n#if LWIP_SOCKET\n#include <lwip/sockets.h>\n#else\n/* We really need the definitions from sockets.h. */\n#undef LWIP_SOCKET\n#define LWIP_SOCKET 1\n#include <lwip/sockets.h>\n#undef LWIP_SOCKET\n#define LWIP_SOCKET 0\n#endif\n\n#define INVALID_SOCKET (-1)\n#define SOMAXCONN 10\ntypedef int sock_t;\n\n#if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL\nstruct mg_mgr;\nstruct mg_connection;\nuint32_t mg_lwip_get_poll_delay_ms(struct mg_mgr *mgr);\nvoid mg_lwip_set_keepalive_params(struct mg_connection *nc, int idle,\n                                  int interval, int count);\n#endif\n\n#endif /* MG_LWIP */\n\n#endif /* CS_COMMON_PLATFORMS_LWIP_MG_LWIP_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/cs_time.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_COMMON_CS_TIME_H_\n#define CS_COMMON_CS_TIME_H_\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif /* __cplusplus */\n\n  /* Sub-second granularity time(). */\n  double cs_time(void);\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif /* CS_COMMON_CS_TIME_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/mg_str.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_COMMON_MG_STR_H_\n#define CS_COMMON_MG_STR_H_\n\n#include <stddef.h>\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif /* __cplusplus */\n\n  /* Describes chunk of memory */\n  struct mg_str\n  {\n    const char *p; /* Memory chunk pointer */\n    size_t len;    /* Memory chunk length */\n  };\n\n  /*\n * Helper functions for creating mg_str struct from plain C string.\n * `NULL` is allowed and becomes `{NULL, 0}`.\n */\n  struct mg_str mg_mk_str(const char *s);\n  struct mg_str mg_mk_str_n(const char *s, size_t len);\n\n/* Macro for initializing mg_str. */\n#define MG_MK_STR(str_literal)           \\\n  {                                      \\\n    str_literal, sizeof(str_literal) - 1 \\\n  }\n\n  /*\n * Cross-platform version of `strcmp()` where where first string is\n * specified by `struct mg_str`.\n */\n  int mg_vcmp(const struct mg_str *str2, const char *str1);\n\n  /*\n * Cross-platform version of `strncasecmp()` where first string is\n * specified by `struct mg_str`.\n */\n  int mg_vcasecmp(const struct mg_str *str2, const char *str1);\n\n  struct mg_str mg_strdup(const struct mg_str s);\n  int mg_strcmp(const struct mg_str str1, const struct mg_str str2);\n  int mg_strncmp(const struct mg_str str1, const struct mg_str str2, size_t n);\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif /* CS_COMMON_MG_STR_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/mbuf.h\"\n#endif\n/*\n * Copyright (c) 2015 Cesanta Software Limited\n * All rights reserved\n */\n\n/*\n * === Memory Buffers\n *\n * Mbufs are mutable/growing memory buffers, like C++ strings.\n * Mbuf can append data to the end of a buffer or insert data into arbitrary\n * position in the middle of a buffer. The buffer grows automatically when\n * needed.\n */\n\n#ifndef CS_COMMON_MBUF_H_\n#define CS_COMMON_MBUF_H_\n\n#if defined(__cplusplus)\nextern \"C\"\n{\n#endif\n\n#include <stdlib.h>\n\n#ifndef MBUF_SIZE_MULTIPLIER\n#define MBUF_SIZE_MULTIPLIER 1.5\n#endif\n\n  /* Memory buffer descriptor */\n  struct mbuf\n  {\n    char *buf;   /* Buffer pointer */\n    size_t len;  /* Data length. Data is located between offset 0 and len. */\n    size_t size; /* Buffer size allocated by realloc(1). Must be >= len */\n  };\n\n  /*\n * Initialises an Mbuf.\n * `initial_capacity` specifies the initial capacity of the mbuf.\n */\n  void mbuf_init(struct mbuf *, size_t initial_capacity);\n\n  /* Frees the space allocated for the mbuffer and resets the mbuf structure. */\n  void mbuf_free(struct mbuf *);\n\n  /*\n * Appends data to the Mbuf.\n *\n * Returns the number of bytes appended or 0 if out of memory.\n */\n  size_t mbuf_append(struct mbuf *, const void *data, size_t data_size);\n\n  /*\n * Inserts data at a specified offset in the Mbuf.\n *\n * Existing data will be shifted forwards and the buffer will\n * be grown if necessary.\n * Returns the number of bytes inserted.\n */\n  size_t mbuf_insert(struct mbuf *, size_t, const void *, size_t);\n\n  /* Removes `data_size` bytes from the beginning of the buffer. */\n  void mbuf_remove(struct mbuf *, size_t data_size);\n\n  /*\n * Resizes an Mbuf.\n *\n * If `new_size` is smaller than buffer's `len`, the\n * resize is not performed.\n */\n  void mbuf_resize(struct mbuf *, size_t new_size);\n\n  /* Shrinks an Mbuf by resizing its `size` to `len`. */\n  void mbuf_trim(struct mbuf *);\n\n#if defined(__cplusplus)\n}\n#endif /* __cplusplus */\n\n#endif /* CS_COMMON_MBUF_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/sha1.h\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_COMMON_SHA1_H_\n#define CS_COMMON_SHA1_H_\n\n#ifndef DISABLE_SHA1\n#define DISABLE_SHA1 0\n#endif\n\n#if !DISABLE_SHA1\n\n/* Amalgamated: #include \"common/platform.h\" */\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif /* __cplusplus */\n\n  typedef struct\n  {\n    uint32_t state[5];\n    uint32_t count[2];\n    unsigned char buffer[64];\n  } cs_sha1_ctx;\n\n  void cs_sha1_init(cs_sha1_ctx *);\n  void cs_sha1_update(cs_sha1_ctx *, const unsigned char *data, uint32_t len);\n  void cs_sha1_final(unsigned char digest[20], cs_sha1_ctx *);\n  void cs_hmac_sha1(const unsigned char *key, size_t key_len,\n                    const unsigned char *text, size_t text_len,\n                    unsigned char out[20]);\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif /* DISABLE_SHA1 */\n\n#endif /* CS_COMMON_SHA1_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/md5.h\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_COMMON_MD5_H_\n#define CS_COMMON_MD5_H_\n\n/* Amalgamated: #include \"common/platform.h\" */\n\n#ifndef DISABLE_MD5\n#define DISABLE_MD5 0\n#endif\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif /* __cplusplus */\n\n  typedef struct MD5Context\n  {\n    uint32_t buf[4];\n    uint32_t bits[2];\n    unsigned char in[64];\n  } MD5_CTX;\n\n  void MD5_Init(MD5_CTX *c);\n  void MD5_Update(MD5_CTX *c, const unsigned char *data, size_t len);\n  void MD5_Final(unsigned char *md, MD5_CTX *c);\n\n  /*\n * Return stringified MD5 hash for NULL terminated list of pointer/length pairs.\n * A length should be specified as size_t variable.\n * Example:\n *\n *    char buf[33];\n *    cs_md5(buf, \"foo\", (size_t) 3, \"bar\", (size_t) 3, NULL);\n */\n  char *cs_md5(char buf[33], ...);\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif /* CS_COMMON_MD5_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/base64.h\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_COMMON_BASE64_H_\n#define CS_COMMON_BASE64_H_\n\n#ifndef DISABLE_BASE64\n#define DISABLE_BASE64 0\n#endif\n\n#if !DISABLE_BASE64\n\n#include <stdio.h>\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n  typedef void (*cs_base64_putc_t)(char, void *);\n\n  struct cs_base64_ctx\n  {\n    /* cannot call it putc because it's a macro on some environments */\n    cs_base64_putc_t b64_putc;\n    unsigned char chunk[3];\n    int chunk_size;\n    void *user_data;\n  };\n\n  void cs_base64_init(struct cs_base64_ctx *ctx, cs_base64_putc_t putc,\n                      void *user_data);\n  void cs_base64_update(struct cs_base64_ctx *ctx, const char *str, size_t len);\n  void cs_base64_finish(struct cs_base64_ctx *ctx);\n\n  void cs_base64_encode(const unsigned char *src, int src_len, char *dst);\n  void cs_fprint_base64(FILE *f, const unsigned char *src, int src_len);\n  int cs_base64_decode(const unsigned char *s, int len, char *dst);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* DISABLE_BASE64 */\n\n#endif /* CS_COMMON_BASE64_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/str_util.h\"\n#endif\n/*\n * Copyright (c) 2015 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_COMMON_STR_UTIL_H_\n#define CS_COMMON_STR_UTIL_H_\n\n#include <stdarg.h>\n#include <stdlib.h>\n\n#ifndef CS_ENABLE_STRDUP\n#define CS_ENABLE_STRDUP 0\n#endif\n\n#ifndef CS_ENABLE_TO64\n#define CS_ENABLE_TO64 0\n#endif\n\n#ifdef __cplusplus\nextern \"C\"\n{\n#endif\n\n  size_t c_strnlen(const char *s, size_t maxlen);\n  int c_snprintf(char *buf, size_t buf_size, const char *format, ...);\n  int c_vsnprintf(char *buf, size_t buf_size, const char *format, va_list ap);\n  /*\n * Find the first occurrence of find in s, where the search is limited to the\n * first slen characters of s.\n */\n  const char *c_strnstr(const char *s, const char *find, size_t slen);\n\n  /*\n * Stringify binary data. Output buffer size must be 2 * size_of_input + 1\n * because each byte of input takes 2 bytes in string representation\n * plus 1 byte for the terminating \\0 character.\n */\n  void cs_to_hex(char *to, const unsigned char *p, size_t len);\n\n  /*\n * Convert stringified binary data back to binary.\n * Does the reverse of `cs_to_hex()`.\n */\n  void cs_from_hex(char *to, const char *p, size_t len);\n\n#if CS_ENABLE_STRDUP\n  char *strdup(const char *src);\n#endif\n\n#if CS_ENABLE_TO64\n#include <stdint.h>\n  /*\n * Simple string -> int64 conversion routine.\n */\n  int64_t cs_to64(const char *s);\n#endif\n\n  /*\n * Cross-platform version of `strncasecmp()`.\n */\n  int mg_ncasecmp(const char *s1, const char *s2, size_t len);\n\n  /*\n * Cross-platform version of `strcasecmp()`.\n */\n  int mg_casecmp(const char *s1, const char *s2);\n\n  /*\n * Prints message to the buffer. If the buffer is large enough to hold the\n * message, it returns buffer. If buffer is to small, it allocates a large\n * enough buffer on heap and returns allocated buffer.\n * This is a supposed use case:\n *\n *    char buf[5], *p = buf;\n *    mg_avprintf(&p, sizeof(buf), \"%s\", \"hi there\");\n *    use_p_somehow(p);\n *    if (p != buf) {\n *      free(p);\n *    }\n *\n * The purpose of this is to avoid malloc-ing if generated strings are small.\n */\n  int mg_asprintf(char **buf, size_t size, const char *fmt, ...);\n\n  /* Same as mg_asprintf, but takes varargs list. */\n  int mg_avprintf(char **buf, size_t size, const char *fmt, va_list ap);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* CS_COMMON_STR_UTIL_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"common/queue.h\"\n#endif\n/* clang-format off */\n/*-\n * Copyright (c) 1991, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 4. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)queue.h\t8.5 (Berkeley) 8/20/94\n * $FreeBSD$\n */\n\n#ifndef _SYS_QUEUE_H_\n#define\t_SYS_QUEUE_H_\n\n/*\n * This file defines four types of data structures: singly-linked lists,\n * singly-linked tail queues, lists and tail queues.\n *\n * A singly-linked list is headed by a single forward pointer. The elements\n * are singly linked for minimum space and pointer manipulation overhead at\n * the expense of O(n) removal for arbitrary elements. New elements can be\n * added to the list after an existing element or at the head of the list.\n * Elements being removed from the head of the list should use the explicit\n * macro for this purpose for optimum efficiency. A singly-linked list may\n * only be traversed in the forward direction.  Singly-linked lists are ideal\n * for applications with large datasets and few or no removals or for\n * implementing a LIFO queue.\n *\n * A singly-linked tail queue is headed by a pair of pointers, one to the\n * head of the list and the other to the tail of the list. The elements are\n * singly linked for minimum space and pointer manipulation overhead at the\n * expense of O(n) removal for arbitrary elements. New elements can be added\n * to the list after an existing element, at the head of the list, or at the\n * end of the list. Elements being removed from the head of the tail queue\n * should use the explicit macro for this purpose for optimum efficiency.\n * A singly-linked tail queue may only be traversed in the forward direction.\n * Singly-linked tail queues are ideal for applications with large datasets\n * and few or no removals or for implementing a FIFO queue.\n *\n * A list is headed by a single forward pointer (or an array of forward\n * pointers for a hash table header). The elements are doubly linked\n * so that an arbitrary element can be removed without a need to\n * traverse the list. New elements can be added to the list before\n * or after an existing element or at the head of the list. A list\n * may be traversed in either direction.\n *\n * A tail queue is headed by a pair of pointers, one to the head of the\n * list and the other to the tail of the list. The elements are doubly\n * linked so that an arbitrary element can be removed without a need to\n * traverse the list. New elements can be added to the list before or\n * after an existing element, at the head of the list, or at the end of\n * the list. A tail queue may be traversed in either direction.\n *\n * For details on the use of these macros, see the queue(3) manual page.\n *\n *\n *\t\t\t\tSLIST\tLIST\tSTAILQ\tTAILQ\n * _HEAD\t\t\t+\t+\t+\t+\n * _CLASS_HEAD\t\t\t+\t+\t+\t+\n * _HEAD_INITIALIZER\t\t+\t+\t+\t+\n * _ENTRY\t\t\t+\t+\t+\t+\n * _CLASS_ENTRY\t\t\t+\t+\t+\t+\n * _INIT\t\t\t+\t+\t+\t+\n * _EMPTY\t\t\t+\t+\t+\t+\n * _FIRST\t\t\t+\t+\t+\t+\n * _NEXT\t\t\t+\t+\t+\t+\n * _PREV\t\t\t-\t+\t-\t+\n * _LAST\t\t\t-\t-\t+\t+\n * _FOREACH\t\t\t+\t+\t+\t+\n * _FOREACH_FROM\t\t+\t+\t+\t+\n * _FOREACH_SAFE\t\t+\t+\t+\t+\n * _FOREACH_FROM_SAFE\t\t+\t+\t+\t+\n * _FOREACH_REVERSE\t\t-\t-\t-\t+\n * _FOREACH_REVERSE_FROM\t-\t-\t-\t+\n * _FOREACH_REVERSE_SAFE\t-\t-\t-\t+\n * _FOREACH_REVERSE_FROM_SAFE\t-\t-\t-\t+\n * _INSERT_HEAD\t\t\t+\t+\t+\t+\n * _INSERT_BEFORE\t\t-\t+\t-\t+\n * _INSERT_AFTER\t\t+\t+\t+\t+\n * _INSERT_TAIL\t\t\t-\t-\t+\t+\n * _CONCAT\t\t\t-\t-\t+\t+\n * _REMOVE_AFTER\t\t+\t-\t+\t-\n * _REMOVE_HEAD\t\t\t+\t-\t+\t-\n * _REMOVE\t\t\t+\t+\t+\t+\n * _SWAP\t\t\t+\t+\t+\t+\n *\n */\n#ifdef QUEUE_MACRO_DEBUG\n/* Store the last 2 places the queue element or head was altered */\nstruct qm_trace {\n\tunsigned long\t lastline;\n\tunsigned long\t prevline;\n\tconst char\t*lastfile;\n\tconst char\t*prevfile;\n};\n\n#define\tTRACEBUF\tstruct qm_trace trace;\n#define\tTRACEBUF_INITIALIZER\t{ __LINE__, 0, __FILE__, NULL } ,\n#define\tTRASHIT(x)\tdo {(x) = (void *)-1;} while (0)\n#define\tQMD_SAVELINK(name, link)\tvoid **name = (void *)&(link)\n\n#define\tQMD_TRACE_HEAD(head) do {\t\t\t\t\t\\\n\t(head)->trace.prevline = (head)->trace.lastline;\t\t\\\n\t(head)->trace.prevfile = (head)->trace.lastfile;\t\t\\\n\t(head)->trace.lastline = __LINE__;\t\t\t\t\\\n\t(head)->trace.lastfile = __FILE__;\t\t\t\t\\\n} while (0)\n\n#define\tQMD_TRACE_ELEM(elem) do {\t\t\t\t\t\\\n\t(elem)->trace.prevline = (elem)->trace.lastline;\t\t\\\n\t(elem)->trace.prevfile = (elem)->trace.lastfile;\t\t\\\n\t(elem)->trace.lastline = __LINE__;\t\t\t\t\\\n\t(elem)->trace.lastfile = __FILE__;\t\t\t\t\\\n} while (0)\n\n#else\n#define\tQMD_TRACE_ELEM(elem)\n#define\tQMD_TRACE_HEAD(head)\n#define\tQMD_SAVELINK(name, link)\n#define\tTRACEBUF\n#define\tTRACEBUF_INITIALIZER\n#define\tTRASHIT(x)\n#endif\t/* QUEUE_MACRO_DEBUG */\n\n#ifdef __cplusplus\n/*\n * In C++ there can be structure lists and class lists:\n */\n#define\tQUEUE_TYPEOF(type) type\n#else\n#define\tQUEUE_TYPEOF(type) struct type\n#endif\n\n/*\n * Singly-linked List declarations.\n */\n#define\tSLIST_HEAD(name, type)\t\t\t\t\t\t\\\nstruct name {\t\t\t\t\t\t\t\t\\\n\tstruct type *slh_first;\t/* first element */\t\t\t\\\n}\n\n#define\tSLIST_CLASS_HEAD(name, type)\t\t\t\t\t\\\nstruct name {\t\t\t\t\t\t\t\t\\\n\tclass type *slh_first;\t/* first element */\t\t\t\\\n}\n\n#define\tSLIST_HEAD_INITIALIZER(head)\t\t\t\t\t\\\n\t{ NULL }\n\n#define\tSLIST_ENTRY(type)\t\t\t\t\t\t\\\nstruct {\t\t\t\t\t\t\t\t\\\n\tstruct type *sle_next;\t/* next element */\t\t\t\\\n}\n\n#define\tSLIST_CLASS_ENTRY(type)\t\t\t\t\t\t\\\nstruct {\t\t\t\t\t\t\t\t\\\n\tclass type *sle_next;\t\t/* next element */\t\t\\\n}\n\n/*\n * Singly-linked List functions.\n */\n#define\tSLIST_EMPTY(head)\t((head)->slh_first == NULL)\n\n#define\tSLIST_FIRST(head)\t((head)->slh_first)\n\n#define\tSLIST_FOREACH(var, head, field)\t\t\t\t\t\\\n\tfor ((var) = SLIST_FIRST((head));\t\t\t\t\\\n\t    (var);\t\t\t\t\t\t\t\\\n\t    (var) = SLIST_NEXT((var), field))\n\n#define\tSLIST_FOREACH_FROM(var, head, field)\t\t\t\t\\\n\tfor ((var) = ((var) ? (var) : SLIST_FIRST((head)));\t\t\\\n\t    (var);\t\t\t\t\t\t\t\\\n\t    (var) = SLIST_NEXT((var), field))\n\n#define\tSLIST_FOREACH_SAFE(var, head, field, tvar)\t\t\t\\\n\tfor ((var) = SLIST_FIRST((head));\t\t\t\t\\\n\t    (var) && ((tvar) = SLIST_NEXT((var), field), 1);\t\t\\\n\t    (var) = (tvar))\n\n#define\tSLIST_FOREACH_FROM_SAFE(var, head, field, tvar)\t\t\t\\\n\tfor ((var) = ((var) ? (var) : SLIST_FIRST((head)));\t\t\\\n\t    (var) && ((tvar) = SLIST_NEXT((var), field), 1);\t\t\\\n\t    (var) = (tvar))\n\n#define\tSLIST_FOREACH_PREVPTR(var, varp, head, field)\t\t\t\\\n\tfor ((varp) = &SLIST_FIRST((head));\t\t\t\t\\\n\t    ((var) = *(varp)) != NULL;\t\t\t\t\t\\\n\t    (varp) = &SLIST_NEXT((var), field))\n\n#define\tSLIST_INIT(head) do {\t\t\t\t\t\t\\\n\tSLIST_FIRST((head)) = NULL;\t\t\t\t\t\\\n} while (0)\n\n#define\tSLIST_INSERT_AFTER(slistelm, elm, field) do {\t\t\t\\\n\tSLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field);\t\\\n\tSLIST_NEXT((slistelm), field) = (elm);\t\t\t\t\\\n} while (0)\n\n#define\tSLIST_INSERT_HEAD(head, elm, field) do {\t\t\t\\\n\tSLIST_NEXT((elm), field) = SLIST_FIRST((head));\t\t\t\\\n\tSLIST_FIRST((head)) = (elm);\t\t\t\t\t\\\n} while (0)\n\n#define\tSLIST_NEXT(elm, field)\t((elm)->field.sle_next)\n\n#define\tSLIST_REMOVE(head, elm, type, field) do {\t\t\t\\\n\tQMD_SAVELINK(oldnext, (elm)->field.sle_next);\t\t\t\\\n\tif (SLIST_FIRST((head)) == (elm)) {\t\t\t\t\\\n\t\tSLIST_REMOVE_HEAD((head), field);\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\telse {\t\t\t\t\t\t\t\t\\\n\t\tQUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head);\t\t\\\n\t\twhile (SLIST_NEXT(curelm, field) != (elm))\t\t\\\n\t\t\tcurelm = SLIST_NEXT(curelm, field);\t\t\\\n\t\tSLIST_REMOVE_AFTER(curelm, field);\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\tTRASHIT(*oldnext);\t\t\t\t\t\t\\\n} while (0)\n\n#define SLIST_REMOVE_AFTER(elm, field) do {\t\t\t\t\\\n\tSLIST_NEXT(elm, field) =\t\t\t\t\t\\\n\t    SLIST_NEXT(SLIST_NEXT(elm, field), field);\t\t\t\\\n} while (0)\n\n#define\tSLIST_REMOVE_HEAD(head, field) do {\t\t\t\t\\\n\tSLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field);\t\\\n} while (0)\n\n#define SLIST_SWAP(head1, head2, type) do {\t\t\t\t\\\n\tQUEUE_TYPEOF(type) *swap_first = SLIST_FIRST(head1);\t\t\\\n\tSLIST_FIRST(head1) = SLIST_FIRST(head2);\t\t\t\\\n\tSLIST_FIRST(head2) = swap_first;\t\t\t\t\\\n} while (0)\n\n/*\n * Singly-linked Tail queue declarations.\n */\n#define\tSTAILQ_HEAD(name, type)\t\t\t\t\t\t\\\nstruct name {\t\t\t\t\t\t\t\t\\\n\tstruct type *stqh_first;/* first element */\t\t\t\\\n\tstruct type **stqh_last;/* addr of last next element */\t\t\\\n}\n\n#define\tSTAILQ_CLASS_HEAD(name, type)\t\t\t\t\t\\\nstruct name {\t\t\t\t\t\t\t\t\\\n\tclass type *stqh_first;\t/* first element */\t\t\t\\\n\tclass type **stqh_last;\t/* addr of last next element */\t\t\\\n}\n\n#define\tSTAILQ_HEAD_INITIALIZER(head)\t\t\t\t\t\\\n\t{ NULL, &(head).stqh_first }\n\n#define\tSTAILQ_ENTRY(type)\t\t\t\t\t\t\\\nstruct {\t\t\t\t\t\t\t\t\\\n\tstruct type *stqe_next;\t/* next element */\t\t\t\\\n}\n\n#define\tSTAILQ_CLASS_ENTRY(type)\t\t\t\t\t\\\nstruct {\t\t\t\t\t\t\t\t\\\n\tclass type *stqe_next;\t/* next element */\t\t\t\\\n}\n\n/*\n * Singly-linked Tail queue functions.\n */\n#define\tSTAILQ_CONCAT(head1, head2) do {\t\t\t\t\\\n\tif (!STAILQ_EMPTY((head2))) {\t\t\t\t\t\\\n\t\t*(head1)->stqh_last = (head2)->stqh_first;\t\t\\\n\t\t(head1)->stqh_last = (head2)->stqh_last;\t\t\\\n\t\tSTAILQ_INIT((head2));\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n\n#define\tSTAILQ_EMPTY(head)\t((head)->stqh_first == NULL)\n\n#define\tSTAILQ_FIRST(head)\t((head)->stqh_first)\n\n#define\tSTAILQ_FOREACH(var, head, field)\t\t\t\t\\\n\tfor((var) = STAILQ_FIRST((head));\t\t\t\t\\\n\t   (var);\t\t\t\t\t\t\t\\\n\t   (var) = STAILQ_NEXT((var), field))\n\n#define\tSTAILQ_FOREACH_FROM(var, head, field)\t\t\t\t\\\n\tfor ((var) = ((var) ? (var) : STAILQ_FIRST((head)));\t\t\\\n\t   (var);\t\t\t\t\t\t\t\\\n\t   (var) = STAILQ_NEXT((var), field))\n\n#define\tSTAILQ_FOREACH_SAFE(var, head, field, tvar)\t\t\t\\\n\tfor ((var) = STAILQ_FIRST((head));\t\t\t\t\\\n\t    (var) && ((tvar) = STAILQ_NEXT((var), field), 1);\t\t\\\n\t    (var) = (tvar))\n\n#define\tSTAILQ_FOREACH_FROM_SAFE(var, head, field, tvar)\t\t\\\n\tfor ((var) = ((var) ? (var) : STAILQ_FIRST((head)));\t\t\\\n\t    (var) && ((tvar) = STAILQ_NEXT((var), field), 1);\t\t\\\n\t    (var) = (tvar))\n\n#define\tSTAILQ_INIT(head) do {\t\t\t\t\t\t\\\n\tSTAILQ_FIRST((head)) = NULL;\t\t\t\t\t\\\n\t(head)->stqh_last = &STAILQ_FIRST((head));\t\t\t\\\n} while (0)\n\n#define\tSTAILQ_INSERT_AFTER(head, tqelm, elm, field) do {\t\t\\\n\tif ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\\\n\t\t(head)->stqh_last = &STAILQ_NEXT((elm), field);\t\t\\\n\tSTAILQ_NEXT((tqelm), field) = (elm);\t\t\t\t\\\n} while (0)\n\n#define\tSTAILQ_INSERT_HEAD(head, elm, field) do {\t\t\t\\\n\tif ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL)\t\\\n\t\t(head)->stqh_last = &STAILQ_NEXT((elm), field);\t\t\\\n\tSTAILQ_FIRST((head)) = (elm);\t\t\t\t\t\\\n} while (0)\n\n#define\tSTAILQ_INSERT_TAIL(head, elm, field) do {\t\t\t\\\n\tSTAILQ_NEXT((elm), field) = NULL;\t\t\t\t\\\n\t*(head)->stqh_last = (elm);\t\t\t\t\t\\\n\t(head)->stqh_last = &STAILQ_NEXT((elm), field);\t\t\t\\\n} while (0)\n\n#define\tSTAILQ_LAST(head, type, field)\t\t\t\t\\\n\t(STAILQ_EMPTY((head)) ? NULL :\t\t\t\t\\\n\t    __containerof((head)->stqh_last,\t\t\t\\\n\t    QUEUE_TYPEOF(type), field.stqe_next))\n\n#define\tSTAILQ_NEXT(elm, field)\t((elm)->field.stqe_next)\n\n#define\tSTAILQ_REMOVE(head, elm, type, field) do {\t\t\t\\\n\tQMD_SAVELINK(oldnext, (elm)->field.stqe_next);\t\t\t\\\n\tif (STAILQ_FIRST((head)) == (elm)) {\t\t\t\t\\\n\t\tSTAILQ_REMOVE_HEAD((head), field);\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\telse {\t\t\t\t\t\t\t\t\\\n\t\tQUEUE_TYPEOF(type) *curelm = STAILQ_FIRST(head);\t\\\n\t\twhile (STAILQ_NEXT(curelm, field) != (elm))\t\t\\\n\t\t\tcurelm = STAILQ_NEXT(curelm, field);\t\t\\\n\t\tSTAILQ_REMOVE_AFTER(head, curelm, field);\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\tTRASHIT(*oldnext);\t\t\t\t\t\t\\\n} while (0)\n\n#define STAILQ_REMOVE_AFTER(head, elm, field) do {\t\t\t\\\n\tif ((STAILQ_NEXT(elm, field) =\t\t\t\t\t\\\n\t     STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL)\t\\\n\t\t(head)->stqh_last = &STAILQ_NEXT((elm), field);\t\t\\\n} while (0)\n\n#define\tSTAILQ_REMOVE_HEAD(head, field) do {\t\t\t\t\\\n\tif ((STAILQ_FIRST((head)) =\t\t\t\t\t\\\n\t     STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)\t\t\\\n\t\t(head)->stqh_last = &STAILQ_FIRST((head));\t\t\\\n} while (0)\n\n#define STAILQ_SWAP(head1, head2, type) do {\t\t\t\t\\\n\tQUEUE_TYPEOF(type) *swap_first = STAILQ_FIRST(head1);\t\t\\\n\tQUEUE_TYPEOF(type) **swap_last = (head1)->stqh_last;\t\t\\\n\tSTAILQ_FIRST(head1) = STAILQ_FIRST(head2);\t\t\t\\\n\t(head1)->stqh_last = (head2)->stqh_last;\t\t\t\\\n\tSTAILQ_FIRST(head2) = swap_first;\t\t\t\t\\\n\t(head2)->stqh_last = swap_last;\t\t\t\t\t\\\n\tif (STAILQ_EMPTY(head1))\t\t\t\t\t\\\n\t\t(head1)->stqh_last = &STAILQ_FIRST(head1);\t\t\\\n\tif (STAILQ_EMPTY(head2))\t\t\t\t\t\\\n\t\t(head2)->stqh_last = &STAILQ_FIRST(head2);\t\t\\\n} while (0)\n\n\n/*\n * List declarations.\n */\n#define\tLIST_HEAD(name, type)\t\t\t\t\t\t\\\nstruct name {\t\t\t\t\t\t\t\t\\\n\tstruct type *lh_first;\t/* first element */\t\t\t\\\n}\n\n#define\tLIST_CLASS_HEAD(name, type)\t\t\t\t\t\\\nstruct name {\t\t\t\t\t\t\t\t\\\n\tclass type *lh_first;\t/* first element */\t\t\t\\\n}\n\n#define\tLIST_HEAD_INITIALIZER(head)\t\t\t\t\t\\\n\t{ NULL }\n\n#define\tLIST_ENTRY(type)\t\t\t\t\t\t\\\nstruct {\t\t\t\t\t\t\t\t\\\n\tstruct type *le_next;\t/* next element */\t\t\t\\\n\tstruct type **le_prev;\t/* address of previous next element */\t\\\n}\n\n#define\tLIST_CLASS_ENTRY(type)\t\t\t\t\t\t\\\nstruct {\t\t\t\t\t\t\t\t\\\n\tclass type *le_next;\t/* next element */\t\t\t\\\n\tclass type **le_prev;\t/* address of previous next element */\t\\\n}\n\n/*\n * List functions.\n */\n\n#if (defined(_KERNEL) && defined(INVARIANTS))\n#define\tQMD_LIST_CHECK_HEAD(head, field) do {\t\t\t\t\\\n\tif (LIST_FIRST((head)) != NULL &&\t\t\t\t\\\n\t    LIST_FIRST((head))->field.le_prev !=\t\t\t\\\n\t     &LIST_FIRST((head)))\t\t\t\t\t\\\n\t\tpanic(\"Bad list head %p first->prev != head\", (head));\t\\\n} while (0)\n\n#define\tQMD_LIST_CHECK_NEXT(elm, field) do {\t\t\t\t\\\n\tif (LIST_NEXT((elm), field) != NULL &&\t\t\t\t\\\n\t    LIST_NEXT((elm), field)->field.le_prev !=\t\t\t\\\n\t     &((elm)->field.le_next))\t\t\t\t\t\\\n\t     \tpanic(\"Bad link elm %p next->prev != elm\", (elm));\t\\\n} while (0)\n\n#define\tQMD_LIST_CHECK_PREV(elm, field) do {\t\t\t\t\\\n\tif (*(elm)->field.le_prev != (elm))\t\t\t\t\\\n\t\tpanic(\"Bad link elm %p prev->next != elm\", (elm));\t\\\n} while (0)\n#else\n#define\tQMD_LIST_CHECK_HEAD(head, field)\n#define\tQMD_LIST_CHECK_NEXT(elm, field)\n#define\tQMD_LIST_CHECK_PREV(elm, field)\n#endif /* (_KERNEL && INVARIANTS) */\n\n#define\tLIST_EMPTY(head)\t((head)->lh_first == NULL)\n\n#define\tLIST_FIRST(head)\t((head)->lh_first)\n\n#define\tLIST_FOREACH(var, head, field)\t\t\t\t\t\\\n\tfor ((var) = LIST_FIRST((head));\t\t\t\t\\\n\t    (var);\t\t\t\t\t\t\t\\\n\t    (var) = LIST_NEXT((var), field))\n\n#define\tLIST_FOREACH_FROM(var, head, field)\t\t\t\t\\\n\tfor ((var) = ((var) ? (var) : LIST_FIRST((head)));\t\t\\\n\t    (var);\t\t\t\t\t\t\t\\\n\t    (var) = LIST_NEXT((var), field))\n\n#define\tLIST_FOREACH_SAFE(var, head, field, tvar)\t\t\t\\\n\tfor ((var) = LIST_FIRST((head));\t\t\t\t\\\n\t    (var) && ((tvar) = LIST_NEXT((var), field), 1);\t\t\\\n\t    (var) = (tvar))\n\n#define\tLIST_FOREACH_FROM_SAFE(var, head, field, tvar)\t\t\t\\\n\tfor ((var) = ((var) ? (var) : LIST_FIRST((head)));\t\t\\\n\t    (var) && ((tvar) = LIST_NEXT((var), field), 1);\t\t\\\n\t    (var) = (tvar))\n\n#define\tLIST_INIT(head) do {\t\t\t\t\t\t\\\n\tLIST_FIRST((head)) = NULL;\t\t\t\t\t\\\n} while (0)\n\n#define\tLIST_INSERT_AFTER(listelm, elm, field) do {\t\t\t\\\n\tQMD_LIST_CHECK_NEXT(listelm, field);\t\t\t\t\\\n\tif ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\\\n\t\tLIST_NEXT((listelm), field)->field.le_prev =\t\t\\\n\t\t    &LIST_NEXT((elm), field);\t\t\t\t\\\n\tLIST_NEXT((listelm), field) = (elm);\t\t\t\t\\\n\t(elm)->field.le_prev = &LIST_NEXT((listelm), field);\t\t\\\n} while (0)\n\n#define\tLIST_INSERT_BEFORE(listelm, elm, field) do {\t\t\t\\\n\tQMD_LIST_CHECK_PREV(listelm, field);\t\t\t\t\\\n\t(elm)->field.le_prev = (listelm)->field.le_prev;\t\t\\\n\tLIST_NEXT((elm), field) = (listelm);\t\t\t\t\\\n\t*(listelm)->field.le_prev = (elm);\t\t\t\t\\\n\t(listelm)->field.le_prev = &LIST_NEXT((elm), field);\t\t\\\n} while (0)\n\n#define\tLIST_INSERT_HEAD(head, elm, field) do {\t\t\t\t\\\n\tQMD_LIST_CHECK_HEAD((head), field);\t\t\t\t\\\n\tif ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL)\t\\\n\t\tLIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\\\n\tLIST_FIRST((head)) = (elm);\t\t\t\t\t\\\n\t(elm)->field.le_prev = &LIST_FIRST((head));\t\t\t\\\n} while (0)\n\n#define\tLIST_NEXT(elm, field)\t((elm)->field.le_next)\n\n#define\tLIST_PREV(elm, head, type, field)\t\t\t\\\n\t((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL :\t\\\n\t    __containerof((elm)->field.le_prev,\t\t\t\\\n\t    QUEUE_TYPEOF(type), field.le_next))\n\n#define\tLIST_REMOVE(elm, field) do {\t\t\t\t\t\\\n\tQMD_SAVELINK(oldnext, (elm)->field.le_next);\t\t\t\\\n\tQMD_SAVELINK(oldprev, (elm)->field.le_prev);\t\t\t\\\n\tQMD_LIST_CHECK_NEXT(elm, field);\t\t\t\t\\\n\tQMD_LIST_CHECK_PREV(elm, field);\t\t\t\t\\\n\tif (LIST_NEXT((elm), field) != NULL)\t\t\t\t\\\n\t\tLIST_NEXT((elm), field)->field.le_prev = \t\t\\\n\t\t    (elm)->field.le_prev;\t\t\t\t\\\n\t*(elm)->field.le_prev = LIST_NEXT((elm), field);\t\t\\\n\tTRASHIT(*oldnext);\t\t\t\t\t\t\\\n\tTRASHIT(*oldprev);\t\t\t\t\t\t\\\n} while (0)\n\n#define LIST_SWAP(head1, head2, type, field) do {\t\t\t\\\n\tQUEUE_TYPEOF(type) *swap_tmp = LIST_FIRST(head1);\t\t\\\n\tLIST_FIRST((head1)) = LIST_FIRST((head2));\t\t\t\\\n\tLIST_FIRST((head2)) = swap_tmp;\t\t\t\t\t\\\n\tif ((swap_tmp = LIST_FIRST((head1))) != NULL)\t\t\t\\\n\t\tswap_tmp->field.le_prev = &LIST_FIRST((head1));\t\t\\\n\tif ((swap_tmp = LIST_FIRST((head2))) != NULL)\t\t\t\\\n\t\tswap_tmp->field.le_prev = &LIST_FIRST((head2));\t\t\\\n} while (0)\n\n/*\n * Tail queue declarations.\n */\n#define\tTAILQ_HEAD(name, type)\t\t\t\t\t\t\\\nstruct name {\t\t\t\t\t\t\t\t\\\n\tstruct type *tqh_first;\t/* first element */\t\t\t\\\n\tstruct type **tqh_last;\t/* addr of last next element */\t\t\\\n\tTRACEBUF\t\t\t\t\t\t\t\\\n}\n\n#define\tTAILQ_CLASS_HEAD(name, type)\t\t\t\t\t\\\nstruct name {\t\t\t\t\t\t\t\t\\\n\tclass type *tqh_first;\t/* first element */\t\t\t\\\n\tclass type **tqh_last;\t/* addr of last next element */\t\t\\\n\tTRACEBUF\t\t\t\t\t\t\t\\\n}\n\n#define\tTAILQ_HEAD_INITIALIZER(head)\t\t\t\t\t\\\n\t{ NULL, &(head).tqh_first, TRACEBUF_INITIALIZER }\n\n#define\tTAILQ_ENTRY(type)\t\t\t\t\t\t\\\nstruct {\t\t\t\t\t\t\t\t\\\n\tstruct type *tqe_next;\t/* next element */\t\t\t\\\n\tstruct type **tqe_prev;\t/* address of previous next element */\t\\\n\tTRACEBUF\t\t\t\t\t\t\t\\\n}\n\n#define\tTAILQ_CLASS_ENTRY(type)\t\t\t\t\t\t\\\nstruct {\t\t\t\t\t\t\t\t\\\n\tclass type *tqe_next;\t/* next element */\t\t\t\\\n\tclass type **tqe_prev;\t/* address of previous next element */\t\\\n\tTRACEBUF\t\t\t\t\t\t\t\\\n}\n\n/*\n * Tail queue functions.\n */\n#if (defined(_KERNEL) && defined(INVARIANTS))\n#define\tQMD_TAILQ_CHECK_HEAD(head, field) do {\t\t\t\t\\\n\tif (!TAILQ_EMPTY(head) &&\t\t\t\t\t\\\n\t    TAILQ_FIRST((head))->field.tqe_prev !=\t\t\t\\\n\t     &TAILQ_FIRST((head)))\t\t\t\t\t\\\n\t\tpanic(\"Bad tailq head %p first->prev != head\", (head));\t\\\n} while (0)\n\n#define\tQMD_TAILQ_CHECK_TAIL(head, field) do {\t\t\t\t\\\n\tif (*(head)->tqh_last != NULL)\t\t\t\t\t\\\n\t    \tpanic(\"Bad tailq NEXT(%p->tqh_last) != NULL\", (head)); \t\\\n} while (0)\n\n#define\tQMD_TAILQ_CHECK_NEXT(elm, field) do {\t\t\t\t\\\n\tif (TAILQ_NEXT((elm), field) != NULL &&\t\t\t\t\\\n\t    TAILQ_NEXT((elm), field)->field.tqe_prev !=\t\t\t\\\n\t     &((elm)->field.tqe_next))\t\t\t\t\t\\\n\t\tpanic(\"Bad link elm %p next->prev != elm\", (elm));\t\\\n} while (0)\n\n#define\tQMD_TAILQ_CHECK_PREV(elm, field) do {\t\t\t\t\\\n\tif (*(elm)->field.tqe_prev != (elm))\t\t\t\t\\\n\t\tpanic(\"Bad link elm %p prev->next != elm\", (elm));\t\\\n} while (0)\n#else\n#define\tQMD_TAILQ_CHECK_HEAD(head, field)\n#define\tQMD_TAILQ_CHECK_TAIL(head, headname)\n#define\tQMD_TAILQ_CHECK_NEXT(elm, field)\n#define\tQMD_TAILQ_CHECK_PREV(elm, field)\n#endif /* (_KERNEL && INVARIANTS) */\n\n#define\tTAILQ_CONCAT(head1, head2, field) do {\t\t\t\t\\\n\tif (!TAILQ_EMPTY(head2)) {\t\t\t\t\t\\\n\t\t*(head1)->tqh_last = (head2)->tqh_first;\t\t\\\n\t\t(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;\t\\\n\t\t(head1)->tqh_last = (head2)->tqh_last;\t\t\t\\\n\t\tTAILQ_INIT((head2));\t\t\t\t\t\\\n\t\tQMD_TRACE_HEAD(head1);\t\t\t\t\t\\\n\t\tQMD_TRACE_HEAD(head2);\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n} while (0)\n\n#define\tTAILQ_EMPTY(head)\t((head)->tqh_first == NULL)\n\n#define\tTAILQ_FIRST(head)\t((head)->tqh_first)\n\n#define\tTAILQ_FOREACH(var, head, field)\t\t\t\t\t\\\n\tfor ((var) = TAILQ_FIRST((head));\t\t\t\t\\\n\t    (var);\t\t\t\t\t\t\t\\\n\t    (var) = TAILQ_NEXT((var), field))\n\n#define\tTAILQ_FOREACH_FROM(var, head, field)\t\t\t\t\\\n\tfor ((var) = ((var) ? (var) : TAILQ_FIRST((head)));\t\t\\\n\t    (var);\t\t\t\t\t\t\t\\\n\t    (var) = TAILQ_NEXT((var), field))\n\n#define\tTAILQ_FOREACH_SAFE(var, head, field, tvar)\t\t\t\\\n\tfor ((var) = TAILQ_FIRST((head));\t\t\t\t\\\n\t    (var) && ((tvar) = TAILQ_NEXT((var), field), 1);\t\t\\\n\t    (var) = (tvar))\n\n#define\tTAILQ_FOREACH_FROM_SAFE(var, head, field, tvar)\t\t\t\\\n\tfor ((var) = ((var) ? (var) : TAILQ_FIRST((head)));\t\t\\\n\t    (var) && ((tvar) = TAILQ_NEXT((var), field), 1);\t\t\\\n\t    (var) = (tvar))\n\n#define\tTAILQ_FOREACH_REVERSE(var, head, headname, field)\t\t\\\n\tfor ((var) = TAILQ_LAST((head), headname);\t\t\t\\\n\t    (var);\t\t\t\t\t\t\t\\\n\t    (var) = TAILQ_PREV((var), headname, field))\n\n#define\tTAILQ_FOREACH_REVERSE_FROM(var, head, headname, field)\t\t\\\n\tfor ((var) = ((var) ? (var) : TAILQ_LAST((head), headname));\t\\\n\t    (var);\t\t\t\t\t\t\t\\\n\t    (var) = TAILQ_PREV((var), headname, field))\n\n#define\tTAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)\t\\\n\tfor ((var) = TAILQ_LAST((head), headname);\t\t\t\\\n\t    (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1);\t\\\n\t    (var) = (tvar))\n\n#define\tTAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar) \\\n\tfor ((var) = ((var) ? (var) : TAILQ_LAST((head), headname));\t\\\n\t    (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1);\t\\\n\t    (var) = (tvar))\n\n#define\tTAILQ_INIT(head) do {\t\t\t\t\t\t\\\n\tTAILQ_FIRST((head)) = NULL;\t\t\t\t\t\\\n\t(head)->tqh_last = &TAILQ_FIRST((head));\t\t\t\\\n\tQMD_TRACE_HEAD(head);\t\t\t\t\t\t\\\n} while (0)\n\n#define\tTAILQ_INSERT_AFTER(head, listelm, elm, field) do {\t\t\\\n\tQMD_TAILQ_CHECK_NEXT(listelm, field);\t\t\t\t\\\n\tif ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\\\n\t\tTAILQ_NEXT((elm), field)->field.tqe_prev = \t\t\\\n\t\t    &TAILQ_NEXT((elm), field);\t\t\t\t\\\n\telse {\t\t\t\t\t\t\t\t\\\n\t\t(head)->tqh_last = &TAILQ_NEXT((elm), field);\t\t\\\n\t\tQMD_TRACE_HEAD(head);\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\tTAILQ_NEXT((listelm), field) = (elm);\t\t\t\t\\\n\t(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field);\t\t\\\n\tQMD_TRACE_ELEM(&(elm)->field);\t\t\t\t\t\\\n\tQMD_TRACE_ELEM(&(listelm)->field);\t\t\t\t\\\n} while (0)\n\n#define\tTAILQ_INSERT_BEFORE(listelm, elm, field) do {\t\t\t\\\n\tQMD_TAILQ_CHECK_PREV(listelm, field);\t\t\t\t\\\n\t(elm)->field.tqe_prev = (listelm)->field.tqe_prev;\t\t\\\n\tTAILQ_NEXT((elm), field) = (listelm);\t\t\t\t\\\n\t*(listelm)->field.tqe_prev = (elm);\t\t\t\t\\\n\t(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field);\t\t\\\n\tQMD_TRACE_ELEM(&(elm)->field);\t\t\t\t\t\\\n\tQMD_TRACE_ELEM(&(listelm)->field);\t\t\t\t\\\n} while (0)\n\n#define\tTAILQ_INSERT_HEAD(head, elm, field) do {\t\t\t\\\n\tQMD_TAILQ_CHECK_HEAD(head, field);\t\t\t\t\\\n\tif ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)\t\\\n\t\tTAILQ_FIRST((head))->field.tqe_prev =\t\t\t\\\n\t\t    &TAILQ_NEXT((elm), field);\t\t\t\t\\\n\telse\t\t\t\t\t\t\t\t\\\n\t\t(head)->tqh_last = &TAILQ_NEXT((elm), field);\t\t\\\n\tTAILQ_FIRST((head)) = (elm);\t\t\t\t\t\\\n\t(elm)->field.tqe_prev = &TAILQ_FIRST((head));\t\t\t\\\n\tQMD_TRACE_HEAD(head);\t\t\t\t\t\t\\\n\tQMD_TRACE_ELEM(&(elm)->field);\t\t\t\t\t\\\n} while (0)\n\n#define\tTAILQ_INSERT_TAIL(head, elm, field) do {\t\t\t\\\n\tQMD_TAILQ_CHECK_TAIL(head, field);\t\t\t\t\\\n\tTAILQ_NEXT((elm), field) = NULL;\t\t\t\t\\\n\t(elm)->field.tqe_prev = (head)->tqh_last;\t\t\t\\\n\t*(head)->tqh_last = (elm);\t\t\t\t\t\\\n\t(head)->tqh_last = &TAILQ_NEXT((elm), field);\t\t\t\\\n\tQMD_TRACE_HEAD(head);\t\t\t\t\t\t\\\n\tQMD_TRACE_ELEM(&(elm)->field);\t\t\t\t\t\\\n} while (0)\n\n#define\tTAILQ_LAST(head, headname)\t\t\t\t\t\\\n\t(*(((struct headname *)((head)->tqh_last))->tqh_last))\n\n#define\tTAILQ_NEXT(elm, field) ((elm)->field.tqe_next)\n\n#define\tTAILQ_PREV(elm, headname, field)\t\t\t\t\\\n\t(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))\n\n#define\tTAILQ_REMOVE(head, elm, field) do {\t\t\t\t\\\n\tQMD_SAVELINK(oldnext, (elm)->field.tqe_next);\t\t\t\\\n\tQMD_SAVELINK(oldprev, (elm)->field.tqe_prev);\t\t\t\\\n\tQMD_TAILQ_CHECK_NEXT(elm, field);\t\t\t\t\\\n\tQMD_TAILQ_CHECK_PREV(elm, field);\t\t\t\t\\\n\tif ((TAILQ_NEXT((elm), field)) != NULL)\t\t\t\t\\\n\t\tTAILQ_NEXT((elm), field)->field.tqe_prev = \t\t\\\n\t\t    (elm)->field.tqe_prev;\t\t\t\t\\\n\telse {\t\t\t\t\t\t\t\t\\\n\t\t(head)->tqh_last = (elm)->field.tqe_prev;\t\t\\\n\t\tQMD_TRACE_HEAD(head);\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\t*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);\t\t\\\n\tTRASHIT(*oldnext);\t\t\t\t\t\t\\\n\tTRASHIT(*oldprev);\t\t\t\t\t\t\\\n\tQMD_TRACE_ELEM(&(elm)->field);\t\t\t\t\t\\\n} while (0)\n\n#define TAILQ_SWAP(head1, head2, type, field) do {\t\t\t\\\n\tQUEUE_TYPEOF(type) *swap_first = (head1)->tqh_first;\t\t\\\n\tQUEUE_TYPEOF(type) **swap_last = (head1)->tqh_last;\t\t\\\n\t(head1)->tqh_first = (head2)->tqh_first;\t\t\t\\\n\t(head1)->tqh_last = (head2)->tqh_last;\t\t\t\t\\\n\t(head2)->tqh_first = swap_first;\t\t\t\t\\\n\t(head2)->tqh_last = swap_last;\t\t\t\t\t\\\n\tif ((swap_first = (head1)->tqh_first) != NULL)\t\t\t\\\n\t\tswap_first->field.tqe_prev = &(head1)->tqh_first;\t\\\n\telse\t\t\t\t\t\t\t\t\\\n\t\t(head1)->tqh_last = &(head1)->tqh_first;\t\t\\\n\tif ((swap_first = (head2)->tqh_first) != NULL)\t\t\t\\\n\t\tswap_first->field.tqe_prev = &(head2)->tqh_first;\t\\\n\telse\t\t\t\t\t\t\t\t\\\n\t\t(head2)->tqh_last = &(head2)->tqh_first;\t\t\\\n} while (0)\n\n#endif /* !_SYS_QUEUE_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/features.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_MONGOOSE_SRC_FEATURES_H_\n#define CS_MONGOOSE_SRC_FEATURES_H_\n\n#ifndef MG_DISABLE_HTTP_DIGEST_AUTH\n#define MG_DISABLE_HTTP_DIGEST_AUTH 0\n#endif\n\n#ifndef MG_DISABLE_HTTP_KEEP_ALIVE\n#define MG_DISABLE_HTTP_KEEP_ALIVE 0\n#endif\n\n#ifndef MG_DISABLE_PFS\n#define MG_DISABLE_PFS 0\n#endif\n\n#ifndef MG_DISABLE_WS_RANDOM_MASK\n#define MG_DISABLE_WS_RANDOM_MASK 0\n#endif\n\n#ifndef MG_ENABLE_ASYNC_RESOLVER\n#define MG_ENABLE_ASYNC_RESOLVER 1\n#endif\n\n#ifndef MG_ENABLE_BROADCAST\n#define MG_ENABLE_BROADCAST 0\n#endif\n\n#ifndef MG_ENABLE_COAP\n#define MG_ENABLE_COAP 0\n#endif\n\n#ifndef MG_ENABLE_DEBUG\n#define MG_ENABLE_DEBUG 0\n#endif\n\n#ifndef MG_ENABLE_DIRECTORY_LISTING\n#define MG_ENABLE_DIRECTORY_LISTING 0\n#endif\n\n#ifndef MG_ENABLE_DNS\n#define MG_ENABLE_DNS 1\n#endif\n\n#ifndef MG_ENABLE_DNS_SERVER\n#define MG_ENABLE_DNS_SERVER 0\n#endif\n\n#ifndef MG_ENABLE_FAKE_DAVLOCK\n#define MG_ENABLE_FAKE_DAVLOCK 0\n#endif\n\n#ifndef MG_ENABLE_FILESYSTEM\n#define MG_ENABLE_FILESYSTEM 0\n#endif\n\n#ifndef MG_ENABLE_GETADDRINFO\n#define MG_ENABLE_GETADDRINFO 0\n#endif\n\n#ifndef MG_ENABLE_HEXDUMP\n#define MG_ENABLE_HEXDUMP CS_ENABLE_STDIO\n#endif\n\n#ifndef MG_ENABLE_HTTP\n#define MG_ENABLE_HTTP 1\n#endif\n\n#ifndef MG_ENABLE_HTTP_CGI\n#define MG_ENABLE_HTTP_CGI 0\n#endif\n\n#ifndef MG_ENABLE_HTTP_SSI\n#define MG_ENABLE_HTTP_SSI MG_ENABLE_FILESYSTEM\n#endif\n\n#ifndef MG_ENABLE_HTTP_SSI_EXEC\n#define MG_ENABLE_HTTP_SSI_EXEC 0\n#endif\n\n#ifndef MG_ENABLE_HTTP_STREAMING_MULTIPART\n#define MG_ENABLE_HTTP_STREAMING_MULTIPART 0\n#endif\n\n#ifndef MG_ENABLE_HTTP_WEBDAV\n#define MG_ENABLE_HTTP_WEBDAV 0\n#endif\n\n#ifndef MG_ENABLE_HTTP_WEBSOCKET\n#define MG_ENABLE_HTTP_WEBSOCKET MG_ENABLE_HTTP\n#endif\n\n#ifndef MG_ENABLE_IPV6\n#define MG_ENABLE_IPV6 0\n#endif\n\n#ifndef MG_ENABLE_JAVASCRIPT\n#define MG_ENABLE_JAVASCRIPT 0\n#endif\n\n#ifndef MG_ENABLE_MQTT\n#define MG_ENABLE_MQTT 1\n#endif\n\n#ifndef MG_ENABLE_MQTT_BROKER\n#define MG_ENABLE_MQTT_BROKER 0\n#endif\n\n#ifndef MG_ENABLE_SSL\n#define MG_ENABLE_SSL 0\n#endif\n\n#ifndef MG_ENABLE_SYNC_RESOLVER\n#define MG_ENABLE_SYNC_RESOLVER 0\n#endif\n\n#ifndef MG_ENABLE_STDIO\n#define MG_ENABLE_STDIO CS_ENABLE_STDIO\n#endif\n\n#ifndef MG_NET_IF\n#define MG_NET_IF MG_NET_IF_SOCKET\n#endif\n\n#ifndef MG_SSL_IF\n#define MG_SSL_IF MG_SSL_IF_OPENSSL\n#endif\n\n#ifndef MG_ENABLE_THREADS /* ifdef-ok */\n#ifdef _WIN32\n#define MG_ENABLE_THREADS 1\n#else\n#define MG_ENABLE_THREADS 0\n#endif\n#endif\n\n#ifndef MG_ENABLE_MUTITHREADS\n#define MG_ENABLE_MUTITHREADS 0\n#endif\n\n#if MG_ENABLE_DEBUG && !defined(CS_ENABLE_DEBUG)\n#define CS_ENABLE_DEBUG 1\n#endif\n\n/* MQTT broker requires MQTT */\n#if MG_ENABLE_MQTT_BROKER && !MG_ENABLE_MQTT\n#undef MG_ENABLE_MQTT\n#define MG_ENABLE_MQTT 1\n#endif\n\n#ifndef MG_ENABLE_HTTP_URL_REWRITES\n#define MG_ENABLE_HTTP_URL_REWRITES \\\n  (CS_PLATFORM == CS_P_WINDOWS || CS_PLATFORM == CS_P_UNIX)\n#endif\n\n#ifndef MG_ENABLE_TUN\n#define MG_ENABLE_TUN MG_ENABLE_HTTP_WEBSOCKET\n#endif\n\n#ifndef MG_ENABLE_SNTP\n#define MG_ENABLE_SNTP 0\n#endif\n\n#endif /* CS_MONGOOSE_SRC_FEATURES_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/net_if.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_MONGOOSE_SRC_NET_IF_H_\n#define CS_MONGOOSE_SRC_NET_IF_H_\n\n/* Amalgamated: #include \"common/platform.h\" */\n\n/*\n * Internal async networking core interface.\n * Consists of calls made by the core, which should not block,\n * and callbacks back into the core (\"..._cb\").\n * Callbacks may (will) cause methods to be invoked from within,\n * but methods are not allowed to invoke callbacks inline.\n *\n * Implementation must ensure that only one callback is invoked at any time.\n */\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n#define MG_MAIN_IFACE 0\n\nstruct mg_mgr;\nstruct mg_connection;\nunion socket_address;\n\nstruct mg_iface_vtable;\n\nstruct mg_iface {\n  struct mg_mgr *mgr;\n  void *data; /* Implementation-specific data */\n  struct mg_iface_vtable *vtable;\n};\n\nstruct mg_iface_vtable {\n  void (*init)(struct mg_iface *iface);\n  void (*free)(struct mg_iface *iface);\n  void (*add_conn)(struct mg_connection *nc);\n  void (*remove_conn)(struct mg_connection *nc);\n  time_t (*poll)(struct mg_iface *iface, int timeout_ms);\n\n  /* Set up a listening TCP socket on a given address. rv = 0 -> ok. */\n  int (*listen_tcp)(struct mg_connection *nc, union socket_address *sa);\n  /* Request that a \"listening\" UDP socket be created. */\n  int (*listen_udp)(struct mg_connection *nc, union socket_address *sa);\n\n  /* Request that a TCP connection is made to the specified address. */\n  void (*connect_tcp)(struct mg_connection *nc, const union socket_address *sa);\n  /* Open a UDP socket. Doesn't actually connect anything. */\n  void (*connect_udp)(struct mg_connection *nc);\n\n  /* Send functions for TCP and UDP. Sent data is copied before return. */\n  void (*tcp_send)(struct mg_connection *nc, const void *buf, size_t len);\n  void (*udp_send)(struct mg_connection *nc, const void *buf, size_t len);\n\n  void (*recved)(struct mg_connection *nc, size_t len);\n\n  /* Perform interface-related connection initialization. Return 1 on ok. */\n  int (*create_conn)(struct mg_connection *nc);\n  /* Perform interface-related cleanup on connection before destruction. */\n  void (*destroy_conn)(struct mg_connection *nc);\n\n  /* Associate a socket to a connection. */\n  void (*sock_set)(struct mg_connection *nc, sock_t sock);\n\n  /* Put connection's address into *sa, local (remote = 0) or remote. */\n  void (*get_conn_addr)(struct mg_connection *nc, int remote,\n                        union socket_address *sa);\n};\n\nextern struct mg_iface_vtable *mg_ifaces[];\nextern int mg_num_ifaces;\n\n/* Creates a new interface instance. */\nstruct mg_iface *mg_if_create_iface(struct mg_iface_vtable *vtable,\n                                    struct mg_mgr *mgr);\n\n/*\n * Find an interface with a given implementation. The search is started from\n * interface `from`, exclusive. Returns NULL if none is found.\n */\nstruct mg_iface *mg_find_iface(struct mg_mgr *mgr,\n                               struct mg_iface_vtable *vtable,\n                               struct mg_iface *from);\n/*\n * Deliver a new TCP connection. Returns NULL in case on error (unable to\n * create connection, in which case interface state should be discarded.\n * This is phase 1 of the two-phase process - MG_EV_ACCEPT will be delivered\n * when mg_if_accept_tcp_cb is invoked.\n */\nstruct mg_connection *mg_if_accept_new_conn(struct mg_connection *lc);\nvoid mg_if_accept_tcp_cb(struct mg_connection *nc, union socket_address *sa,\n                         size_t sa_len);\n\n/* Callback invoked by connect methods. err = 0 -> ok, != 0 -> error. */\nvoid mg_if_connect_cb(struct mg_connection *nc, int err);\n/* Callback that reports that data has been put on the wire. */\nvoid mg_if_sent_cb(struct mg_connection *nc, int num_sent);\n/*\n * Receive callback.\n * if `own` is true, buf must be heap-allocated and ownership is transferred\n * to the core.\n * Core will acknowledge consumption by calling iface::recved.\n */\nvoid mg_if_recv_tcp_cb(struct mg_connection *nc, void *buf, int len, int own);\n/*\n * Receive callback.\n * buf must be heap-allocated and ownership is transferred to the core.\n * Core will acknowledge consumption by calling iface::recved.\n */\nvoid mg_if_recv_udp_cb(struct mg_connection *nc, void *buf, int len,\n                       union socket_address *sa, size_t sa_len);\n\n/* void mg_if_close_conn(struct mg_connection *nc); */\n\n/* Deliver a POLL event to the connection. */\nvoid mg_if_poll(struct mg_connection *nc, time_t now);\n\n/* Deliver a TIMER event to the connection. */\nvoid mg_if_timer(struct mg_connection *c, double now);\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif /* CS_MONGOOSE_SRC_NET_IF_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/ssl_if.h\"\n#endif\n/*\n * Copyright (c) 2014-2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_MONGOOSE_SRC_SSL_IF_H_\n#define CS_MONGOOSE_SRC_SSL_IF_H_\n\n#if MG_ENABLE_SSL\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\nstruct mg_ssl_if_ctx;\nstruct mg_connection;\n\nvoid mg_ssl_if_init();\n\nenum mg_ssl_if_result {\n  MG_SSL_OK = 0,\n  MG_SSL_WANT_READ = -1,\n  MG_SSL_WANT_WRITE = -2,\n  MG_SSL_ERROR = -3,\n};\n\nstruct mg_ssl_if_conn_params {\n  const char *cert;\n  const char *key;\n  const char *ca_cert;\n  const char *server_name;\n};\n\nenum mg_ssl_if_result mg_ssl_if_conn_init(\n    struct mg_connection *nc, const struct mg_ssl_if_conn_params *params,\n    const char **err_msg);\nenum mg_ssl_if_result mg_ssl_if_conn_accept(struct mg_connection *nc,\n                                            struct mg_connection *lc);\nvoid mg_ssl_if_conn_free(struct mg_connection *nc);\n\nenum mg_ssl_if_result mg_ssl_if_handshake(struct mg_connection *nc);\nint mg_ssl_if_read(struct mg_connection *nc, void *buf, size_t buf_size);\nint mg_ssl_if_write(struct mg_connection *nc, const void *data, size_t len);\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif /* MG_ENABLE_SSL */\n\n#endif /* CS_MONGOOSE_SRC_SSL_IF_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/net.h\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n * This software is dual-licensed: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation. For the terms of this\n * license, see <http://www.gnu.org/licenses/>.\n *\n * You are free to use this software under the terms of the GNU General\n * Public License, but WITHOUT ANY WARRANTY; without even the implied\n * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n * See the GNU General Public License for more details.\n *\n * Alternatively, you can license this software under a commercial\n * license, as set out in <https://www.cesanta.com/license>.\n */\n\n/*\n * === Core API: TCP/UDP/SSL\n *\n * NOTE: Mongoose manager is single threaded. It does not protect\n * its data structures by mutexes, therefore all functions that are dealing\n * with a particular event manager should be called from the same thread,\n * with exception of the `mg_broadcast()` function. It is fine to have different\n * event managers handled by different threads.\n */\n\n#ifndef CS_MONGOOSE_SRC_NET_H_\n#define CS_MONGOOSE_SRC_NET_H_\n\n#if MG_ENABLE_JAVASCRIPT\n#define EXCLUDE_COMMON\n#include <v7.h>\n#endif\n\n/* Amalgamated: #include \"mongoose/src/common.h\" */\n/* Amalgamated: #include \"mongoose/src/net_if.h\" */\n/* Amalgamated: #include \"common/mbuf.h\" */\n\n#ifndef MG_VPRINTF_BUFFER_SIZE\n#define MG_VPRINTF_BUFFER_SIZE 100\n#endif\n\n#ifdef MG_USE_READ_WRITE\n#define MG_RECV_FUNC(s, b, l, f) read(s, b, l)\n#define MG_SEND_FUNC(s, b, l, f) write(s, b, l)\n#else\n#define MG_RECV_FUNC(s, b, l, f) recv(s, b, l, f)\n#define MG_SEND_FUNC(s, b, l, f) send(s, b, l, f)\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\nunion socket_address {\n  struct sockaddr sa;\n  struct sockaddr_in sin;\n#if MG_ENABLE_IPV6\n  struct sockaddr_in6 sin6;\n#else\n  struct sockaddr sin6;\n#endif\n};\n\nstruct mg_connection;\n\n/*\n * Callback function (event handler) prototype. Must be defined by the user.\n * Mongoose calls the event handler, passing the events defined below.\n */\ntypedef void (*mg_event_handler_t)(struct mg_connection *nc, int ev,\n                                   void *ev_data);\n\n/* Events. Meaning of event parameter (evp) is given in the comment. */\n#define MG_EV_POLL 0    /* Sent to each connection on each mg_mgr_poll() call */\n#define MG_EV_ACCEPT 1  /* New connection accepted. union socket_address * */\n#define MG_EV_CONNECT 2 /* connect() succeeded or failed. int *  */\n#define MG_EV_RECV 3    /* Data has benn received. int *num_bytes */\n#define MG_EV_SEND 4    /* Data has been written to a socket. int *num_bytes */\n#define MG_EV_CLOSE 5   /* Connection is closed. NULL */\n#define MG_EV_TIMER 6   /* now >= conn->ev_timer_time. double * */\n\n/*\n * Mongoose event manager.\n */\nstruct mg_mgr {\n  struct mg_connection *active_connections;\n#if MG_ENABLE_HEXDUMP\n  const char *hexdump_file; /* Debug hexdump file path */\n#endif\n#if MG_ENABLE_BROADCAST\n  sock_t ctl[2]; /* Sockucnair for mg_broadcast() */\n#endif\n  void *user_data; /* User data */\n  int num_ifaces;\n  struct mg_iface **ifaces; /* network interfaces */\n#if MG_ENABLE_JAVASCRIPT\n  struct v7 *v7;\n#endif\n\n#if MG_ENABLE_MUTITHREADS\n  sock_t mthread_ctl[2];\n#endif\n};\n\n/*\n * Mongoose connection.\n */\nstruct mg_connection {\n  struct mg_connection *next, *prev; /* mg_mgr::active_connections linkage */\n  struct mg_connection *listener;    /* Set only for accept()-ed connections */\n  struct mg_mgr *mgr;                /* Pointer to containing manager */\n\n  sock_t sock; /* Socket to the remote peer */\n  int err;\n  union socket_address sa; /* Remote peer address */\n  size_t recv_mbuf_limit;  /* Max size of recv buffer */\n  struct mbuf recv_mbuf;   /* Received data */\n  struct mbuf send_mbuf;   /* Data scheduled for sending */\n  time_t last_io_time;     /* Timestamp of the last socket IO */\n  double ev_timer_time;    /* Timestamp of the future MG_EV_TIMER */\n#if MG_ENABLE_SSL\n  void *ssl_if_data; /* SSL library data. */\n#endif\n  mg_event_handler_t proto_handler; /* Protocol-specific event handler */\n  void *proto_data;                 /* Protocol-specific data */\n  void (*proto_data_destructor)(void *proto_data);\n  mg_event_handler_t handler; /* Event handler function */\n  void *user_data;            /* User-specific data */\n  union {\n    void *v;\n    /*\n     * the C standard is fussy about fitting function pointers into\n     * void pointers, since some archs might have fat pointers for functions.\n     */\n    mg_event_handler_t f;\n  } priv_1;       /* Used by mg_enable_multithreading() */\n  void *priv_2;   /* Used by mg_enable_multithreading() */\n  void *mgr_data; /* Implementation-specific event manager's data. */\n  struct mg_iface *iface;\n  unsigned long flags;\n/* Flags set by Mongoose */\n#define MG_F_LISTENING (1 << 0)          /* This connection is listening */\n#define MG_F_UDP (1 << 1)                /* This connection is UDP */\n#define MG_F_RESOLVING (1 << 2)          /* Waiting for async resolver */\n#define MG_F_CONNECTING (1 << 3)         /* connect() call in progress */\n#define MG_F_SSL (1 << 4)                /* SSL is enabled on the connection */\n#define MG_F_SSL_HANDSHAKE_DONE (1 << 5) /* SSL hanshake has completed */\n#define MG_F_WANT_READ (1 << 6)          /* SSL specific */\n#define MG_F_WANT_WRITE (1 << 7)         /* SSL specific */\n#define MG_F_IS_WEBSOCKET (1 << 8)       /* Websocket specific */\n\n/* Flags that are settable by user */\n#define MG_F_SEND_AND_CLOSE (1 << 10)      /* Push remaining data and close  */\n#define MG_F_CLOSE_IMMEDIATELY (1 << 11)   /* Disconnect */\n#define MG_F_WEBSOCKET_NO_DEFRAG (1 << 12) /* Websocket specific */\n#define MG_F_DELETE_CHUNK (1 << 13)        /* HTTP specific */\n#define MG_F_ENABLE_BROADCAST (1 << 14)    /* Allow broadcast address usage */\n\n#define MG_F_USER_1 (1 << 20) /* Flags left for application */\n#define MG_F_USER_2 (1 << 21)\n#define MG_F_USER_3 (1 << 22)\n#define MG_F_USER_4 (1 << 23)\n#define MG_F_USER_5 (1 << 24)\n#define MG_F_USER_6 (1 << 25)\n};\n\n/*\n * Initialise Mongoose manager. Side effect: ignores SIGPIPE signal.\n * `mgr->user_data` field will be initialised with a `user_data` parameter.\n * That is an arbitrary pointer, where the user code can associate some data\n * with the particular Mongoose manager. For example, a C++ wrapper class\n * could be written in which case `user_data` can hold a pointer to the\n * class instance.\n */\nvoid mg_mgr_init(struct mg_mgr *mgr, void *user_data);\n\nvoid mg_add_conn(struct mg_mgr *mgr, struct mg_connection *c);\nvoid mg_remove_conn(struct mg_connection *conn);\n\n\n/*\n * Optional parameters to `mg_mgr_init_opt()`.\n *\n * If `main_iface` is not NULL, it will be used as the main interface in the\n * default interface set. The pointer will be free'd by `mg_mgr_free`.\n * Otherwise, the main interface will be autodetected based on the current\n * platform.\n *\n * If `num_ifaces` is 0 and `ifaces` is NULL, the default interface set will be\n * used.\n * This is an advanced option, as it requires you to construct a full interface\n * set, including special networking interfaces required by some optional\n * features such as TCP tunneling. Memory backing `ifaces` and each of the\n * `num_ifaces` pointers it contains will be reclaimed by `mg_mgr_free`.\n */\nstruct mg_mgr_init_opts {\n  struct mg_iface_vtable *main_iface;\n  int num_ifaces;\n  struct mg_iface_vtable **ifaces;\n};\n\n/*\n * Like `mg_mgr_init` but with more options.\n *\n * Notably, this allows you to create a manger and choose\n * dynamically which networking interface implementation to use.\n */\nvoid mg_mgr_init_opt(struct mg_mgr *mgr, void *user_data,\n                     struct mg_mgr_init_opts opts);\n\n/*\n * De-initialises Mongoose manager.\n *\n * Closes and deallocates all active connections.\n */\nvoid mg_mgr_free(struct mg_mgr *);\n\n/*\n * This function performs the actual IO and must be called in a loop\n * (an event loop). It returns the current timestamp.\n * `milli` is the maximum number of milliseconds to sleep.\n * `mg_mgr_poll()` checks all connections for IO readiness. If at least one\n * of the connections is IO-ready, `mg_mgr_poll()` triggers the respective\n * event handlers and returns.\n */\ntime_t mg_mgr_poll(struct mg_mgr *, int milli);\n\n#if MG_ENABLE_BROADCAST\n/*\n * Passes a message of a given length to all connections.\n *\n * Must be called from a thread that does NOT call `mg_mgr_poll()`.\n * Note that `mg_broadcast()` is the only function\n * that can be, and must be, called from a different (non-IO) thread.\n *\n * `func` callback function will be called by the IO thread for each\n * connection. When called, the event will be `MG_EV_POLL`, and a message will\n * be passed as the `ev_data` pointer. Maximum message size is capped\n * by `MG_CTL_MSG_MESSAGE_SIZE` which is set to 8192 bytes.\n */\nvoid mg_broadcast(struct mg_mgr *, mg_event_handler_t func, void *, size_t);\n#endif\n\n/*\n * Iterates over all active connections.\n *\n * Returns the next connection from the list\n * of active connections or `NULL` if there are no more connections. Below\n * is the iteration idiom:\n *\n * ```c\n * for (c = mg_next(srv, NULL); c != NULL; c = mg_next(srv, c)) {\n *   // Do something with connection `c`\n * }\n * ```\n */\nstruct mg_connection *mg_next(struct mg_mgr *, struct mg_connection *);\n\n/*\n * Optional parameters to `mg_add_sock_opt()`.\n *\n * `flags` is an initial `struct mg_connection::flags` bitmask to set,\n * see `MG_F_*` flags definitions.\n */\nstruct mg_add_sock_opts {\n  void *user_data;           /* Initial value for connection's user_data */\n  unsigned int flags;        /* Initial connection flags */\n  const char **error_string; /* Placeholder for the error string */\n  struct mg_iface *iface;    /* Interface instance */\n};\n\n/*\n * Creates a connection, associates it with the given socket and event handler\n * and adds it to the manager.\n *\n * For more options see the `mg_add_sock_opt` variant.\n */\nstruct mg_connection *mg_add_sock(struct mg_mgr *, sock_t, mg_event_handler_t);\n\n/*\n * Creates a connection, associates it with the given socket and event handler\n * and adds to the manager.\n *\n * See the `mg_add_sock_opts` structure for a description of the options.\n */\nstruct mg_connection *mg_add_sock_opt(struct mg_mgr *, sock_t,\n                                      mg_event_handler_t,\n                                      struct mg_add_sock_opts);\n\n/*\n * Optional parameters to `mg_bind_opt()`.\n *\n * `flags` is an initial `struct mg_connection::flags` bitmask to set,\n * see `MG_F_*` flags definitions.\n */\nstruct mg_bind_opts {\n  void *user_data;           /* Initial value for connection's user_data */\n  unsigned int flags;        /* Extra connection flags */\n  const char **error_string; /* Placeholder for the error string */\n  struct mg_iface *iface;    /* Interface instance */\n#if MG_ENABLE_SSL\n  /* SSL settings. */\n  const char *ssl_cert;    /* Server certificate to present to clients\n                            * Or client certificate to present to tunnel\n                            * dispatcher. */\n  const char *ssl_key;     /* Private key corresponding to the certificate.\n                              If ssl_cert is set but ssl_key is not, ssl_cert\n                              is used. */\n  const char *ssl_ca_cert; /* CA bundle used to verify client certificates or\n                            * tunnel dispatchers. */\n#endif\n};\n\n/*\n * Creates a listening connection.\n *\n * See `mg_bind_opt` for full documentation.\n */\nstruct mg_connection *mg_bind(struct mg_mgr *, const char *,\n                              mg_event_handler_t);\n/*\n * Creates a listening connection.\n *\n * The `address` parameter specifies which address to bind to. It's format is\n * the same as for the `mg_connect()` call, where `HOST` part is optional.\n * `address` can be just a port number, e.g. `:8000`. To bind to a specific\n * interface, an IP address can be specified, e.g. `1.2.3.4:8000`. By default,\n * a TCP connection is created. To create UDP connection, prepend `udp://`\n * prefix, e.g. `udp://:8000`. To summarize, `address` paramer has following\n * format: `[PROTO://][IP_ADDRESS]:PORT`, where `PROTO` could be `tcp` or\n * `udp`.\n *\n * See the `mg_bind_opts` structure for a description of the optional\n * parameters.\n *\n * Returns a new listening connection or `NULL` on error.\n * NOTE: The connection remains owned by the manager, do not free().\n */\nstruct mg_connection *mg_bind_opt(struct mg_mgr *mgr, const char *address,\n                                  mg_event_handler_t handler,\n                                  struct mg_bind_opts opts);\n\n/* Optional parameters to `mg_connect_opt()` */\nstruct mg_connect_opts {\n  void *user_data;           /* Initial value for connection's user_data */\n  unsigned int flags;        /* Extra connection flags */\n  const char **error_string; /* Placeholder for the error string */\n  struct mg_iface *iface;    /* Interface instance */\n#if MG_ENABLE_SSL\n  /* SSL settings. */\n  const char *ssl_cert;    /* Client certificate to present to the server */\n  const char *ssl_key;     /* Private key corresponding to the certificate.\n                              If ssl_cert is set but ssl_key is not, ssl_cert\n                              is used. */\n  const char *ssl_ca_cert; /* Verify server certificate using this CA bundle.\n                              If set to \"*\", then SSL is enabled but no cert\n                              verification is performed. */\n\n  /*\n   * Server name verification. If ssl_ca_cert is set and the certificate has\n   * passed verification, its subject will be verified against this string.\n   * By default (if ssl_server_name is NULL) hostname part of the address will\n   * be used. Wildcard matching is supported. A special value of \"*\" disables\n   * name verification.\n   */\n  const char *ssl_server_name;\n#endif\n};\n\n/*\n * Connects to a remote host.\n *\n * See `mg_connect_opt()` for full documentation.\n */\nstruct mg_connection *mg_connect(struct mg_mgr *mgr, const char *address,\n                                 mg_event_handler_t handler);\n\n/*\n * Connects to a remote host.\n *\n * The `address` format is `[PROTO://]HOST:PORT`. `PROTO` could be `tcp` or\n * `udp`. `HOST` could be an IP address,\n * IPv6 address (if Mongoose is compiled with `-DMG_ENABLE_IPV6`) or a host\n * name. If `HOST` is a name, Mongoose will resolve it asynchronously. Examples\n * of valid addresses: `google.com:80`, `udp://1.2.3.4:53`, `10.0.0.1:443`,\n * `[::1]:80`\n *\n * See the `mg_connect_opts` structure for a description of the optional\n * parameters.\n *\n * Returns a new outbound connection or `NULL` on error.\n *\n * NOTE: The connection remains owned by the manager, do not free().\n *\n * NOTE: To enable IPv6 addresses `-DMG_ENABLE_IPV6` should be specified\n * in the compilation flags.\n *\n * NOTE: The new connection will receive `MG_EV_CONNECT` as its first event\n * which will report the connect success status.\n * If the asynchronous resolution fails or the `connect()` syscall fails for\n * whatever reason (e.g. with `ECONNREFUSED` or `ENETUNREACH`), then\n * `MG_EV_CONNECT` event will report failure. Code example below:\n *\n * ```c\n * static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {\n *   int connect_status;\n *\n *   switch (ev) {\n *     case MG_EV_CONNECT:\n *       connect_status = * (int *) ev_data;\n *       if (connect_status == 0) {\n *         // Success\n *       } else  {\n *         // Error\n *         printf(\"connect() error: %s\\n\", strerror(connect_status));\n *       }\n *       break;\n *     ...\n *   }\n * }\n *\n *   ...\n *   mg_connect(mgr, \"my_site.com:80\", ev_handler);\n * ```\n */\nstruct mg_connection *mg_connect_opt(struct mg_mgr *mgr, const char *address,\n                                     mg_event_handler_t handler,\n                                     struct mg_connect_opts opts);\n\n#if MG_ENABLE_SSL && MG_NET_IF != MG_NET_IF_SIMPLELINK\n/*\n * Note: This function is deprecated. Please, use SSL options in\n * mg_connect_opt.\n *\n * Enables SSL for a given connection.\n * `cert` is a server certificate file name for a listening connection\n * or a client certificate file name for an outgoing connection.\n * The certificate files must be in PEM format. The server certificate file\n * must contain a certificate, concatenated with a private key, optionally\n * concatenated with DH parameters.\n * `ca_cert` is a CA certificate or NULL if peer verification is not\n * required.\n * Return: NULL on success or error message on error.\n */\nconst char *mg_set_ssl(struct mg_connection *nc, const char *cert,\n                       const char *ca_cert);\n#endif\n\n/*\n * Sends data to the connection.\n *\n * Note that sending functions do not actually push data to the socket.\n * They just append data to the output buffer. MG_EV_SEND will be delivered when\n * the data has actually been pushed out.\n */\nvoid mg_send(struct mg_connection *, const void *buf, int len);\n\n/* Enables format string warnings for mg_printf */\n#if defined(__GNUC__)\n__attribute__((format(printf, 2, 3)))\n#endif\n/* don't separate from mg_printf declaration */\n\n/*\n * Sends `printf`-style formatted data to the connection.\n *\n * See `mg_send` for more details on send semantics.\n */\nint mg_printf(struct mg_connection *, const char *fmt, ...);\n\n/* Same as `mg_printf()`, but takes `va_list ap` as an argument. */\nint mg_vprintf(struct mg_connection *, const char *fmt, va_list ap);\n\n/*\n * Creates a socket pair.\n * `sock_type` can be either `SOCK_STREAM` or `SOCK_DGRAM`.\n * Returns 0 on failure and 1 on success.\n */\nint mg_sockucnair(sock_t[2], int sock_type);\n\n#if MG_ENABLE_SYNC_RESOLVER\n/*\n * Convert domain name into IP address.\n *\n * This is a utility function. If compilation flags have\n * `-DMG_ENABLE_GETADDRINFO`, then `getaddrinfo()` call is used for name\n * resolution. Otherwise, `gethostbyname()` is used.\n *\n * CAUTION: this function can block.\n * Return 1 on success, 0 on failure.\n */\nint mg_resolve(const char *domain_name, char *ip_addr_buf, size_t buf_len);\n#endif\n\n/*\n * Verify given IP address against the ACL.\n *\n * `remote_ip` - an IPv4 address to check, in host byte order\n * `acl` - a comma separated list of IP subnets: `x.x.x.x/x` or `x.x.x.x`.\n * Each subnet is\n * prepended by either a - or a + sign. A plus sign means allow, where a\n * minus sign means deny. If a subnet mask is omitted, such as `-1.2.3.4`,\n * it means that only that single IP address is denied.\n * Subnet masks may vary from 0 to 32, inclusive. The default setting\n * is to allow all access. On each request the full list is traversed,\n * and the last match wins. Example:\n *\n * `-0.0.0.0/0,+192.168/16` - deny all acccesses, only allow 192.168/16 subnet\n *\n * To learn more about subnet masks, see this\n * link:https://en.wikipedia.org/wiki/Subnetwork[Wikipedia page on Subnetwork].\n *\n * Returns -1 if ACL is malformed, 0 if address is disallowed, 1 if allowed.\n */\nint mg_check_ip_acl(const char *acl, uint32_t remote_ip);\n\n/*\n * Optional parameters for mg_enable_multithreading_opt()\n */\nstruct mg_multithreading_opts {\n  int poll_timeout; /* Polling interval */\n};\n\n/*\n * Enables multi-threaded handling for the given listening connection `nc`.\n * For each accepted connection, Mongoose will create a separate thread\n * and run an event handler in that thread. Thus, if an event handler is doing\n * a blocking call or some long computation, it will not slow down\n * other connections.\n */\nvoid mg_enable_multithreading(struct mg_connection *nc);\nvoid mg_enable_multithreading_opt(struct mg_connection *nc,\n                                  struct mg_multithreading_opts opts);\n\n#if MG_ENABLE_JAVASCRIPT\n/*\n * Enables server-side JavaScript scripting.\n * Requires a `-DMG_ENABLE_JAVASCRIPT` compilation flag and V7 engine sources.\n * V7 instance must not be destroyed during manager's lifetime.\n * Returns a V7 error.\n */\nenum v7_err mg_enable_javascript(struct mg_mgr *m, struct v7 *v7,\n                                 const char *init_js_file_name);\n#endif\n\n/*\n * Schedules an MG_EV_TIMER event to be delivered at `timestamp` time.\n * `timestamp` is UNIX time (the number of seconds since Epoch). It is\n * `double` instead of `time_t` to allow for sub-second precision.\n * Returns the old timer value.\n *\n * Example: set the connect timeout to 1.5 seconds:\n *\n * ```\n *  c = mg_connect(&mgr, \"cesanta.com\", ev_handler);\n *  mg_set_timer(c, mg_time() + 1.5);\n *  ...\n *\n *  void ev_handler(struct mg_connection *c, int ev, void *ev_data) {\n *  switch (ev) {\n *    case MG_EV_CONNECT:\n *      mg_set_timer(c, 0);  // Clear connect timer\n *      break;\n *    case MG_EV_TIMER:\n *      log(\"Connect timeout\");\n *      c->flags |= MG_F_CLOSE_IMMEDIATELY;\n *      break;\n * ```\n */\ndouble mg_set_timer(struct mg_connection *c, double timestamp);\n\n/*\n * A sub-second precision version of time().\n */\ndouble mg_time(void);\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif /* CS_MONGOOSE_SRC_NET_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/uri.h\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n */\n\n/*\n * === URI\n */\n\n#ifndef CS_MONGOOSE_SRC_URI_H_\n#define CS_MONGOOSE_SRC_URI_H_\n\n/* Amalgamated: #include \"mongoose/src/net.h\" */\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*\n * Parses an URI and fills string chunks with locations of the respective\n * uri components within the input uri string. NULL pointers will be\n * ignored.\n *\n * General syntax:\n *\n *     [scheme://[user_info@]]host[:port][/path][?query][#fragment]\n *\n * Example:\n *\n *     foo.com:80\n *     tcp://foo.com:1234\n *     http://foo.com:80/bar?baz=1\n *     https://user:pw@foo.com:443/blah\n *\n * `path` will include the leading slash. `query` won't include the leading `?`.\n * `host` can contain embedded colons if surrounded by square brackets in order\n * to support IPv6 literal addresses.\n *\n *\n * Returns 0 on success, -1 on error.\n */\nint mg_parse_uri(struct mg_str uri, struct mg_str *scheme,\n                 struct mg_str *user_info, struct mg_str *host,\n                 unsigned int *port, struct mg_str *path, struct mg_str *query,\n                 struct mg_str *fragment);\n\nint mg_normalize_uri_path(const struct mg_str *in, struct mg_str *out);\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n#endif /* CS_MONGOOSE_SRC_URI_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/util.h\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n */\n\n/*\n * === Utility API\n */\n\n#ifndef CS_MONGOOSE_SRC_UTIL_H_\n#define CS_MONGOOSE_SRC_UTIL_H_\n\n#include <stdio.h>\n\n/* Amalgamated: #include \"mongoose/src/common.h\" */\n/* Amalgamated: #include \"mongoose/src/net_if.h\" */\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n#ifndef MAX_PATH_SIZE\n#define MAX_PATH_SIZE 500\n#endif\n\n/*\n * Fetches substring from input string `s`, `end` into `v`.\n * Skips initial delimiter characters. Records first non-delimiter character\n * at the beginning of substring `v`. Then scans the rest of the string\n * until a delimiter character or end-of-string is found.\n * `delimiters` is a 0-terminated string containing delimiter characters.\n * Either one of `delimiters` or `end_string` terminates the search.\n * Returns an `s` pointer, advanced forward where parsing has stopped.\n */\nconst char *mg_skip(const char *s, const char *end_string,\n                    const char *delimiters, struct mg_str *v);\n\n/*\n * Decodes base64-encoded string `s`, `len` into the destination `dst`.\n * The destination has to have enough space to hold the decoded buffer.\n * Decoding stops either when all strings have been decoded or invalid an\n * character appeared.\n * Destination is '\\0'-terminated.\n * Returns the number of decoded characters. On success, that should be equal\n * to `len`. On error (invalid character) the return value is smaller then\n * `len`.\n */\nint mg_base64_decode(const unsigned char *s, int len, char *dst);\n\n/*\n * Base64-encode chunk of memory `src`, `src_len` into the destination `dst`.\n * Destination has to have enough space to hold encoded buffer.\n * Destination is '\\0'-terminated.\n */\nvoid mg_base64_encode(const unsigned char *src, int src_len, char *dst);\n\n#if MG_ENABLE_FILESYSTEM\n/*\n * Performs a 64-bit `stat()` call against a given file.\n *\n * `path` should be UTF8 encoded.\n *\n * Return value is the same as for `stat()` syscall.\n */\nint mg_stat(const char *path, cs_stat_t *st);\n\n/*\n * Opens the given file and returns a file stream.\n *\n * `path` and `mode` should be UTF8 encoded.\n *\n * Return value is the same as for the `fopen()` call.\n */\nFILE *mg_fopen(const char *path, const char *mode);\n\n/*\n * Opens the given file and returns a file stream.\n *\n * `path` should be UTF8 encoded.\n *\n * Return value is the same as for the `open()` syscall.\n */\nint mg_open(const char *path, int flag, int mode);\n#endif /* MG_ENABLE_FILESYSTEM */\n\n#if MG_ENABLE_THREADS\n/*\n * Starts a new detached thread.\n * Arguments and semantics are the same as pthead's `pthread_create()`.\n * `thread_func` is a thread function, `thread_func_param` is a parameter\n * that is passed to the thread function.\n */\nvoid *mg_start_thread(void *(*thread_func)(void *), void *thread_func_param);\n#endif\n\nvoid mg_set_close_on_exec(sock_t);\n\n#define MG_SOCK_STRINGIFY_IP 1\n#define MG_SOCK_STRINGIFY_PORT 2\n#define MG_SOCK_STRINGIFY_REMOTE 4\n/*\n * Converts a connection's local or remote address into string.\n *\n * The `flags` parameter is a bit mask that controls the behaviour,\n * see `MG_SOCK_STRINGIFY_*` definitions.\n *\n * - MG_SOCK_STRINGIFY_IP - print IP address\n * - MG_SOCK_STRINGIFY_PORT - print port number\n * - MG_SOCK_STRINGIFY_REMOTE - print remote peer's IP/port, not local address\n *\n * If both port number and IP address are printed, they are separated by `:`.\n * If compiled with `-DMG_ENABLE_IPV6`, IPv6 addresses are supported.\n */\nvoid mg_conn_addr_to_str(struct mg_connection *nc, char *buf, size_t len,\n                         int flags);\n#if MG_NET_IF == MG_NET_IF_SOCKET\n/* Legacy interface. */\nvoid mg_sock_to_str(sock_t sock, char *buf, size_t len, int flags);\n#endif\n\n/*\n * Convert the socket's address into string.\n *\n * `flags` is MG_SOCK_STRINGIFY_IP and/or MG_SOCK_STRINGIFY_PORT.\n */\nvoid mg_sock_addr_to_str(const union socket_address *sa, char *buf, size_t len,\n                         int flags);\n\n#if MG_ENABLE_HEXDUMP\n/*\n * Generates a human-readable hexdump of memory chunk.\n *\n * Takes a memory buffer `buf` of length `len` and creates a hex dump of that\n * buffer in `dst`. The generated output is a-la hexdump(1).\n * Returns the length of generated string, excluding terminating `\\0`. If\n * returned length is bigger than `dst_len`, the overflow bytes are discarded.\n */\nint mg_hexdump(const void *buf, int len, char *dst, int dst_len);\n\n/*\n * Generates human-readable hexdump of the data sent or received by the\n * connection. `path` is a file name where hexdump should be written.\n * `num_bytes` is a number of bytes sent/received. `ev` is one of the `MG_*`\n * events sent to an event handler. This function is supposed to be called from\n * the event handler.\n */\nvoid mg_hexdump_connection(struct mg_connection *nc, const char *path,\n                           const void *buf, int num_bytes, int ev);\n#endif\n\n/*\n * Returns true if target platform is big endian.\n */\nint mg_is_big_endian(void);\n\n/*\n * A helper function for traversing a comma separated list of values.\n * It returns a list pointer shifted to the next value or NULL if the end\n * of the list found.\n * The value is stored in a val vector. If the value has a form \"x=y\", then\n * eq_val vector is initialised to point to the \"y\" part, and val vector length\n * is adjusted to point only to \"x\".\n * If the list is just a comma separated list of entries, like \"aa,bb,cc\" then\n * `eq_val` will contain zero-length string.\n *\n * The purpose of this function is to parse comma separated string without\n * any copying/memory allocation.\n */\nconst char *mg_next_comma_list_entry(const char *list, struct mg_str *val,\n                                     struct mg_str *eq_val);\n\n/*\n * Matches 0-terminated string (mg_match_prefix) or string with given length\n * mg_match_prefix_n against a glob pattern.\n *\n * Match is case-insensitive. Returns number of bytes matched, or -1 if no\n * match.\n */\nint mg_match_prefix(const char *pattern, int pattern_len, const char *str);\nint mg_match_prefix_n(const struct mg_str pattern, const struct mg_str str);\n\n/*\n * Use with cs_base64_init/update/finish in order to write out base64 in chunks.\n */\nvoid mg_mbuf_append_base64_putc(char ch, void *user_data);\n\n/*\n * Encode `len` bytes starting at `data` as base64 and append them to an mbuf.\n */\nvoid mg_mbuf_append_base64(struct mbuf *mbuf, const void *data, size_t len);\n\n/*\n * Generate a Basic Auth header and appends it to buf.\n * If pass is NULL, then user is expected to contain the credentials pair\n * already encoded as `user:pass`.\n */\nvoid mg_basic_auth_header(const char *user, const char *pass, struct mbuf *buf);\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n#endif /* CS_MONGOOSE_SRC_UTIL_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/http.h\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n */\n\n/*\n * === Common API reference\n */\n\n#ifndef CS_MONGOOSE_SRC_HTTP_H_\n#define CS_MONGOOSE_SRC_HTTP_H_\n\n#if MG_ENABLE_HTTP\n\n/* Amalgamated: #include \"mongoose/src/net.h\" */\n/* Amalgamated: #include \"common/mg_str.h\" */\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n#ifndef MG_MAX_HTTP_HEADERS\n#define MG_MAX_HTTP_HEADERS 20\n#endif\n\n#ifndef MG_MAX_HTTP_REQUEST_SIZE\n#define MG_MAX_HTTP_REQUEST_SIZE 1024\n#endif\n\n#ifndef MG_MAX_PATH\n#ifdef PATH_MAX\n#define MG_MAX_PATH PATH_MAX\n#else\n#define MG_MAX_PATH 256\n#endif\n#endif\n\n#ifndef MG_MAX_HTTP_SEND_MBUF\n#define MG_MAX_HTTP_SEND_MBUF 1024\n#endif\n\n#ifndef MG_CGI_ENVIRONMENT_SIZE\n#define MG_CGI_ENVIRONMENT_SIZE 8192\n#endif\n\n/* HTTP message */\nstruct http_message {\n  struct mg_str message; /* Whole message: request line + headers + body */\n\n  /* HTTP Request line (or HTTP response line) */\n  struct mg_str method; /* \"GET\" */\n  struct mg_str uri;    /* \"/my_file.html\" */\n  struct mg_str proto;  /* \"HTTP/1.1\" -- for both request and response */\n\n  /* For responses, code and response status message are set */\n  int resp_code;\n  struct mg_str resp_status_msg;\n\n  /*\n   * Query-string part of the URI. For example, for HTTP request\n   *    GET /foo/bar?param1=val1&param2=val2\n   *    |    uri    |     query_string     |\n   *\n   * Note that question mark character doesn't belong neither to the uri,\n   * nor to the query_string\n   */\n  struct mg_str query_string;\n\n  /* Headers */\n  struct mg_str header_names[MG_MAX_HTTP_HEADERS];\n  struct mg_str header_values[MG_MAX_HTTP_HEADERS];\n\n  /* Message body */\n  struct mg_str body; /* Zero-length for requests with no body */\n};\n\n#if MG_ENABLE_HTTP_WEBSOCKET\n/* WebSocket message */\nstruct websocket_message {\n  unsigned char *data;\n  size_t size;\n  unsigned char flags;\n};\n#endif\n\n/* HTTP multipart part */\nstruct mg_http_multipart_part {\n  const char *file_name;\n  const char *var_name;\n  struct mg_str data;\n  int status; /* <0 on error */\n  void *user_data;\n};\n\n/* SSI call context */\nstruct mg_ssi_call_ctx {\n  struct http_message *req; /* The request being processed. */\n  struct mg_str file;       /* Filesystem path of the file being processed. */\n  struct mg_str arg; /* The argument passed to the tag: <!-- call arg -->. */\n};\n\n/* HTTP and websocket events. void *ev_data is described in a comment. */\n#define MG_EV_HTTP_REQUEST 100 /* struct http_message * */\n#define MG_EV_HTTP_REPLY 101   /* struct http_message * */\n#define MG_EV_HTTP_CHUNK 102   /* struct http_message * */\n#define MG_EV_SSI_CALL 105     /* char * */\n#define MG_EV_SSI_CALL_CTX 106 /* struct mg_ssi_call_ctx * */\n\n#if MG_ENABLE_HTTP_WEBSOCKET\n#define MG_EV_WEBSOCKET_HANDSHAKE_REQUEST 111 /* struct http_message * */\n#define MG_EV_WEBSOCKET_HANDSHAKE_DONE 112    /* NULL */\n#define MG_EV_WEBSOCKET_FRAME 113             /* struct websocket_message * */\n#define MG_EV_WEBSOCKET_CONTROL_FRAME 114     /* struct websocket_message * */\n#endif\n\n#if MG_ENABLE_HTTP_STREAMING_MULTIPART\n#define MG_EV_HTTP_MULTIPART_REQUEST 121 /* struct http_message */\n#define MG_EV_HTTP_PART_BEGIN 122        /* struct mg_http_multipart_part */\n#define MG_EV_HTTP_PART_DATA 123         /* struct mg_http_multipart_part */\n#define MG_EV_HTTP_PART_END 124          /* struct mg_http_multipart_part */\n/* struct mg_http_multipart_part */\n#define MG_EV_HTTP_MULTIPART_REQUEST_END 125\n#endif\n\n/*\n * Attaches a built-in HTTP event handler to the given connection.\n * The user-defined event handler will receive following extra events:\n *\n * - MG_EV_HTTP_REQUEST: HTTP request has arrived. Parsed HTTP request\n *  is passed as\n *   `struct http_message` through the handler's `void *ev_data` pointer.\n * - MG_EV_HTTP_REPLY: The HTTP reply has arrived. The parsed HTTP reply is\n *   passed as `struct http_message` through the handler's `void *ev_data`\n *   pointer.\n * - MG_EV_HTTP_CHUNK: The HTTP chunked-encoding chunk has arrived.\n *   The parsed HTTP reply is passed as `struct http_message` through the\n *   handler's `void *ev_data` pointer. `http_message::body` would contain\n *   incomplete, reassembled HTTP body.\n *   It will grow with every new chunk that arrives, and it can\n *   potentially consume a lot of memory. An event handler may process\n *   the body as chunks are coming, and signal Mongoose to delete processed\n *   body by setting `MG_F_DELETE_CHUNK` in `mg_connection::flags`. When\n *   the last zero chunk is received,\n *   Mongoose sends `MG_EV_HTTP_REPLY` event with\n *   full reassembled body (if handler did not signal to delete chunks) or\n *   with empty body (if handler did signal to delete chunks).\n * - MG_EV_WEBSOCKET_HANDSHAKE_REQUEST: server has received the WebSocket\n *   handshake request. `ev_data` contains parsed HTTP request.\n * - MG_EV_WEBSOCKET_HANDSHAKE_DONE: server has completed the WebSocket\n *   handshake. `ev_data` is `NULL`.\n * - MG_EV_WEBSOCKET_FRAME: new WebSocket frame has arrived. `ev_data` is\n *   `struct websocket_message *`\n *\n * When compiled with MG_ENABLE_HTTP_STREAMING_MULTIPART, Mongoose parses\n * multipart requests and splits them into separate events:\n * - MG_EV_HTTP_MULTIPART_REQUEST: Start of the request.\n *   This event is sent before body is parsed. After this, the user\n *   should expect a sequence of PART_BEGIN/DATA/END requests.\n *   This is also the last time when headers and other request fields are\n *   accessible.\n * - MG_EV_HTTP_PART_BEGIN: Start of a part of a multipart message.\n *   Argument: mg_http_multipart_part with var_name and file_name set\n *   (if present). No data is passed in this message.\n * - MG_EV_HTTP_PART_DATA: new portion of data from the multipart message.\n *   Argument: mg_http_multipart_part. var_name and file_name are preserved,\n *   data is available in mg_http_multipart_part.data.\n * - MG_EV_HTTP_PART_END: End of the current part. var_name, file_name are\n *   the same, no data in the message. If status is 0, then the part is\n *   properly terminated with a boundary, status < 0 means that connection\n *   was terminated.\n * - MG_EV_HTTP_MULTIPART_REQUEST_END: End of the multipart request.\n *   Argument: mg_http_multipart_part, var_name and file_name are NULL,\n *   status = 0 means request was properly closed, < 0 means connection\n *   was terminated (note: in this case both PART_END and REQUEST_END are\n *   delivered).\n */\nvoid mg_set_protocol_http_websocket(struct mg_connection *nc);\n\n#if MG_ENABLE_HTTP_WEBSOCKET\n/*\n * Send websocket handshake to the server.\n *\n * `nc` must be a valid connection, connected to a server. `uri` is an URI\n * to fetch, extra_headers` is extra HTTP headers to send or `NULL`.\n *\n * This function is intended to be used by websocket client.\n *\n * Note that the Host header is mandatory in HTTP/1.1 and must be\n * included in `extra_headers`. `mg_send_websocket_handshake2` offers\n * a better API for that.\n *\n * Deprecated in favour of `mg_send_websocket_handshake2`\n */\nvoid mg_send_websocket_handshake(struct mg_connection *nc, const char *uri,\n                                 const char *extra_headers);\n\n/*\n * Send websocket handshake to the server.\n *\n * `nc` must be a valid connection, connected to a server. `uri` is an URI\n * to fetch, `host` goes into the `Host` header, `protocol` goes into the\n * `Sec-WebSocket-Proto` header (NULL to omit), extra_headers` is extra HTTP\n * headers to send or `NULL`.\n *\n * This function is intended to be used by websocket client.\n */\nvoid mg_send_websocket_handshake2(struct mg_connection *nc, const char *path,\n                                  const char *host, const char *protocol,\n                                  const char *extra_headers);\n\n/* Like mg_send_websocket_handshake2 but also passes basic auth header */\nvoid mg_send_websocket_handshake3(struct mg_connection *nc, const char *path,\n                                  const char *host, const char *protocol,\n                                  const char *extra_headers, const char *user,\n                                  const char *pass);\n/*\n * Helper function that creates an outbound WebSocket connection.\n *\n * `url` is a URL to connect to. It must be properly URL-encoded, e.g. have\n * no spaces, etc. By default, `mg_connect_ws()` sends Connection and\n * Host headers. `extra_headers` is an extra HTTP header to send, e.g.\n * `\"User-Agent: my-app\\r\\n\"`.\n * If `protocol` is not NULL, then a `Sec-WebSocket-Protocol` header is sent.\n *\n * Examples:\n *\n * ```c\n *   nc1 = mg_connect_ws(mgr, ev_handler_1, \"ws://echo.websocket.org\", NULL,\n *                       NULL);\n *   nc2 = mg_connect_ws(mgr, ev_handler_1, \"wss://echo.websocket.org\", NULL,\n *                       NULL);\n *   nc3 = mg_connect_ws(mgr, ev_handler_1, \"ws://api.cesanta.com\",\n *                       \"clubby.cesanta.com\", NULL);\n * ```\n */\nstruct mg_connection *mg_connect_ws(struct mg_mgr *mgr,\n                                    mg_event_handler_t event_handler,\n                                    const char *url, const char *protocol,\n                                    const char *extra_headers);\n\n/*\n * Helper function that creates an outbound WebSocket connection\n *\n * Mostly identical to `mg_connect_ws`, but allows to provide extra parameters\n * (for example, SSL parameters)\n */\nstruct mg_connection *mg_connect_ws_opt(struct mg_mgr *mgr,\n                                        mg_event_handler_t ev_handler,\n                                        struct mg_connect_opts opts,\n                                        const char *url, const char *protocol,\n                                        const char *extra_headers);\n\n/*\n * Send WebSocket frame to the remote end.\n *\n * `op_and_flags` specifies the frame's type. It's one of:\n *\n * - WEBSOCKET_OP_CONTINUE\n * - WEBSOCKET_OP_TEXT\n * - WEBSOCKET_OP_BINARY\n * - WEBSOCKET_OP_CLOSE\n * - WEBSOCKET_OP_PING\n * - WEBSOCKET_OP_PONG\n *\n * Orred with one of the flags:\n *\n * - WEBSOCKET_DONT_FIN: Don't set the FIN flag on the frame to be sent.\n *\n * `data` and `data_len` contain frame data.\n */\nvoid mg_send_websocket_frame(struct mg_connection *nc, int op_and_flags,\n                             const void *data, size_t data_len);\n\n/*\n * Sends multiple websocket frames.\n *\n * Like `mg_send_websocket_frame()`, but composes a frame from multiple buffers.\n */\nvoid mg_send_websocket_framev(struct mg_connection *nc, int op_and_flags,\n                              const struct mg_str *strings, int num_strings);\n\n/*\n * Sends WebSocket frame to the remote end.\n *\n * Like `mg_send_websocket_frame()`, but allows to create formatted messages\n * with `printf()`-like semantics.\n */\nvoid mg_printf_websocket_frame(struct mg_connection *nc, int op_and_flags,\n                               const char *fmt, ...);\n\n/* Websocket opcodes, from http://tools.ietf.org/html/rfc6455 */\n#define WEBSOCKET_OP_CONTINUE 0\n#define WEBSOCKET_OP_TEXT 1\n#define WEBSOCKET_OP_BINARY 2\n#define WEBSOCKET_OP_CLOSE 8\n#define WEBSOCKET_OP_PING 9\n#define WEBSOCKET_OP_PONG 10\n\n/*\n * If set causes the FIN flag to not be set on outbound\n * frames. This enables sending multiple fragments of a single\n * logical message.\n *\n * The WebSocket protocol mandates that if the FIN flag of a data\n * frame is not set, the next frame must be a WEBSOCKET_OP_CONTINUE.\n * The last frame must have the FIN bit set.\n *\n * Note that mongoose will automatically defragment incoming messages,\n * so this flag is used only on outbound messages.\n */\n#define WEBSOCKET_DONT_FIN 0x100\n\n#endif /* MG_ENABLE_HTTP_WEBSOCKET */\n\n/*\n * Decodes a URL-encoded string.\n *\n * Source string is specified by (`src`, `src_len`), and destination is\n * (`dst`, `dst_len`). If `is_form_url_encoded` is non-zero, then\n * `+` character is decoded as a blank space character. This function\n * guarantees to NUL-terminate the destination. If destination is too small,\n * then the source string is partially decoded and `-1` is returned. Otherwise,\n * a length of the decoded string is returned, not counting final NUL.\n */\nint mg_url_decode(const char *src, int src_len, char *dst, int dst_len,\n                  int is_form_url_encoded);\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif /* MG_ENABLE_HTTP */\n\n#endif /* CS_MONGOOSE_SRC_HTTP_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/http_server.h\"\n#endif\n/*\n * === Server API reference\n */\n\n#ifndef CS_MONGOOSE_SRC_HTTP_SERVER_H_\n#define CS_MONGOOSE_SRC_HTTP_SERVER_H_\n\n#if MG_ENABLE_HTTP\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*\n * Parses a HTTP message.\n *\n * `is_req` should be set to 1 if parsing a request, 0 if reply.\n *\n * Returns the number of bytes parsed. If HTTP message is\n * incomplete `0` is returned. On parse error, a negative number is returned.\n */\nint mg_parse_http(const char *s, int n, struct http_message *hm, int is_req);\n\n/*\n * Searches and returns the header `name` in parsed HTTP message `hm`.\n * If header is not found, NULL is returned. Example:\n *\n *     struct mg_str *host_hdr = mg_get_http_header(hm, \"Host\");\n */\nstruct mg_str *mg_get_http_header(struct http_message *hm, const char *name);\n\n/*\n * Parses the HTTP header `hdr`. Finds variable `var_name` and stores its value\n * in the buffer `buf`, `buf_size`. Returns 0 if variable not found, non-zero\n * otherwise.\n *\n * This function is supposed to parse cookies, authentication headers, etc.\n * Example (error handling omitted):\n *\n *     char user[20];\n *     struct mg_str *hdr = mg_get_http_header(hm, \"Authorization\");\n *     mg_http_parse_header(hdr, \"username\", user, sizeof(user));\n *\n * Returns the length of the variable's value. If buffer is not large enough,\n * or variable not found, 0 is returned.\n */\nint mg_http_parse_header(struct mg_str *hdr, const char *var_name, char *buf,\n                         size_t buf_size);\n\n/*\n * Gets and parses the Authorization: Basic header\n * Returns -1 if no Authorization header is found, or if\n * mg_parse_http_basic_auth\n * fails parsing the resulting header.\n */\nint mg_get_http_basic_auth(struct http_message *hm, char *user, size_t user_len,\n                           char *pass, size_t pass_len);\n\n/*\n * Parses the Authorization: Basic header\n * Returns -1 iif the authorization type is not \"Basic\" or any other error such\n * as incorrectly encoded base64 user password pair.\n */\nint mg_parse_http_basic_auth(struct mg_str *hdr, char *user, size_t user_len,\n                             char *pass, size_t pass_len);\n\n/*\n * Parses the buffer `buf`, `buf_len` that contains multipart form data chunks.\n * Stores the chunk name in a `var_name`, `var_name_len` buffer.\n * If a chunk is an uploaded file, then `file_name`, `file_name_len` is\n * filled with an uploaded file name. `chunk`, `chunk_len`\n * points to the chunk data.\n *\n * Return: number of bytes to skip to the next chunk or 0 if there are\n *         no more chunks.\n *\n * Usage example:\n *\n * ```c\n *    static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {\n *      switch(ev) {\n *        case MG_EV_HTTP_REQUEST: {\n *          struct http_message *hm = (struct http_message *) ev_data;\n *          char var_name[100], file_name[100];\n *          const char *chunk;\n *          size_t chunk_len, n1, n2;\n *\n *          n1 = n2 = 0;\n *          while ((n2 = mg_parse_multipart(hm->body.p + n1,\n *                                          hm->body.len - n1,\n *                                          var_name, sizeof(var_name),\n *                                          file_name, sizeof(file_name),\n *                                          &chunk, &chunk_len)) > 0) {\n *            printf(\"var: %s, file_name: %s, size: %d, chunk: [%.*s]\\n\",\n *                   var_name, file_name, (int) chunk_len,\n *                   (int) chunk_len, chunk);\n *            n1 += n2;\n *          }\n *        }\n *        break;\n * ```\n */\nsize_t mg_parse_multipart(const char *buf, size_t buf_len, char *var_name,\n                          size_t var_name_len, char *file_name,\n                          size_t file_name_len, const char **chunk,\n                          size_t *chunk_len);\n\n/*\n * Fetches a HTTP form variable.\n *\n * Fetches a variable `name` from a `buf` into a buffer specified by `dst`,\n * `dst_len`. The destination is always zero-terminated. Returns the length of\n * a fetched variable. If not found, 0 is returned. `buf` must be valid\n * url-encoded buffer. If destination is too small, `-1` is returned.\n */\nint mg_get_http_var(const struct mg_str *buf, const char *name, char *dst,\n                    size_t dst_len);\n\n#if MG_ENABLE_FILESYSTEM\n/*\n * This structure defines how `mg_serve_http()` works.\n * Best practice is to set only required settings, and leave the rest as NULL.\n */\nstruct mg_serve_http_opts {\n  /* Path to web root directory */\n  const char *document_root;\n\n  /* List of index files. Default is \"\" */\n  const char *index_files;\n\n  /*\n   * Leave as NULL to disable authentication.\n   * To enable directory protection with authentication, set this to \".htpasswd\"\n   * Then, creating \".htpasswd\" file in any directory automatically protects\n   * it with digest authentication.\n   * Use `mongoose` web server binary, or `htdigest` Apache utility to\n   * create/manipulate passwords file.\n   * Make sure `auth_domain` is set to a valid domain name.\n   */\n  const char *per_directory_auth_file;\n\n  /* Authorization domain (domain name of this web server) */\n  const char *auth_domain;\n\n  /*\n   * Leave as NULL to disable authentication.\n   * Normally, only selected directories in the document root are protected.\n   * If absolutely every access to the web server needs to be authenticated,\n   * regardless of the URI, set this option to the path to the passwords file.\n   * Format of that file is the same as \".htpasswd\" file. Make sure that file\n   * is located outside document root to prevent people fetching it.\n   */\n  const char *global_auth_file;\n\n  /* Set to \"no\" to disable directory listing. Enabled by default. */\n  const char *enable_directory_listing;\n\n  /*\n   * SSI files pattern. If not set, \"**.shtml$|**.shtm$\" is used.\n   *\n   * All files that match ssi_pattern are treated as SSI.\n   *\n   * Server Side Includes (SSI) is a simple interpreted server-side scripting\n   * language which is most commonly used to include the contents of a file\n   * into a web page. It can be useful when it is desirable to include a common\n   * piece of code throughout a website, for example, headers and footers.\n   *\n   * In order for a webpage to recognize an SSI-enabled HTML file, the\n   * filename should end with a special extension, by default the extension\n   * should be either .shtml or .shtm\n   *\n   * Unknown SSI directives are silently ignored by Mongoose. Currently,\n   * the following SSI directives are supported:\n   *    &lt;!--#include FILE_TO_INCLUDE --&gt;\n   *    &lt;!--#exec \"COMMAND_TO_EXECUTE\" --&gt;\n   *    &lt;!--#call COMMAND --&gt;\n   *\n   * Note that &lt;!--#include ...> directive supports three path\n   *specifications:\n   *\n   * &lt;!--#include virtual=\"path\" --&gt;  Path is relative to web server root\n   * &lt;!--#include abspath=\"path\" --&gt;  Path is absolute or relative to the\n   *                                  web server working dir\n   * &lt;!--#include file=\"path\" --&gt;,    Path is relative to current document\n   * &lt;!--#include \"path\" --&gt;\n   *\n   * The include directive may be used to include the contents of a file or\n   * the result of running a CGI script.\n   *\n   * The exec directive is used to execute\n   * a command on a server, and show command's output. Example:\n   *\n   * &lt;!--#exec \"ls -l\" --&gt;\n   *\n   * The call directive is a way to invoke a C handler from the HTML page.\n   * On each occurence of &lt;!--#call COMMAND OPTIONAL_PARAMS> directive,\n   * Mongoose calls a registered event handler with MG_EV_SSI_CALL event,\n   * and event parameter will point to the COMMAND OPTIONAL_PARAMS string.\n   * An event handler can output any text, for example by calling\n   * `mg_printf()`. This is a flexible way of generating a web page on\n   * server side by calling a C event handler. Example:\n   *\n   * &lt;!--#call foo --&gt; ... &lt;!--#call bar --&gt;\n   *\n   * In the event handler:\n   *    case MG_EV_SSI_CALL: {\n   *      const char *param = (const char *) ev_data;\n   *      if (strcmp(param, \"foo\") == 0) {\n   *        mg_printf(c, \"hello from foo\");\n   *      } else if (strcmp(param, \"bar\") == 0) {\n   *        mg_printf(c, \"hello from bar\");\n   *      }\n   *      break;\n   *    }\n   */\n  const char *ssi_pattern;\n\n  /* IP ACL. By default, NULL, meaning all IPs are allowed to connect */\n  const char *ip_acl;\n\n#if MG_ENABLE_HTTP_URL_REWRITES\n  /* URL rewrites.\n   *\n   * Comma-separated list of `uri_pattern=url_file_or_directory_path` rewrites.\n   * When HTTP request is received, Mongoose constructs a file name from the\n   * requested URI by combining `document_root` and the URI. However, if the\n   * rewrite option is used and `uri_pattern` matches requested URI, then\n   * `document_root` is ignored. Instead, `url_file_or_directory_path` is used,\n   * which should be a full path name or a path relative to the web server's\n   * current working directory. It can also be an URI (http:// or https://)\n   * in which case mongoose will behave as a reverse proxy for that destination.\n   *\n   * Note that `uri_pattern`, as all Mongoose patterns, is a prefix pattern.\n   *\n   * If uri_pattern starts with `@` symbol, then Mongoose compares it with the\n   * HOST header of the request. If they are equal, Mongoose sets document root\n   * to `file_or_directory_path`, implementing virtual hosts support.\n   * Example: `@foo.com=/document/root/for/foo.com`\n   *\n   * If `uri_pattern` starts with `%` symbol, then Mongoose compares it with\n   * the listening port. If they match, then Mongoose issues a 301 redirect.\n   * For example, to redirect all HTTP requests to the\n   * HTTPS port, do `%80=https://my.site.com`. Note that the request URI is\n   * automatically appended to the redirect location.\n   */\n  const char *url_rewrites;\n#endif\n\n  /* DAV document root. If NULL, DAV requests are going to fail. */\n  const char *dav_document_root;\n\n  /*\n   * DAV passwords file. If NULL, DAV requests are going to fail.\n   * If passwords file is set to \"-\", then DAV auth is disabled.\n   */\n  const char *dav_auth_file;\n\n  /* Glob pattern for the files to hide. */\n  const char *hidden_file_pattern;\n\n  /* Set to non-NULL to enable CGI, e.g. **.cgi$|**.php$\" */\n  const char *cgi_file_pattern;\n\n  /* If not NULL, ignore CGI script hashbang and use this interpreter */\n  const char *cgi_interpreter;\n\n  /*\n   * Comma-separated list of Content-Type overrides for path suffixes, e.g.\n   * \".txt=text/plain; charset=utf-8,.c=text/plain\"\n   */\n  const char *custom_mime_types;\n\n  /*\n   * Extra HTTP headers to add to each server response.\n   * Example: to enable CORS, set this to \"Access-Control-Allow-Origin: *\".\n   */\n  const char *extra_headers;\n};\n\n/*\n * Serves given HTTP request according to the `options`.\n *\n * Example code snippet:\n *\n * ```c\n * static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {\n *   struct http_message *hm = (struct http_message *) ev_data;\n *   struct mg_serve_http_opts opts = { .document_root = \"/var/www\" };  // C99\n *\n *   switch (ev) {\n *     case MG_EV_HTTP_REQUEST:\n *       mg_serve_http(nc, hm, opts);\n *       break;\n *     default:\n *       break;\n *   }\n * }\n * ```\n */\nvoid mg_serve_http(struct mg_connection *nc, struct http_message *hm,\n                   struct mg_serve_http_opts opts);\n\n/*\n * Serves a specific file with a given MIME type and optional extra headers.\n *\n * Example code snippet:\n *\n * ```c\n * static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {\n *   switch (ev) {\n *     case MG_EV_HTTP_REQUEST: {\n *       struct http_message *hm = (struct http_message *) ev_data;\n *       mg_http_serve_file(nc, hm, \"file.txt\",\n *                          mg_mk_str(\"text/plain\"), mg_mk_str(\"\"));\n *       break;\n *     }\n *     ...\n *   }\n * }\n * ```\n */\nvoid mg_http_serve_file(struct mg_connection *nc, struct http_message *hm,\n                        const char *path, const struct mg_str mime_type,\n                        const struct mg_str extra_headers);\n#endif /* MG_ENABLE_FILESYSTEM */\n\n/*\n * Registers a callback for a specified http endpoint\n * Note: if callback is registered it is called instead of the\n * callback provided in mg_bind\n *\n * Example code snippet:\n *\n * ```c\n * static void handle_hello1(struct mg_connection *nc, int ev, void *ev_data) {\n *   (void) ev; (void) ev_data;\n *   mg_printf(nc, \"HTTP/1.0 200 OK\\r\\n\\r\\n[I am Hello1]\");\n *  nc->flags |= MG_F_SEND_AND_CLOSE;\n * }\n *\n * static void handle_hello1(struct mg_connection *nc, int ev, void *ev_data) {\n *  (void) ev; (void) ev_data;\n *   mg_printf(nc, \"HTTP/1.0 200 OK\\r\\n\\r\\n[I am Hello2]\");\n *  nc->flags |= MG_F_SEND_AND_CLOSE;\n * }\n *\n * void init() {\n *   nc = mg_bind(&mgr, local_addr, cb1);\n *   mg_register_http_endpoint(nc, \"/hello1\", handle_hello1);\n *   mg_register_http_endpoint(nc, \"/hello1/hello2\", handle_hello2);\n * }\n * ```\n */\nvoid mg_register_http_endpoint(struct mg_connection *nc, const char *uri_path,\n                               mg_event_handler_t handler);\n\n#if MG_ENABLE_HTTP_STREAMING_MULTIPART\n\n/* Callback prototype for `mg_file_upload_handler()`. */\ntypedef struct mg_str (*mg_fu_fname_fn)(struct mg_connection *nc,\n                                        struct mg_str fname);\n\n/*\n * File upload handler.\n * This handler can be used to implement file uploads with minimum code.\n * This handler will process MG_EV_HTTP_PART_* events and store file data into\n * a local file.\n * `local_name_fn` will be invoked with whatever name was provided by the client\n * and will expect the name of the local file to open. A return value of NULL\n * will abort file upload (client will get a \"403 Forbidden\" response). If\n * non-null, the returned string must be heap-allocated and will be freed by\n * the caller.\n * Exception: it is ok to return the same string verbatim.\n *\n * Example:\n *\n * ```c\n * struct mg_str upload_fname(struct mg_connection *nc, struct mg_str fname) {\n *   // Just return the same filename. Do not actually do this except in test!\n *   // fname is user-controlled and needs to be sanitized.\n *   return fname;\n * }\n * void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {\n *   switch (ev) {\n *     ...\n *     case MG_EV_HTTP_PART_BEGIN:\n *     case MG_EV_HTTP_PART_DATA:\n *     case MG_EV_HTTP_PART_END:\n *       mg_file_upload_handler(nc, ev, ev_data, upload_fname);\n *       break;\n *   }\n * }\n * ```\n */\nvoid mg_file_upload_handler(struct mg_connection *nc, int ev, void *ev_data,\n                            mg_fu_fname_fn local_name_fn);\n#endif /* MG_ENABLE_HTTP_STREAMING_MULTIPART */\n\n/*\n * Authenticates a HTTP request against an opened password file.\n * Returns 1 if authenticated, 0 otherwise.\n */\nint mg_http_check_digest_auth(struct http_message *hm, const char *auth_domain,\n                              FILE *fp);\n\n/*\n * Sends buffer `buf` of size `len` to the client using chunked HTTP encoding.\n * This function sends the buffer size as hex number + newline first, then\n * the buffer itself, then the newline. For example,\n * `mg_send_http_chunk(nc, \"foo\", 3)` whill append the `3\\r\\nfoo\\r\\n` string\n * to the `nc->send_mbuf` output IO buffer.\n *\n * NOTE: The HTTP header \"Transfer-Encoding: chunked\" should be sent prior to\n * using this function.\n *\n * NOTE: do not forget to send an empty chunk at the end of the response,\n * to tell the client that everything was sent. Example:\n *\n * ```\n *   mg_printf_http_chunk(nc, \"%s\", \"my response!\");\n *   mg_send_http_chunk(nc, \"\", 0); // Tell the client we're finished\n * ```\n */\nvoid mg_send_http_chunk(struct mg_connection *nc, const char *buf, size_t len);\n\n/*\n * Sends a printf-formatted HTTP chunk.\n * Functionality is similar to `mg_send_http_chunk()`.\n */\nvoid mg_printf_http_chunk(struct mg_connection *nc, const char *fmt, ...);\n\n/*\n * Sends the response status line.\n * If `extra_headers` is not NULL, then `extra_headers` are also sent\n * after the reponse line. `extra_headers` must NOT end end with new line.\n * Example:\n *\n *      mg_send_response_line(nc, 200, \"Access-Control-Allow-Origin: *\");\n *\n * Will result in:\n *\n *      HTTP/1.1 200 OK\\r\\n\n *      Access-Control-Allow-Origin: *\\r\\n\n */\nvoid mg_send_response_line(struct mg_connection *nc, int status_code,\n                           const char *extra_headers);\n\n/*\n * Sends an error response. If reason is NULL, the message will be inferred\n * from the error code (if supported).\n */\nvoid mg_http_send_error(struct mg_connection *nc, int code, const char *reason);\n\n/*\n * Sends a redirect response.\n * `status_code` should be either 301 or 302 and `location` point to the\n * new location.\n * If `extra_headers` is not empty, then `extra_headers` are also sent\n * after the reponse line. `extra_headers` must NOT end end with new line.\n *\n * Example:\n *\n *      mg_http_send_redirect(nc, 302, mg_mk_str(\"/login\"), mg_mk_str(NULL));\n */\nvoid mg_http_send_redirect(struct mg_connection *nc, int status_code,\n                           const struct mg_str location,\n                           const struct mg_str extra_headers);\n\n/*\n * Sends the response line and headers.\n * This function sends the response line with the `status_code`, and\n * automatically\n * sends one header: either \"Content-Length\" or \"Transfer-Encoding\".\n * If `content_length` is negative, then \"Transfer-Encoding: chunked\" header\n * is sent, otherwise, \"Content-Length\" header is sent.\n *\n * NOTE: If `Transfer-Encoding` is `chunked`, then message body must be sent\n * using `mg_send_http_chunk()` or `mg_printf_http_chunk()` functions.\n * Otherwise, `mg_send()` or `mg_printf()` must be used.\n * Extra headers could be set through `extra_headers`. Note `extra_headers`\n * must NOT be terminated by a new line.\n */\nvoid mg_send_head(struct mg_connection *n, int status_code,\n                  int64_t content_length, const char *extra_headers);\n\n/*\n * Sends a printf-formatted HTTP chunk, escaping HTML tags.\n */\nvoid mg_printf_html_escape(struct mg_connection *nc, const char *fmt, ...);\n\n#if MG_ENABLE_HTTP_URL_REWRITES\n/*\n * Proxies a given request to a given upstream http server. The path prefix\n * in `mount` will be stripped of the path requested to the upstream server,\n * e.g. if mount is /api and upstream is http://localhost:8001/foo\n * then an incoming request to /api/bar will cause a request to\n * http://localhost:8001/foo/bar\n *\n * EXPERIMENTAL API. Please use http_serve_http + url_rewrites if a static\n * mapping is good enough.\n */\nvoid mg_http_reverse_proxy(struct mg_connection *nc,\n                           const struct http_message *hm, struct mg_str mount,\n                           struct mg_str upstream);\n#endif\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif /* MG_ENABLE_HTTP */\n\n#endif /* CS_MONGOOSE_SRC_HTTP_SERVER_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/http_client.h\"\n#endif\n/*\n * === Client API reference\n */\n\n#ifndef CS_MONGOOSE_SRC_HTTP_CLIENT_H_\n#define CS_MONGOOSE_SRC_HTTP_CLIENT_H_\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*\n * Helper function that creates an outbound HTTP connection.\n *\n * `url` is the URL to fetch. It must be properly URL-encoded, e.g. have\n * no spaces, etc. By default, `mg_connect_http()` sends the Connection and\n * Host headers. `extra_headers` is an extra HTTP header to send, e.g.\n * `\"User-Agent: my-app\\r\\n\"`.\n * If `post_data` is NULL, then a GET request is created. Otherwise, a POST\n * request is created with the specified POST data. Note that if the data being\n * posted is a form submission, the `Content-Type` header should be set\n * accordingly (see example below).\n *\n * Examples:\n *\n * ```c\n *   nc1 = mg_connect_http(mgr, ev_handler_1, \"http://www.google.com\", NULL,\n *                         NULL);\n *   nc2 = mg_connect_http(mgr, ev_handler_1, \"https://github.com\", NULL, NULL);\n *   nc3 = mg_connect_http(\n *       mgr, ev_handler_1, \"my_server:8000/form_submit/\",\n *       \"Content-Type: application/x-www-form-urlencoded\\r\\n\",\n *       \"var_1=value_1&var_2=value_2\");\n * ```\n */\nstruct mg_connection *mg_connect_http(struct mg_mgr *mgr,\n                                      mg_event_handler_t event_handler,\n                                      const char *url,\n                                      const char *extra_headers,\n                                      const char *post_data);\n\n/*\n * Helper function that creates an outbound HTTP connection.\n *\n * Mostly identical to mg_connect_http, but allows you to provide extra\n *parameters\n * (for example, SSL parameters)\n */\nstruct mg_connection *mg_connect_http_opt(struct mg_mgr *mgr,\n                                          mg_event_handler_t ev_handler,\n                                          struct mg_connect_opts opts,\n                                          const char *url,\n                                          const char *extra_headers,\n                                          const char *post_data);\n\n/* Creates digest authentication header for a client request. */\nint mg_http_create_digest_auth_header(char *buf, size_t buf_len,\n                                      const char *method, const char *uri,\n                                      const char *auth_domain, const char *user,\n                                      const char *passwd);\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n#endif /* CS_MONGOOSE_SRC_HTTP_CLIENT_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/mqtt.h\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n * This software is dual-licensed: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation. For the terms of this\n * license, see <http://www.gnu.org/licenses/>.\n *\n * You are free to use this software under the terms of the GNU General\n * Public License, but WITHOUT ANY WARRANTY; without even the implied\n * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n * See the GNU General Public License for more details.\n *\n * Alternatively, you can license this software under a commercial\n * license, as set out in <https://www.cesanta.com/license>.\n */\n\n/*\n * === MQTT API reference\n */\n\n#ifndef CS_MONGOOSE_SRC_MQTT_H_\n#define CS_MONGOOSE_SRC_MQTT_H_\n\n/* Amalgamated: #include \"mongoose/src/net.h\" */\n\nstruct mg_mqtt_message {\n  int cmd;\n  int qos;\n  struct mg_str topic;\n  struct mg_str payload;\n\n  uint8_t connack_ret_code; /* connack */\n  uint16_t message_id;      /* puback */\n\n  /* connect */\n  uint8_t protocol_version;\n  uint8_t connect_flags;\n  uint16_t keep_alive_timer;\n  struct mg_str protocol_name;\n  struct mg_str client_id;\n  struct mg_str will_topic;\n  struct mg_str will_message;\n  struct mg_str user_name;\n  struct mg_str password;\n};\n\nstruct mg_mqtt_topic_expression {\n  const char *topic;\n  uint8_t qos;\n};\n\nstruct mg_send_mqtt_handshake_opts {\n  unsigned char flags; /* connection flags */\n  uint16_t keep_alive;\n  const char *will_topic;\n  const char *will_message;\n  const char *user_name;\n  const char *password;\n};\n\n/* mg_mqtt_proto_data should be in header to allow external access to it */\nstruct mg_mqtt_proto_data {\n  uint16_t keep_alive;\n};\n\n/* Message types */\n#define MG_MQTT_CMD_CONNECT 1\n#define MG_MQTT_CMD_CONNACK 2\n#define MG_MQTT_CMD_PUBLISH 3\n#define MG_MQTT_CMD_PUBACK 4\n#define MG_MQTT_CMD_PUBREC 5\n#define MG_MQTT_CMD_PUBREL 6\n#define MG_MQTT_CMD_PUBCOMP 7\n#define MG_MQTT_CMD_SUBSCRIBE 8\n#define MG_MQTT_CMD_SUBACK 9\n#define MG_MQTT_CMD_UNSUBSCRIBE 10\n#define MG_MQTT_CMD_UNSUBACK 11\n#define MG_MQTT_CMD_PINGREQ 12\n#define MG_MQTT_CMD_PINGRESP 13\n#define MG_MQTT_CMD_DISCONNECT 14\n\n/* MQTT event types */\n#define MG_MQTT_EVENT_BASE 200\n#define MG_EV_MQTT_CONNECT (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_CONNECT)\n#define MG_EV_MQTT_CONNACK (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_CONNACK)\n#define MG_EV_MQTT_PUBLISH (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PUBLISH)\n#define MG_EV_MQTT_PUBACK (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PUBACK)\n#define MG_EV_MQTT_PUBREC (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PUBREC)\n#define MG_EV_MQTT_PUBREL (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PUBREL)\n#define MG_EV_MQTT_PUBCOMP (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PUBCOMP)\n#define MG_EV_MQTT_SUBSCRIBE (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_SUBSCRIBE)\n#define MG_EV_MQTT_SUBACK (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_SUBACK)\n#define MG_EV_MQTT_UNSUBSCRIBE (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_UNSUBSCRIBE)\n#define MG_EV_MQTT_UNSUBACK (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_UNSUBACK)\n#define MG_EV_MQTT_PINGREQ (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PINGREQ)\n#define MG_EV_MQTT_PINGRESP (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_PINGRESP)\n#define MG_EV_MQTT_DISCONNECT (MG_MQTT_EVENT_BASE + MG_MQTT_CMD_DISCONNECT)\n\n/* Message flags */\n#define MG_MQTT_RETAIN 0x1\n#define MG_MQTT_DUP 0x4\n#define MG_MQTT_QOS(qos) ((qos) << 1)\n#define MG_MQTT_GET_QOS(flags) (((flags) &0x6) >> 1)\n#define MG_MQTT_SET_QOS(flags, qos) (flags) = ((flags) & ~0x6) | ((qos) << 1)\n\n/* Connection flags */\n#define MG_MQTT_CLEAN_SESSION 0x02\n#define MG_MQTT_HAS_WILL 0x04\n#define MG_MQTT_WILL_RETAIN 0x20\n#define MG_MQTT_HAS_PASSWORD 0x40\n#define MG_MQTT_HAS_USER_NAME 0x80\n#define MG_MQTT_GET_WILL_QOS(flags) (((flags) &0x18) >> 3)\n#define MG_MQTT_SET_WILL_QOS(flags, qos) \\\n  (flags) = ((flags) & ~0x18) | ((qos) << 3)\n\n/* CONNACK return codes */\n#define MG_EV_MQTT_CONNACK_ACCEPTED 0\n#define MG_EV_MQTT_CONNACK_UNACCEPTABLE_VERSION 1\n#define MG_EV_MQTT_CONNACK_IDENTIFIER_REJECTED 2\n#define MG_EV_MQTT_CONNACK_SERVER_UNAVAILABLE 3\n#define MG_EV_MQTT_CONNACK_BAD_AUTH 4\n#define MG_EV_MQTT_CONNACK_NOT_AUTHORIZED 5\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/*\n * Attaches a built-in MQTT event handler to the given connection.\n *\n * The user-defined event handler will receive following extra events:\n *\n * - MG_EV_MQTT_CONNACK\n * - MG_EV_MQTT_PUBLISH\n * - MG_EV_MQTT_PUBACK\n * - MG_EV_MQTT_PUBREC\n * - MG_EV_MQTT_PUBREL\n * - MG_EV_MQTT_PUBCOMP\n * - MG_EV_MQTT_SUBACK\n */\nvoid mg_set_protocol_mqtt(struct mg_connection *nc);\n\n/* Sends an MQTT handshake. */\nvoid mg_send_mqtt_handshake(struct mg_connection *nc, const char *client_id);\n\n/* Sends an MQTT handshake with optional parameters. */\nvoid mg_send_mqtt_handshake_opt(struct mg_connection *nc, const char *client_id,\n                                struct mg_send_mqtt_handshake_opts);\n\n/* Publishes a message to a given topic. */\nvoid mg_mqtt_publish(struct mg_connection *nc, const char *topic,\n                     uint16_t message_id, int flags, const void *data,\n                     size_t len);\n\n/* Subscribes to a bunch of topics. */\nvoid mg_mqtt_subscribe(struct mg_connection *nc,\n                       const struct mg_mqtt_topic_expression *topics,\n                       size_t topics_len, uint16_t message_id);\n\n/* Unsubscribes from a bunch of topics. */\nvoid mg_mqtt_unsubscribe(struct mg_connection *nc, char **topics,\n                         size_t topics_len, uint16_t message_id);\n\n/* Sends a DISCONNECT command. */\nvoid mg_mqtt_disconnect(struct mg_connection *nc);\n\n/* Sends a CONNACK command with a given `return_code`. */\nvoid mg_mqtt_connack(struct mg_connection *nc, uint8_t return_code);\n\n/* Sends a PUBACK command with a given `message_id`. */\nvoid mg_mqtt_puback(struct mg_connection *nc, uint16_t message_id);\n\n/* Sends a PUBREC command with a given `message_id`. */\nvoid mg_mqtt_pubrec(struct mg_connection *nc, uint16_t message_id);\n\n/* Sends a PUBREL command with a given `message_id`. */\nvoid mg_mqtt_pubrel(struct mg_connection *nc, uint16_t message_id);\n\n/* Sends a PUBCOMP command with a given `message_id`. */\nvoid mg_mqtt_pubcomp(struct mg_connection *nc, uint16_t message_id);\n\n/*\n * Sends a SUBACK command with a given `message_id`\n * and a sequence of granted QoSs.\n */\nvoid mg_mqtt_suback(struct mg_connection *nc, uint8_t *qoss, size_t qoss_len,\n                    uint16_t message_id);\n\n/* Sends a UNSUBACK command with a given `message_id`. */\nvoid mg_mqtt_unsuback(struct mg_connection *nc, uint16_t message_id);\n\n/* Sends a PINGREQ command. */\nvoid mg_mqtt_ping(struct mg_connection *nc);\n\n/* Sends a PINGRESP command. */\nvoid mg_mqtt_pong(struct mg_connection *nc);\n\n/*\n * Extracts the next topic expression from a SUBSCRIBE command payload.\n *\n * The topic expression name will point to a string in the payload buffer.\n * Returns the pos of the next topic expression or -1 when the list\n * of topics is exhausted.\n */\nint mg_mqtt_next_subscribe_topic(struct mg_mqtt_message *msg,\n                                 struct mg_str *topic, uint8_t *qos, int pos);\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif /* CS_MONGOOSE_SRC_MQTT_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/mqtt_server.h\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n * This software is dual-licensed: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation. For the terms of this\n * license, see <http://www.gnu.org/licenses/>.\n *\n * You are free to use this software under the terms of the GNU General\n * Public License, but WITHOUT ANY WARRANTY; without even the implied\n * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n * See the GNU General Public License for more details.\n *\n * Alternatively, you can license this software under a commercial\n * license, as set out in <https://www.cesanta.com/license>.\n */\n\n/*\n * === MQTT Server API reference\n */\n\n#ifndef CS_MONGOOSE_SRC_MQTT_BROKER_H_\n#define CS_MONGOOSE_SRC_MQTT_BROKER_H_\n\n#if MG_ENABLE_MQTT_BROKER\n\n/* Amalgamated: #include \"common/queue.h\" */\n/* Amalgamated: #include \"mongoose/src/mqtt.h\" */\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n#define MG_MQTT_MAX_SESSION_SUBSCRIPTIONS 512;\n\nstruct mg_mqtt_broker;\n\n/* MQTT session (Broker side). */\nstruct mg_mqtt_session {\n  struct mg_mqtt_broker *brk;       /* Broker */\n  LIST_ENTRY(mg_mqtt_session) link; /* mg_mqtt_broker::sessions linkage */\n  struct mg_connection *nc;         /* Connection with the client */\n  size_t num_subscriptions;         /* Size of `subscriptions` array */\n  void *user_data;                  /* User data */\n  struct mg_mqtt_topic_expression *subscriptions;\n};\n\n/* MQTT broker. */\nstruct mg_mqtt_broker {\n  LIST_HEAD(_mg_sesshead, mg_mqtt_session) sessions; /* Session list */\n  void *user_data;                                   /* User data */\n};\n\n/* Initialises a MQTT broker. */\nvoid mg_mqtt_broker_init(struct mg_mqtt_broker *brk, void *user_data);\n\n/*\n * Processes a MQTT broker message.\n *\n * The listening connection expects a pointer to an initialised\n * `mg_mqtt_broker` structure in the `user_data` field.\n *\n * Basic usage:\n *\n * ```c\n * mg_mqtt_broker_init(&brk, NULL);\n *\n * if ((nc = mg_bind(&mgr, address, mg_mqtt_broker)) == NULL) {\n *   // fail;\n * }\n * nc->user_data = &brk;\n * ```\n *\n * New incoming connections will receive a `mg_mqtt_session` structure\n * in the connection `user_data`. The original `user_data` will be stored\n * in the `user_data` field of the session structure. This allows the user\n * handler to store user data before `mg_mqtt_broker` creates the session.\n *\n * Since only the MG_EV_ACCEPT message is processed by the listening socket,\n * for most events the `user_data` will thus point to a `mg_mqtt_session`.\n */\nvoid mg_mqtt_broker(struct mg_connection *brk, int ev, void *data);\n\n/*\n * Iterates over all MQTT session connections. Example:\n *\n * ```c\n * struct mg_mqtt_session *s;\n * for (s = mg_mqtt_next(brk, NULL); s != NULL; s = mg_mqtt_next(brk, s)) {\n *   // Do something\n * }\n * ```\n */\nstruct mg_mqtt_session *mg_mqtt_next(struct mg_mqtt_broker *brk,\n                                     struct mg_mqtt_session *s);\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif /* MG_ENABLE_MQTT_BROKER */\n#endif /* CS_MONGOOSE_SRC_MQTT_BROKER_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/dns.h\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n */\n\n/*\n * === DNS API reference\n */\n\n#ifndef CS_MONGOOSE_SRC_DNS_H_\n#define CS_MONGOOSE_SRC_DNS_H_\n\n/* Amalgamated: #include \"mongoose/src/net.h\" */\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n#define MG_DNS_A_RECORD 0x01     /* Lookup IP address */\n#define MG_DNS_CNAME_RECORD 0x05 /* Lookup CNAME */\n#define MG_DNS_PTR_RECORD 0x0c   /* Lookup PTR */\n#define MG_DNS_TXT_RECORD 0x10   /* Lookup TXT */\n#define MG_DNS_AAAA_RECORD 0x1c  /* Lookup IPv6 address */\n#define MG_DNS_SRV_RECORD 0x21   /* Lookup SRV */\n#define MG_DNS_MX_RECORD 0x0f    /* Lookup mail server for domain */\n\n#define MG_MAX_DNS_QUESTIONS 32\n#define MG_MAX_DNS_ANSWERS 32\n\n#define MG_DNS_MESSAGE 100 /* High-level DNS message event */\n\nenum mg_dns_resource_record_kind {\n  MG_DNS_INVALID_RECORD = 0,\n  MG_DNS_QUESTION,\n  MG_DNS_ANSWER\n};\n\n/* DNS resource record. */\nstruct mg_dns_resource_record {\n  struct mg_str name; /* buffer with compressed name */\n  int rtype;\n  int rclass;\n  int ttl;\n  enum mg_dns_resource_record_kind kind;\n  struct mg_str rdata; /* protocol data (can be a compressed name) */\n};\n\n/* DNS message (request and response). */\nstruct mg_dns_message {\n  struct mg_str pkt; /* packet body */\n  uint16_t flags;\n  uint16_t transaction_id;\n  int num_questions;\n  int num_answers;\n  struct mg_dns_resource_record questions[MG_MAX_DNS_QUESTIONS];\n  struct mg_dns_resource_record answers[MG_MAX_DNS_ANSWERS];\n};\n\nstruct mg_dns_resource_record *mg_dns_next_record(\n    struct mg_dns_message *msg, int query, struct mg_dns_resource_record *prev);\n\n/*\n * Parses the record data from a DNS resource record.\n *\n *  - A:     struct in_addr *ina\n *  - AAAA:  struct in6_addr *ina\n *  - CNAME: char buffer\n *\n * Returns -1 on error.\n *\n * TODO(mkm): MX\n */\nint mg_dns_parse_record_data(struct mg_dns_message *msg,\n                             struct mg_dns_resource_record *rr, void *data,\n                             size_t data_len);\n\n/*\n * Sends a DNS query to the remote end.\n */\nvoid mg_send_dns_query(struct mg_connection *nc, const char *name,\n                       int query_type);\n\n/*\n * Inserts a DNS header to an IO buffer.\n *\n * Returns the number of bytes inserted.\n */\nint mg_dns_insert_header(struct mbuf *io, size_t pos,\n                         struct mg_dns_message *msg);\n\n/*\n * Appends already encoded questions from an existing message.\n *\n * This is useful when generating a DNS reply message which includes\n * all question records.\n *\n * Returns the number of appended bytes.\n */\nint mg_dns_copy_questions(struct mbuf *io, struct mg_dns_message *msg);\n\n/*\n * Encodes and appends a DNS resource record to an IO buffer.\n *\n * The record metadata is taken from the `rr` parameter, while the name and data\n * are taken from the parameters, encoded in the appropriate format depending on\n * record type and stored in the IO buffer. The encoded values might contain\n * offsets within the IO buffer. It's thus important that the IO buffer doesn't\n * get trimmed while a sequence of records are encoded while preparing a DNS\n * reply.\n *\n * This function doesn't update the `name` and `rdata` pointers in the `rr`\n * struct because they might be invalidated as soon as the IO buffer grows\n * again.\n *\n * Returns the number of bytes appened or -1 in case of error.\n */\nint mg_dns_encode_record(struct mbuf *io, struct mg_dns_resource_record *rr,\n                         const char *name, size_t nlen, const void *rdata,\n                         size_t rlen);\n\n/*\n * Encodes a DNS name.\n */\nint mg_dns_encode_name(struct mbuf *io, const char *name, size_t len);\n\n/* Low-level: parses a DNS response. */\nint mg_parse_dns(const char *buf, int len, struct mg_dns_message *msg);\n\n/*\n * Uncompresses a DNS compressed name.\n *\n * The containing DNS message is required because of the compressed encoding\n * and reference suffixes present elsewhere in the packet.\n *\n * If the name is less than `dst_len` characters long, the remainder\n * of `dst` is terminated with `\\0` characters. Otherwise, `dst` is not\n * terminated.\n *\n * If `dst_len` is 0 `dst` can be NULL.\n * Returns the uncompressed name length.\n */\nsize_t mg_dns_uncompress_name(struct mg_dns_message *msg, struct mg_str *name,\n                              char *dst, int dst_len);\n\n/*\n * Attaches a built-in DNS event handler to the given listening connection.\n *\n * The DNS event handler parses the incoming UDP packets, treating them as DNS\n * requests. If an incoming packet gets successfully parsed by the DNS event\n * handler, a user event handler will receive an `MG_DNS_REQUEST` event, with\n * `ev_data` pointing to the parsed `struct mg_dns_message`.\n *\n * See\n * [captive_dns_server](https://github.com/cesanta/mongoose/tree/master/examples/captive_dns_server)\n * example on how to handle DNS request and send DNS reply.\n */\nvoid mg_set_protocol_dns(struct mg_connection *nc);\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n#endif /* CS_MONGOOSE_SRC_DNS_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/dns_server.h\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n */\n\n/*\n * === DNS server API reference\n *\n * Disabled by default; enable with `-DMG_ENABLE_DNS_SERVER`.\n */\n\n#ifndef CS_MONGOOSE_SRC_DNS_SERVER_H_\n#define CS_MONGOOSE_SRC_DNS_SERVER_H_\n\n#if MG_ENABLE_DNS_SERVER\n\n/* Amalgamated: #include \"mongoose/src/dns.h\" */\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n#define MG_DNS_SERVER_DEFAULT_TTL 3600\n\nstruct mg_dns_reply {\n  struct mg_dns_message *msg;\n  struct mbuf *io;\n  size_t start;\n};\n\n/*\n * Creates a DNS reply.\n *\n * The reply will be based on an existing query message `msg`.\n * The query body will be appended to the output buffer.\n * \"reply + recursion allowed\" will be added to the message flags and the\n * message's num_answers will be set to 0.\n *\n * Answer records can be appended with `mg_dns_send_reply` or by lower\n * level function defined in the DNS API.\n *\n * In order to send a reply use `mg_dns_send_reply`.\n * It's possible to use a connection's send buffer as reply buffer,\n * and it will work for both UDP and TCP connections.\n *\n * Example:\n *\n * ```c\n * reply = mg_dns_create_reply(&nc->send_mbuf, msg);\n * for (i = 0; i < msg->num_questions; i++) {\n *   rr = &msg->questions[i];\n *   if (rr->rtype == MG_DNS_A_RECORD) {\n *     mg_dns_reply_record(&reply, rr, 3600, &dummy_ip_addr, 4);\n *   }\n * }\n * mg_dns_send_reply(nc, &reply);\n * ```\n */\nstruct mg_dns_reply mg_dns_create_reply(struct mbuf *io,\n                                        struct mg_dns_message *msg);\n\n/*\n * Appends a DNS reply record to the IO buffer and to the DNS message.\n *\n * The message's num_answers field will be incremented. It's the caller's duty\n * to ensure num_answers is properly initialised.\n *\n * Returns -1 on error.\n */\nint mg_dns_reply_record(struct mg_dns_reply *reply,\n                        struct mg_dns_resource_record *question,\n                        const char *name, int rtype, int ttl, const void *rdata,\n                        size_t rdata_len);\n\n/*\n * Sends a DNS reply through a connection.\n *\n * The DNS data is stored in an IO buffer pointed by reply structure in `r`.\n * This function mutates the content of that buffer in order to ensure that\n * the DNS header reflects the size and flags of the message, that might have\n * been updated either with `mg_dns_reply_record` or by direct manipulation of\n * `r->message`.\n *\n * Once sent, the IO buffer will be trimmed unless the reply IO buffer\n * is the connection's send buffer and the connection is not in UDP mode.\n */\nvoid mg_dns_send_reply(struct mg_connection *nc, struct mg_dns_reply *r);\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif /* MG_ENABLE_DNS_SERVER */\n#endif /* CS_MONGOOSE_SRC_DNS_SERVER_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/resolv.h\"\n#endif\n/*\n * Copyright (c) 2014 Cesanta Software Limited\n * All rights reserved\n */\n\n/*\n * === API reference\n */\n\n#ifndef CS_MONGOOSE_SRC_RESOLV_H_\n#define CS_MONGOOSE_SRC_RESOLV_H_\n\n/* Amalgamated: #include \"mongoose/src/dns.h\" */\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\nenum mg_resolve_err {\n  MG_RESOLVE_OK = 0,\n  MG_RESOLVE_NO_ANSWERS = 1,\n  MG_RESOLVE_EXCEEDED_RETRY_COUNT = 2,\n  MG_RESOLVE_TIMEOUT = 3\n};\n\ntypedef void (*mg_resolve_callback_t)(struct mg_dns_message *dns_message,\n                                      void *user_data, enum mg_resolve_err);\n\n/* Options for `mg_resolve_async_opt`. */\nstruct mg_resolve_async_opts {\n  const char *nameserver_url;\n  int max_retries;    /* defaults to 2 if zero */\n  int timeout;        /* in seconds; defaults to 5 if zero */\n  int accept_literal; /* pseudo-resolve literal ipv4 and ipv6 addrs */\n  int only_literal;   /* only resolves literal addrs; sync cb invocation */\n  struct mg_connection **dns_conn; /* return DNS connection */\n};\n\n/* See `mg_resolve_async_opt()` */\nint mg_resolve_async(struct mg_mgr *mgr, const char *name, int query,\n                     mg_resolve_callback_t cb, void *data);\n\n/*\n * Resolved a DNS name asynchronously.\n *\n * Upon successful resolution, the user callback will be invoked\n * with the full DNS response message and a pointer to the user's\n * context `data`.\n *\n * In case of timeout while performing the resolution the callback\n * will receive a NULL `msg`.\n *\n * The DNS answers can be extracted with `mg_next_record` and\n * `mg_dns_parse_record_data`:\n *\n * [source,c]\n * ----\n * struct in_addr ina;\n * struct mg_dns_resource_record *rr = mg_next_record(msg, MG_DNS_A_RECORD,\n *   NULL);\n * mg_dns_parse_record_data(msg, rr, &ina, sizeof(ina));\n * ----\n */\nint mg_resolve_async_opt(struct mg_mgr *mgr, const char *name, int query,\n                         mg_resolve_callback_t cb, void *data,\n                         struct mg_resolve_async_opts opts);\n\n/*\n * Resolve a name from `/etc/hosts`.\n *\n * Returns 0 on success, -1 on failure.\n */\nint mg_resolve_from_hosts_file(const char *host, union socket_address *usa);\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n#endif /* CS_MONGOOSE_SRC_RESOLV_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/coap.h\"\n#endif\n/*\n * Copyright (c) 2015 Cesanta Software Limited\n * All rights reserved\n * This software is dual-licensed: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 2 as\n * published by the Free Software Foundation. For the terms of this\n * license, see <http://www.gnu.org/licenses/>.\n *\n * You are free to use this software under the terms of the GNU General\n * Public License, but WITHOUT ANY WARRANTY; without even the implied\n * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n * See the GNU General Public License for more details.\n *\n * Alternatively, you can license this software under a commercial\n * license, as set out in <https://www.cesanta.com/license>.\n */\n\n/*\n * === CoAP API reference\n *\n * CoAP message format:\n *\n * ```\n * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-\n * |Ver| T | TKL | Code | Message ID | Token (if any, TKL bytes) ...\n * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-\n * | Options (if any) ...            |1 1 1 1 1 1 1 1| Payload (if any) ...\n * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-\n * ```\n */\n\n#ifndef CS_MONGOOSE_SRC_COAP_H_\n#define CS_MONGOOSE_SRC_COAP_H_\n\n#if MG_ENABLE_COAP\n\n#define MG_COAP_MSG_TYPE_FIELD 0x2\n#define MG_COAP_CODE_CLASS_FIELD 0x4\n#define MG_COAP_CODE_DETAIL_FIELD 0x8\n#define MG_COAP_MSG_ID_FIELD 0x10\n#define MG_COAP_TOKEN_FIELD 0x20\n#define MG_COAP_OPTIOMG_FIELD 0x40\n#define MG_COAP_PAYLOAD_FIELD 0x80\n\n#define MG_COAP_ERROR 0x10000\n#define MG_COAP_FORMAT_ERROR (MG_COAP_ERROR | 0x20000)\n#define MG_COAP_IGNORE (MG_COAP_ERROR | 0x40000)\n#define MG_COAP_NOT_ENOUGH_DATA (MG_COAP_ERROR | 0x80000)\n#define MG_COAP_NETWORK_ERROR (MG_COAP_ERROR | 0x100000)\n\n#define MG_COAP_MSG_CON 0\n#define MG_COAP_MSG_NOC 1\n#define MG_COAP_MSG_ACK 2\n#define MG_COAP_MSG_RST 3\n#define MG_COAP_MSG_MAX 3\n\n#define MG_COAP_CODECLASS_REQUEST 0\n#define MG_COAP_CODECLASS_RESP_OK 2\n#define MG_COAP_CODECLASS_CLIENT_ERR 4\n#define MG_COAP_CODECLASS_SRV_ERR 5\n\n#define MG_COAP_EVENT_BASE 300\n#define MG_EV_COAP_CON (MG_COAP_EVENT_BASE + MG_COAP_MSG_CON)\n#define MG_EV_COAP_NOC (MG_COAP_EVENT_BASE + MG_COAP_MSG_NOC)\n#define MG_EV_COAP_ACK (MG_COAP_EVENT_BASE + MG_COAP_MSG_ACK)\n#define MG_EV_COAP_RST (MG_COAP_EVENT_BASE + MG_COAP_MSG_RST)\n\n/*\n * CoAP options.\n * Use mg_coap_add_option and mg_coap_free_options\n * for creation and destruction.\n */\nstruct mg_coap_option {\n  struct mg_coap_option *next;\n  uint32_t number;\n  struct mg_str value;\n};\n\n/* CoAP message. See RFC 7252 for details. */\nstruct mg_coap_message {\n  uint32_t flags;\n  uint8_t msg_type;\n  uint8_t code_class;\n  uint8_t code_detail;\n  uint16_t msg_id;\n  struct mg_str token;\n  struct mg_coap_option *options;\n  struct mg_str payload;\n  struct mg_coap_option *optiomg_tail;\n};\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif /* __cplusplus */\n\n/* Sets CoAP protocol handler - triggers CoAP specific events. */\nint mg_set_protocol_coap(struct mg_connection *nc);\n\n/*\n * Adds a new option to mg_coap_message structure.\n * Returns pointer to the newly created option.\n * Note: options must be freed by using mg_coap_free_options\n */\nstruct mg_coap_option *mg_coap_add_option(struct mg_coap_message *cm,\n                                          uint32_t number, char *value,\n                                          size_t len);\n\n/*\n * Frees the memory allocated for options.\n * If the cm paramater doesn't contain any option it does nothing.\n */\nvoid mg_coap_free_options(struct mg_coap_message *cm);\n\n/*\n * Composes a CoAP message from `mg_coap_message`\n * and sends it into `nc` connection.\n * Returns 0 on success. On error, it is a bitmask:\n *\n * - `#define MG_COAP_ERROR 0x10000`\n * - `#define MG_COAP_FORMAT_ERROR (MG_COAP_ERROR | 0x20000)`\n * - `#define MG_COAP_IGNORE (MG_COAP_ERROR | 0x40000)`\n * - `#define MG_COAP_NOT_ENOUGH_DATA (MG_COAP_ERROR | 0x80000)`\n * - `#define MG_COAP_NETWORK_ERROR (MG_COAP_ERROR | 0x100000)`\n */\nuint32_t mg_coap_send_message(struct mg_connection *nc,\n                              struct mg_coap_message *cm);\n\n/*\n * Composes CoAP acknowledgement from `mg_coap_message`\n * and sends it into `nc` connection.\n * Return value: see `mg_coap_send_message()`\n */\nuint32_t mg_coap_send_ack(struct mg_connection *nc, uint16_t msg_id);\n\n/*\n * Parses CoAP message and fills mg_coap_message and returns cm->flags.\n * This is a helper function.\n *\n * NOTE: usually CoAP works over UDP, so lack of data means format error.\n * But, in theory, it is possible to use CoAP over TCP (according to RFC)\n *\n * The caller has to check results and treat COAP_NOT_ENOUGH_DATA according to\n * underlying protocol:\n *\n * - in case of UDP COAP_NOT_ENOUGH_DATA means COAP_FORMAT_ERROR,\n * - in case of TCP client can try to receive more data\n *\n * Return value: see `mg_coap_send_message()`\n */\nuint32_t mg_coap_parse(struct mbuf *io, struct mg_coap_message *cm);\n\n/*\n * Composes CoAP message from mg_coap_message structure.\n * This is a helper function.\n * Return value: see `mg_coap_send_message()`\n */\nuint32_t mg_coap_compose(struct mg_coap_message *cm, struct mbuf *io);\n\n#ifdef __cplusplus\n}\n#endif /* __cplusplus */\n\n#endif /* MG_ENABLE_COAP */\n\n#endif /* CS_MONGOOSE_SRC_COAP_H_ */\n#ifdef MG_MODULE_LINES\n#line 1 \"mongoose/src/sntp.h\"\n#endif\n/*\n * Copyright (c) 2016 Cesanta Software Limited\n * All rights reserved\n */\n\n#ifndef CS_MONGOOSE_SRC_SNTP_H_\n#define CS_MONGOOSE_SRC_SNTP_H_\n\n#if MG_ENABLE_SNTP\n\n#define MG_SNTP_EVENT_BASE 500\n\n/*\n * Received reply from time server. Event handler parameter contains\n * pointer to mg_sntp_message structure\n */\n#define MG_SNTP_REPLY (MG_SNTP_EVENT_BASE + 1)\n\n/* Received malformed SNTP packet */\n#define MG_SNTP_MALFORMED_REPLY (MG_SNTP_EVENT_BASE + 2)\n\n/* Failed to get time from server (timeout etc) */\n#define MG_SNTP_FAILED (MG_SNTP_EVENT_BASE + 3)\n\nstruct mg_sntp_message {\n  /* if server sends this flags, user should not send requests to it */\n  int kiss_of_death;\n  /* usual mg_time */\n  double time;\n};\n\n/* Establishes connection to given sntp server */\nstruct mg_connection *mg_sntp_connect(struct mg_mgr *mgr,\n                                      mg_event_handler_t event_handler,\n                                      const char *sntp_server_name);\n\n/* Sends time request to given connection */\nvoid mg_sntp_send_request(struct mg_connection *c);\n\n/*\n * Helper function\n * Establishes connection to time server, tries to send request\n * repeats sending SNTP_ATTEMPTS times every SNTP_TIMEOUT sec\n * (if needed)\n * See sntp_client example\n */\nstruct mg_connection *mg_sntp_get_time(struct mg_mgr *mgr,\n                                       mg_event_handler_t event_handler,\n                                       const char *sntp_server_name);\n\n#endif\n\n#endif /* CS_MONGOOSE_SRC_SNTP_H_ */\n"
  }
]